AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Thema durchsuchen
Ansicht
Themen-Optionen

CommandLines der Prozesse unter Windows 64 Bit ermitteln?

Ein Thema von Delphi-Laie · begonnen am 5. Sep 2014 · letzter Beitrag vom 16. Sep 2014
 
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#18

AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?

  Alt 14. Sep 2014, 22:46
Das Problem mit den fehlenden Imports kann ich auch nicht nachvollziehen. Habe mal ein bisschen rumgespielt:
Delphi-Quellcode:
const
  {$IFDEF WIN32}
  OFFSET_PROCESSPARAMETERS = $10;
  OFFSET_COMMANDLINE = $40;
  {$ELSE}
  OFFSET_PROCESSPARAMETERS = $20;
  OFFSET_COMMANDLINE = $70;
  {$ENDIF}
  OFFSET_PROCESSPARAMETERSWOW64 = $20;
  OFFSET_COMMANDLINEWOW64 = $70;

function GetProcessCommandLineFromPEB(hProcess: THandle): String;
var
  Status: NTSTATUS;
  ReturnLength: UInt64;
  ProcessInfo: TProcessBasicInformation;
  ProcessParametersPointer: NativeUInt;
  CommandLine: TUnicodeString;
  {$IFDEF WIN32}
  IsWow64: BOOL;
  Wow64ProcessInfo: TWow64ProcessBasicInformation64;
  Wow64CommandLine: TWow64UnicodeString64;
  Wow64ProcessParametersPointer: UInt64;
  {$ENDIF}
begin
  Result := 'ERROR';
  {$IFDEF WIN32}
  if (not IsWow64Process(hProcess, IsWow64)) then
  begin
    RaiseLastOSError;
  end;
  if (not IsWow64) then
  begin
    // Query PEB base address
    Status := NtWow64QueryInformationProcess64(hProcess, ProcessBasicInformation,
      @Wow64ProcessInfo, SizeOf(Wow64ProcessInfo), @ReturnLength);
    if ((not NT_SUCCESS(Status)) or (ReturnLength <> SizeOf(Wow64ProcessInfo))) then
    begin
      RaiseLastOSError(RtlNtStatusToDosError(Status));
    end;
    // Read the ProcessParameters pointer
    Status := NtWow64ReadVirtualMemory64(hProcess, Wow64ProcessInfo.PebBaseAddress +
      OFFSET_PROCESSPARAMETERSWOW64, @Wow64ProcessParametersPointer,
      SizeOf(Wow64ProcessParametersPointer), @ReturnLength);
    if ((not NT_SUCCESS(Status)) or (ReturnLength <> SizeOf(Wow64ProcessParametersPointer))) then
    begin
      RaiseLastOSError(RtlNtStatusToDosError(Status));
    end;
    // Read the CommandLine UNICODE_STRING
    Status := NtWow64ReadVirtualMemory64(hProcess, Wow64ProcessParametersPointer +
      OFFSET_COMMANDLINEWOW64, @Wow64CommandLine, SizeOf(Wow64CommandLine), @ReturnLength);
    if ((not NT_SUCCESS(Status)) or (ReturnLength <> SizeOf(Wow64CommandLine))) then
    begin
      RaiseLastOSError(RtlNtStatusToDosError(Status));
    end;
    // Read the actual commandline
    SetLength(Result, Wow64CommandLine.Length div SizeOf(Result[1]));
    Status := NtWow64ReadVirtualMemory64(hProcess, Wow64CommandLine.Buffer,
      @Result[1], Wow64CommandLine.Length, @ReturnLength);
    if ((not NT_SUCCESS(Status)) or (ReturnLength <> Wow64CommandLine.Length)) then
    begin
      RaiseLastOSError(RtlNtStatusToDosError(Status));
    end;
    Exit;
  end;
  {$ENDIF}
  // Query PEB base address
  Status := NtQueryInformationProcess(hProcess, ProcessBasicInformation,
    @ProcessInfo, SizeOf(ProcessInfo), @ReturnLength);
  if ((not NT_SUCCESS(Status)) or (ReturnLength <> SizeOf(ProcessInfo))) then
  begin
    RaiseLastOSError(RtlNtStatusToDosError(Status));
  end;
  // Read the ProcessParameters pointer
  Status := NtReadVirtualMemory(hProcess, Pointer(NativeUInt(ProcessInfo.PebBaseAddress) +
    OFFSET_PROCESSPARAMETERS), @ProcessParametersPointer, SizeOf(ProcessParametersPointer),
    @ReturnLength);
  if ((not NT_SUCCESS(Status)) or (ReturnLength <> SizeOf(ProcessParametersPointer))) then
  begin
    RaiseLastOSError(RtlNtStatusToDosError(Status));
  end;
  // Read the CommandLine UNICODE_STRING
  Status := NtReadVirtualMemory(hProcess, Pointer(NativeUInt(ProcessParametersPointer) +
    OFFSET_COMMANDLINE), @CommandLine, SizeOf(CommandLine), @ReturnLength);
  if ((not NT_SUCCESS(Status)) or (ReturnLength <> SizeOf(CommandLine))) then
  begin
    RaiseLastOSError(RtlNtStatusToDosError(Status));
  end;
  // Read the actual commandline
  SetLength(Result, CommandLine.Length div SizeOf(Result[1]));
  Status := NtReadVirtualMemory(hProcess, CommandLine.Buffer, @Result[1], CommandLine.Length,
    @ReturnLength);
  if ((not NT_SUCCESS(Status)) or (ReturnLength <> CommandLine.Length)) then
  begin
    RaiseLastOSError(RtlNtStatusToDosError(Status));
  end;
end;
Zusätzlich brauchst du folgende Definitionen:
Delphi-Quellcode:
type
  NTSTATUS = LongInt;
  HANDLE = THandle;

// Set struct alignment and enum size for C compatibility
{$IFDEF WIN32}
  {$A4}
{$ELSE}
  {$A8}
{$ENDIF}
{$Z4}
type
  TProcessInfoClass = (
    ProcessBasicInformation,
    ProcessQuotaLimits,
    ProcessIoCounters,
    ProcessVmCounters,
    ProcessTimes,
    ProcessBasePriority,
    ProcessRaisePriority,
    ProcessDebugPort,
    ProcessExceptionPort,
    ProcessAccessToken,
    ProcessLdtInformation,
    ProcessLdtSize,
    ProcessDefaultHardErrorMode,
    ProcessIoPortHandlers,
    ProcessPooledUsageAndLimits,
    ProcessWorkingSetWatch,
    ProcessUserModeIOPL,
    ProcessEnableAlignmentFaultFixup,
    ProcessPriorityClass,
    ProcessWx86Information,
    ProcessHandleCount,
    ProcessAffinityMask,
    ProcessPriorityBoost,
    ProcessDeviceMap,
    ProcessSessionInformation,
    ProcessForegroundInformation,
    ProcessWow64Information,
    ProcessImageFileName,
    ProcessLUIDDeviceMapsEnabled,
    ProcessBreakOnTermination,
    ProcessDebugObjectHandle,
    ProcessDebugFlags,
    ProcessHandleTracing,
    MaxProcessInfoClass);

type
  TProcessBasicInformation = record
    ExitStatus: Cardinal;
    PebBaseAddress: PVOID;
    AffinityMask: NativeUInt;
    BasePriority: NativeUInt;
    UniqueProcessId: NativeUInt;
    InheritedFromUniqueProcessId: NativeUInt;
  end;
{$IFDEF WIN32}
  TWow64ProcessBasicInformation64 = record
    ExitStatus: Cardinal;
    Pad1: DWord;
    PebBaseAddress: UInt64;
    AffinityMask: UInt64;
    BasePriority: Cardinal;
    Pad2: DWord;
    UniqueProcessId: UInt64;
    InheritedFromUniqueProcessId: UInt64;
  end;
{$ENDIF}

  TUnicodeString = record
    Length: USHORT;
    MaximumLength: USHORT;
    Buffer: Pointer;
  end;
{$IFDEF WIN32}
  TWow64UnicodeString64 = record
    Length: USHORT;
    MaximumLength: USHORT;
    Pad1: DWord;
    Buffer: UInt64;
  end;
{$ENDIF}

{$IFDEF WIN32}
function NtWow64QueryInformationProcess64(ProcessHandle: HANDLE;
  ProcessInformationClass: TProcessInfoClass; ProcessInformation: PVOID;
  ProcessInformationLength: ULONG; ReturnLength: PUInt64): NTSTATUS; stdcall; external 'ntdll.dll';
function NtWow64ReadVirtualMemory64(ProcessHandle: HANDLE; BaseAddress: UInt64; Buffer: Pointer;
  BufferLength: UInt64; ReturnLength: PUInt64): NTSTATUS; stdcall; external 'ntdll.dll';
{$ENDIF}

function NtQueryInformationProcess(ProcessHandle: HANDLE;
  ProcessInformationClass: TProcessInfoClass; ProcessInformation: PVOID;
  ProcessInformationLength: ULONG; ReturnLength: PULONG): NTSTATUS; stdcall; external 'ntdll.dll';
function NtReadVirtualMemory(ProcessHandle: HANDLE; BaseAddress : PVOID; Buffer: PVOID;
  BufferLength: ULONG; ReturnLength: PULONG): NTSTATUS; stdcall; external 'ntdll.dll';
function RtlNtStatusToDosError(Status: NTSTATUS): ULONG; stdcall; external 'ntdll.dll';

function NT_SUCCESS(Status: NTSTATUS): BOOL;
begin
  Result := Status >= 0;
end;
Und der Aufruf wäre z.b. so:
Delphi-Quellcode:
procedure TForm2.Button1Click(Sender: TObject);
var
  hProcess: THandle;
begin
  hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or PROCESS_VM_READ,
    false, 3000);
  if (hProcess <> 0) then
  try
    MessageBox(0, PChar(GetProcessCommandlineFromPEB(hProcess)), 'Info', MB_ICONINFORMATION);
  finally
    CloseHandle(hProcess);
  end;
end;
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:15 Uhr.
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