Einzelnen Beitrag anzeigen

Benutzerbild von Sprint
Sprint

Registriert seit: 18. Aug 2004
Ort: Edewecht
712 Beiträge
 
Delphi 5 Professional
 
#1

Komandozeilenparameter fremder Prozesse auslesen

  Alt 3. Dez 2004, 06:56
Seitdem Microsoft in der MSDN und dem Platform SDK Funktionen wie NtQueryInformationProcess beschreibt, ist es nicht mehr allzu schwer einem Prozess bestimmte Werte zu entlocken. Aber so sehr gehen Mircosoft'sche Hilfedateien nun auch wieder nicht ins Detail. Mit Hilfe des Internets und diversen Büchern ist es doch möglich verschiede Quelltexte in C zu ergattern. Diese Beispiele greifen dann oft auf Header Dateien von Visual C++ oder dem DDK zu. Delphi liefert leider keine Übersetzungen zu diesem Thema. Und in den englischsprachigen Borland Newsgroup findet man hin und wieder auch mal unvollständige Informationen. Als ich dann in irgendeinem Buch zu "undokumentierte Windows NT Funktionen" gelesen hatte, das im Adressraum jedes Prozess die Informationen stehen, die man normalerweise mit NtQueryInformationProcess ausließt, dachte ich mir das das auch mit der reinen WinAPI Funktion ReadProcessMemory geht. Ich habe versucht ohne diese Header Dateien auszukommen und muss sagen das ich in den ersten beiden Anläufen gescheitert bin.

Delphi-Quellcode:
function GetProcessCmdLine(ProcessId: DWORD): String;
var
  ProcessHandle: THandle;
  MBI: TMemoryBasicInformation;
  Buffer: Pointer;
  SystemInfo: TSystemInfo;
  Size: DWORD;
  CmdLine: WideString;
  LengthCmdLine: Word;
  PosCmdLine: Pointer;
begin

  Result := '';
  FillChar(SystemInfo, SizeOf(TSystemInfo), 0);
  GetSystemInfo(SystemInfo);
  GetMem(Buffer, SystemInfo.dwPageSize);
  try
    ProcessHandle := OpenProcess(PROCESS_VM_READ or PROCESS_QUERY_INFORMATION, False, ProcessId);
    if ProcessHandle <> 0 then
    begin
      Size := SizeOf(TMemoryBasicInformation);
      FillChar(MBI, Size, 0);
      if VirtualQueryEx(ProcessHandle, Pointer($00020000), MBI, Size) = Size then
        if ReadProcessMemory(ProcessHandle, MBI.BaseAddress, Buffer, SystemInfo.dwPageSize, DWORD(nil^)) then
        begin
          LengthCmdLine := PWord(Longint(Buffer) + $42)^;
          if LengthCmdLine < (MAX_PATH * 2) then
          begin
            SetLength(CmdLine, LengthCmdLine);
            PosCmdLine := Pointer(PLongint(Longint(Buffer) + $44)^);
            if ReadProcessMemory(ProcessHandle, PosCmdLine, PWideChar(CmdLine), LengthCmdLine, DWORD(nil^)) then
              Result := Trim(Copy(CmdLine, 1, Pos(#0, CmdLine) - 1));
          end;
        end;
      CloseHandle(ProcessHandle);
    end;
  finally
    FreeMem(Buffer);
  end;

end;
Ich muss dazu sagen, das ich das jetzt nur unter Windows XP getestet habe. Wäre ganz nett, wenn jemand diese Funktion unter einem anderen Windows OS testet und sein Ergebnis hier postet. Danke.

Eine kleine Diskussion zu dem Thema gibt es hier.


[edit=Chakotay1308]Diskussionshinweis eingefügt. Mfg, Chakotay1308[/edit]
Angehängte Dateien
Dateityp: zip processcmdline.zip (7,6 KB, 77x aufgerufen)
Ciao, Sprint.

"I don't know what I am doing, but I am sure I am having fun!"
  Mit Zitat antworten Zitat