[problem]How get CommandLine from other applacation?

delphi package - getting into other processes
Post Reply
Ahell
Posts: 31
Joined: Mon Feb 07, 2011 4:54 pm

[problem]How get CommandLine from other applacation?

Post by Ahell »

Hello Madshi!

How I can get CMDLine from other application?

I'm write down this code:

Code: Select all

library HLRPI;

uses
  madRemote;

{$R *.res}

const
  MAX_PATH = 260;
  kernel32 = 'kernel32.dll';

type
  DWORD = LongWord;

function GetCommandLineW: PWideChar; stdcall; external kernel32 name 'GetCommandLineW';  //For perfect results of all chars from cmd. Like /english /Русский /こんにちは /Empfehlung etc. 

function GetCmdLineThread(buffer: PWideChar): DWORD; stdcall;
var
  cl: PWideChar;
begin
  cl := GetCommandLineW;
  for result := 0 to MAX_PATH - 1 do
  begin
    buffer[result] := cl[result];
    if buffer[result] = #0 then
      break;
  end;
end;

function GetProcessCdLine(aProcID: Cardinal): string; cdecl; 
var
  arrCh: array[0..MAX_PATH - 1] of WideChar;
  len: dword;
begin
  if RemoteExecute(aProcID, @GetCmdLineThread, len, @arrCh, MAX_PATH) then
    SetString(result, arrCh, len)
  else
    result := '';
end;

exports GetProcessCmdLine;

begin
end.
And I call it from DLL by dynamic load:

Code: Select all

const
  HLRPI = 'HLRPI.dll';

type
  TGetProcessCMDLine = function(aValue: Cardinal): string;

function GetProcessCMD(aProcID: Cardinal; var aReturnStr: string): Boolean;

implementation

function GetProcessCMD(aProcID: Cardinal; var aReturnStr: string): Boolean;
var
  hDLL: THandle;
  hFunc: TGetProcessCMDLine;
begin
  Result := False;
  if (aProcID <= 0) then Exit;
  aReturnStr := '';
  hDLL := 0;
  hFunc := nil;
  try
    hDLL := LoadLibrary(PAnsiChar(HLRPI));
    if (hDLL <> 0) then
    begin
      @hFunc := GetProcAddress(hDLL, PAnsiChar('GetProcessCmdLine'));
      if Addr(hFunc) <> nil then
      begin
        aReturnStr := hFunc(aProcID);
        Result:=True;
        end
      else
        Result := False;
    end
    else
    begin
      Result := False;
    end;
  finally
    FreeLibrary(hDLL);
  end;
end;
DLL compiled with Delphi XE2.

GetProcessCMD work's fine. But GetProcessCmdLine function return is empty. Why?

I don't have a commercial license.

Or may be, how I can get CMD line without using madCHook.dll+mchEvaluation.exe?
madshi
Site Admin
Posts: 10749
Joined: Sun Mar 21, 2004 5:25 pm

Re: [problem]How get CommandLine from other applacation?

Post by madshi »

The "aProcID" name suggests that you're using a processID. But RemoteExecute needs a process *handle*, which is a different thing. Maybe that's already the cause of the problem?
Ahell
Posts: 31
Joined: Mon Feb 07, 2011 4:54 pm

Re: [problem]How get CommandLine from other applacation?

Post by Ahell »

:o
Thanks! But it still doesn't solve problem.

Code: Select all

library HLRPI;

uses
  madRemote;

{$R *.res}

const
  MAX_PATH = 260;
  kernel32 = 'kernel32.dll';
  STANDARD_RIGHTS_REQUIRED = $000F0000;
  SYNCHRONIZE = $00100000;
  PROCESS_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $FFFF);

type
  DWORD = LongWord;
  Bool = LongBool;

function GetCommandLineW: PWideChar; stdcall;
  external kernel32 name 'GetCommandLineW';

function OpenProcess(dwDesiredAccess: DWORD; bInheritHandle: BOOL;
  dwProcessId: DWORD): THandle; stdcall; external kernel32 name 'OpenProcess';

function CloseHandle(hObject: THandle): BOOL; stdcall;
  external kernel32 name 'CloseHandle';

function GetCmdLineThread(buffer: PWideChar): DWORD; stdcall;
var
  cl: PWideChar;
begin
  cl := GetCommandLineW;
  for result := 0 to MAX_PATH - 1 do
  begin
    buffer[result] := cl[result];
    if buffer[result] = #0 then
      break;
  end;
end;

function GetProcessCmdLine(aProcID: Cardinal): string; cdecl; // c++ compability
var
  arrCh: array [0 .. MAX_PATH - 1] of WideChar;
  hProcess: THandle;
  len: DWORD;
begin
  hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, aProcID);
  try
    if hProcess <> 0 then
    begin
      if RemoteExecute(hProcess, @GetCmdLineThread, len, @arrCh, MAX_PATH) then
        SetString(result, arrCh, len)
      else
        result := '';
    end;
  finally
    CloseHandle(hProcess);
  end;
end;

exports
  GetProcessCmdLine;

begin

end.
The result of the function is empty..
My application already have a debug privilege, before using this function.. Or may be, I'm need give it to dll? :o

Can you explain, how to get the command line of another process without using MadCodehook (trial-version)? :wink:
I'm need only this function..
madshi
Site Admin
Posts: 10749
Joined: Sun Mar 21, 2004 5:25 pm

Re: [problem]How get CommandLine from other applacation?

Post by madshi »

Does OpenProcess succeed?

Doing this without madRemote? Well, you could (mis)use SetWindowsHookEx to inject a dll into the target process, and then use some kind of inter process communication to transport the command line back to you. Sorry, you'll have to figure out the details yourself... ;)
Ahell
Posts: 31
Joined: Mon Feb 07, 2011 4:54 pm

Re: [problem]How get CommandLine from other applacation?

Post by Ahell »

Yes, open process succeed.
I had ported dll code to exe and result of function are succeed, but it isn't friendly with Unicode(Application written in Delphi 7).
All of non-ASCI Chars, I've seen as "console.exe -first /second --¦єёёъшщ -p"T++T"" Original of this "console.exe -first /second --Русский -p"ЛООЛ""

Function from dll, return empty string..... :o

Hm, why I'm need load and call my dll from other process? After OpenProcess, I can't got this information? Why?
MadKernel already have property IProcess.CommandLine : string; but it's using MadCodeHook(splashscreen,,).. :sorry:


Other questions:
When we can see a new release of MadExcept, with support Memory Leaks catching? MaxExcept must have this tool :crazy:
madshi
Site Admin
Posts: 10749
Joined: Sun Mar 21, 2004 5:25 pm

Re: [problem]How get CommandLine from other applacation?

Post by madshi »

In your "GetProcessCmdLine" function you're using an array of WideChar, but you return a "string". A "string" is Unicode in XE2, but Ansi in Delphi 7. So if you want to use this code with Delphi 7, you have to change "string" to "WideString". That should take care of the unicode problems. The next problem is that if you let your DLL return a Delphi style "string" or "wideString", these are dynamic constructs which only work properly if the dll and exe are sharing the same memory manager.

Memory leak catching might be added to madExcept 4. Sorry, no release date yet.
Post Reply