Einzelnen Beitrag anzeigen

wido

Registriert seit: 2. Jan 2006
122 Beiträge
 

Re: GetCommandLine für fremde Anwendung

  Alt 15. Apr 2008, 20:02
Ich habs einfach mal ausgecodet. Funktioniert übrigens für 64bit Prozesse leider nicht, da die PebBaseAddress für solche Prozesse nil ist. Evtl. gibts ne 64bit PEB Struktur. Ich werd nachher mal nachschauen. Kommt übrigens wie Du siehst komplett ohne Code Injection aus .

Delphi-Quellcode:
program GetCommandLineExDemo;
{$APPTYPE CONSOLE}

uses
  JwaWinBase, JwaNative, JwaWinNt, JwaWinType, JwaPSAPI, JwaNtStatus;

type
  PROCESS_BASIC_INFORMATION = packed record
    ExitStatus: DWORD;
    PebBaseAddress: Pointer;
    AffinityMask: DWORD;
    BasePriority: DWORD;
    UniqueProcessId: DWORD;
    InheritedUniquePID:DWORD;
  end;

// Funktioniert nur für Windows NT basierte Systeme
function GetCommandLineEx(PID : DWORD) : widestring;
var
  ProcessHandle : THandle;
  ProcessBasicInfo : PROCESS_BASIC_INFORMATION;
  PEB : _PEB_W2K;
  ProcessParameters : RTL_USER_PROCESS_PARAMETERS;
  ReturnLength : DWORD;
  CommandLine : PWideChar;
begin
  result := '';
  ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, PID);
  if ProcessHandle <> 0 then
    begin
      // Schritt 1: Wir holen uns die PROCESS_BASIC_INFORMATION um den PEB zu lokalisieren
      if (NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation, @ProcessBasicInfo, SizeOf(ProcessBasicInfo), @ReturnLength) = STATUS_SUCCESS) and (ReturnLength = SizeOf(ProcessBasicInfo)) then
        // Schritt 2: Wir lesen den PEB aus
        if ReadProcessMemory(ProcessHandle, ProcessBasicInfo.PebBaseAddress, @PEB, SizeOf(PEB), @ReturnLength) and (ReturnLength = SizeOf(PEB)) then
          // Schritt 3: Wir lesen die ProcessParameters aus
          if ReadProcessMemory(ProcessHandle, PEB.ProcessParameters, @ProcessParameters, SizeOf(ProcessParameters), @ReturnLength) and (ReturnLength = SizeOf(ProcessParameters)) then
            begin
              // Schritt 4: Wir lesen die Command Line aus
              GetMem(CommandLine, (ProcessParameters.CommandLine.Length + 1) * 2);
              if ReadProcessMemory(ProcessHandle, ProcessParameters.CommandLine.Buffer, CommandLine, ProcessParameters.CommandLine.Length * 2, @ReturnLength) then
                result := WideString(CommandLine);
              FreeMem(CommandLine);
            end;
      CloseHandle(ProcessHandle);
    end;
end;

var
  PIDs : array[0..1000] of DWORD;
  Needed : DWORD;
  i : Integer;
begin
  EnumProcesses(@PIDs[0], 1001, Needed);
  for i := 0 to (Needed div 4) - 1 do
    writeln(PIDs[i], ' --> ', GetCommandLineEx(PIDs[i]));
  readln;
end.
  Mit Zitat antworten Zitat