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]