Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi GetCommandLine für fremde Anwendung (https://www.delphipraxis.net/108151-getcommandline-fuer-fremde-anwendung.html)

ringli 9. Feb 2008 09:57

Re: GetCommandLine für fremde Anwendung
 
Liste der Anhänge anzeigen (Anzahl: 1)
Dank bitsetter's Hilfe konnte das Problem gelöst werden. :thumb:
Im Anhang die Lösung in Form einer kleinen Demoanwendung. Getestet wurde der Code unter den folgenden Betriebssytemen:
  • XP32 --> funktioniert
  • Vista32 --> funktioniert
  • XP64 --> bei 32bit-Anwendungen funktioniert der Code, bei 64bit-Anwendungen funktioniert der Code allerdings nicht was vermutlich daran liegt das 32Bit-Anwendungen keinen Code in eine 64bit-Anwendung injizieren können. Oder hat jemand diesbezüglich einen anderen Wissensstand?

iskywalker 15. Apr 2008 17:28

Re: GetCommandLine für fremde Anwendung
 
Vielleicht pointer größe?
(statt 32 64)

wido 15. Apr 2008 19:39

Re: GetCommandLine für fremde Anwendung
 
32 Bit Prozesse können keine Remote Threads in 64 Bit Prozessen erstellen. Allerdings gibt es dennoch Möglichkeiten der Code Injection.

Ansonsten würde ich von Code Injection die Finger lassen, wenn immer es geht. Prinzipiell kannst Du allein mit ReadProcessMemory die Command Line auslesen. Bei Interesse, kann ichs Dir mal auscoden. Könnte sein, daß es auch mit 64 Bit Prozessen funktioniert. Habs aber nie probiert, daher keine Ahnung.

wido 15. Apr 2008 20:02

Re: GetCommandLine für fremde Anwendung
 
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.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:09 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz