Einzelnen Beitrag anzeigen

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