Registriert seit: 18. Nov 2005
Ort: Ratingen
945 Beiträge
Delphi XE2 Professional
|
Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist
13. Aug 2006, 20:07
Für die Forensuche - Die Lösung:
Hilfsfunktion:
Delphi-Quellcode:
function GetUserAndDomainFromPID(ProcessId: DWORD; var User, Domain: String): Boolean;
{ Hilfsfunktion. Ermittelt zu einer PID den Benutzerkontext und die Domäne }
var
hToken: THandle;
cbBuf: Cardinal;
ptiUser: PTOKEN_USER;
snu: SID_NAME_USE;
ProcessHandle: THandle;
UserSize, DomainSize: DWORD;
bSuccess: Boolean;
begin
Result := False;
ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION, False, ProcessId);
if ProcessHandle <> 0 then
begin
if OpenProcessToken(ProcessHandle, TOKEN_QUERY, hToken) then
begin
bSuccess := GetTokenInformation(hToken, TokenUser, nil, 0, cbBuf);
ptiUser := nil;
while (Not bSuccess) And (GetLastError = ERROR_INSUFFICIENT_BUFFER) do
begin
ReallocMem(ptiUser, cbBuf);
bSuccess := GetTokenInformation(hToken, TokenUser, ptiUser, cbBuf, cbBuf);
end;
CloseHandle(hToken);
if Not bSuccess then
begin
Exit;
end;
UserSize := 0;
DomainSize := 0;
LookupAccountSid(nil, ptiUser.User.Sid, nil, UserSize, nil, DomainSize, snu);
if (UserSize <> 0) And (DomainSize <> 0) then
begin
SetLength(User, UserSize);
SetLength(Domain, DomainSize);
if LookupAccountSid(nil, ptiUser.User.Sid, PChar(User), UserSize, PChar(Domain),
DomainSize, snu) then
begin
Result := True;
User := StrPas(PChar(User));
Domain := StrPas(PChar(Domain));
end;
end;
if bSuccess then
begin
FreeMem(ptiUser);
end;
end;
CloseHandle(ProcessHandle);
end;
end;
Eigentliche Funktion:
Delphi-Quellcode:
function IsServiceApp(AppName: String; PID: Integer; var ServiceName: String): Boolean;
{
Überprüft, ob ein Prozess mit der PID ein Dienst ist.
Bedingungen: - Benutzerkonto ist das Systemkonto
- Service ist in der Registry eingetragen
}
var
User, Domain: String;
Reg: TRegistry;
List: TStringList;
I: Integer;
begin
Result := False;
GetUserAndDomainFromPID(PID, User, Domain); // Ermittelt den Benutzerkontext
if User = 'SYSTEM' then
begin // Programm läuft im Systemkontext... (könnte ein Dienst sein)
Reg := TRegistry.Create;
List := TStringList.Create;
Reg.RootKey := HKEY_LOCAL_MACHINE;
Reg.OpenKeyReadOnly('\SYSTEM\CurrentControlSet\Services\'); // Serviceliste öffnen
Reg.GetKeyNames(List); // Alle Untereinträge auflisten
for I := 0 to List.Count - 1 do
begin
Reg.OpenKeyReadOnly('\SYSTEM\CurrentControlSet\Services\' + List[i]);
if Reg.ValueExists('ImagePath')
// Wenn zugehörige Startdatei angegeben... (sonst kann nicht zugeordnet werden über den Prozessnamen)
then
begin
if LowerCase(ExtractFileNameFromSystemPath(Reg.ReadString('ImagePath'))) =
LowerCase(AppName)
// Wenn die Dienst-EXE = Prozess-EXE --> Prozess ist ein Dienst
then
begin
Result := True; // Prozess = Dienst
ServiceName := List[i]; // Prozessnamen zurückgeben (z.B. "Spooler")
Break; // Schleife verlassen
end;
end;
end;
List.Free;
Reg.Free;
end;
end;
Funktioniert bis jetzt ohne Probleme, bin aber für Diskussion offen
|
|
Zitat
|