Einzelnen Beitrag anzeigen

berens

Registriert seit: 3. Sep 2004
434 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Autologon W7 / LSA-Wert in Registry schreiben

  Alt 22. Jun 2011, 11:54
Hallo zusammen, Danke Luckie für die Tip.

LsaStorePrivateData ist ein guter Ansatz, allerdings wird in der OH ja empfohlen, stattdessen CryptProtectDatazu verwenden.

Ich bin nicht wählerisch, und verwende das, was ich irgendwie zum Laufen bekomme.

Aus einem deiner anderen Beiträge mit Demo-Projekt war ich so frei, das Ganze mit der Unit lsaapi von Colin Wilson zu testen. Dort sind die Prozeduren und Typen für die LSA-Geschichte in eine Delphi-Unit importiert.

Dazu passend habe ich diesen Beitrag in der M$-KB gefunden, der genau mein Problem behandelt (wenn's denn wahr ist): http://msdn.microsoft.com/en-us/library/Aa378826 ; leider in C.

Mit meiner naiven Gemüt habt ich das nun nach Delphi übersetzt. Generell scheint es zu klappen, aber wenn ich die Ausgaben von LSASecretsView mit denen von Sysinternals' Autologon vergleiche, merke ich schon, dass ich an mehreren Stellen wohl die Typen falsch übersetzt habe (Passwort: 1234567890; Wenn ich mit LsaStorePrivateData speichere: "1234567890..U..3.Uh."; Sysinternal Autologon: "1.2.3.4.5.6.7.8.9.0.".)

Ausserdem muss an die Stellen im folgenden Code, an den die Variable "t" steht, NULL / NIL hin. Mit NULL, NIL, 0 oder '' will er aber nicht compilieren.

Bitte werft mal einen Blick auf meine "Übersetzung" (Original) und nennt mir die Korrekturen. Dafür wäre ich sehr Dankbar.

Mit dem ganzen Pointer-Gedöns von C komme ich eh nicht klar, deshalb bitte auch die Stellen genau ansehen, bei denen die Variablen/Pointer im Original mit &Undzeichen beginnen. Danke.

Übersetzung:
Delphi-Quellcode:
uses lsaapi;

  TLSAObjectAttributes = packed record
    Length : ULONG;
    RootDirectory : THandle;
    ObjectName : PLSAUnicodeString;
    Attributes : ULONG;
    SecurityDescriptor : pointer; // Points to type SECURITY_DESCRIPTOR
    SecurityQualityOfService : pointer; // Points to type SECURITY_QUALITY_OF_SERVICE
  end;

  LSA_HANDLE = pointer;
  PLSA_HANDLE = ^LSA_HANDLE;

  TLSAUnicodeString = packed record
    Length : WORD;
    MaximumLength : WORD;
    Buffer : PWideChar
  end;
  PLSAUnicodeString = ^TLSAUnicodeString;
  NTStatus = Integer; //DWORD;

// ^-- Auszüge aus der lsaapi

// THX to: http://msdn.microsoft.com/en-us/library/Aa378826
function StoreAutoLogonPassword(_Password: string = ''): DWORD;
var
  ObjectAttributes: TLSAObjectAttributes;
  LsaPolicyHandle: LSA_HANDLE;
  lusSecretName: TLSAUnicodeString;
  lusSecretData: TLSAUnicodeString;
  SecretNameLength: Word;
  SecretDataLength: Word;
  ntsResult: NTStatus;
  dwRetCode: DWORD;
  t: TLSAUnicodeString;
begin
  LsaPolicyHandle := NIL;
  SecretNameLength := 0;
  SecretDataLength := 0;
  ntsResult := STATUS_SUCCESS;
  dwRetCode := ERROR_SUCCESS;

  // Object attributes are reserved, so initialize to zeros.
  ZeroMemory(@ObjectAttributes, SizeOf(ObjectAttributes));

  // Get a handle to the Policy object.
  ntsResult := LsaOpenPolicy(
    t, // local Machine
    ObjectAttributes,
    POLICY_CREATE_SECRET,
    LsaPolicyHandle);

  if (STATUS_SUCCESS <> ntsResult) then begin
    // An error occurred. Display it as a win32 error code.
    dwRetCode := LsaNtStatusToWinError(ntsResult);
    ShowMessage('Failed call to LsaOpenPolicy: ' + IntToStr(dwRetCode));
    Result := dwRetCode;
    Exit;
  end;

  // Initialize an LSA_UNICODE_STRING for the name of the
  // private data ("DefaultPassword").
  SecretNameLength := word(length('DefaultPassword'));
  lusSecretName.Buffer := 'DefaultPassword';
  lusSecretName.Length := SecretNameLength * sizeof(WCHAR);
  lusSecretName.MaximumLength := (SecretNameLength+1) * sizeof(WCHAR);

  // If the pwszSecret parameter is NULL, then clear the secret.
  if(_Password = '') then begin
    ShowMessage('Clearing the secret...');
    ntsResult := LsaStorePrivateData(
      LsaPolicyHandle,
      lusSecretName,
      t);
    dwRetCode := LsaNtStatusToWinError(ntsResult);
  end else begin
    ShowMessage('Setting the secret...');
    // Initialize an LSA_UNICODE_STRING for the value
    // of the private data.
    SecretDataLength := word(length(_Password));
    lusSecretData.Buffer := pwidechar(_Password);
    lusSecretData.Length := SecretDataLength * sizeof(WCHAR);
    lusSecretData.MaximumLength :=
        (SecretDataLength+1) * sizeof(WCHAR);
    ntsResult := LsaStorePrivateData(
        LsaPolicyHandle,
        lusSecretName,
        lusSecretData);
    dwRetCode := LsaNtStatusToWinError(ntsResult);
  end;

  LsaClose(LsaPolicyHandle);

  if (dwRetCode <> ERROR_SUCCESS) then begin
    writeln('Failed call to LsaStorePrivateData: ' + IntToStr(dwRetCode));
  end;

  Result := dwRetCode;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  StoreAutoLogonPassword('1234567890');
end;
  Mit Zitat antworten Zitat