* * *

Author Topic: g  (Read 5058 times)

mcland

  • Guest
g
« on: October 09, 2017, 12:02:31 pm »
No
« Last Edit: February 20, 2018, 12:27:08 pm by mcland »

Thaddy

  • Hero Member
  • *****
  • Posts: 6359
Re: get process path
« Reply #1 on: October 09, 2017, 12:05:45 pm »
For your own process it is simply:
Code: Pascal  [Select]
  1. program program1;
  2. begin
  3.   writeln(paramstr(0));  // paramstr(0) contains the full path x-platform.  
  4. end.

For other processes it is way more complex
- They may be hidden
- They may be symlinked
- They maybe only exist in memory, so you need the launching application.

What do you exactly want? It is more a hackers technique than useful in a normal context.
« Last Edit: October 09, 2017, 12:08:59 pm by Thaddy »
I am enjoining wine, not whine....

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 6327
Re: get process path
« Reply #2 on: October 09, 2017, 12:09:00 pm »
Note that "ExtractFileName" strips the path, so maybe your way shows the path too, but you strip it before writeln()ing.

GetMem

  • Hero Member
  • *****
  • Posts: 3083
Re: get process path
« Reply #3 on: October 09, 2017, 01:24:04 pm »
Try something like this:
Code: Pascal  [Select]
  1. uses JwaPsApi;
  2.  
  3. function GetProcessFileName(PID : DWORD) : string;
  4. var
  5.   Handle : THandle;
  6. begin
  7.    Result := '-';
  8.    Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID);
  9.    if Handle <> 0 then
  10.     try
  11.       SetLength(Result, MAX_PATH);
  12.       if GetModuleFileNameEx(Handle, 0, Pchar(Result), MAX_PATH) > 0 then
  13.       begin
  14.          SetLength(Result, StrLen(PChar(Result)));
  15.          if not FileExists(Result) then
  16.            Result := '-';
  17.       end
  18.       else
  19.         Result := '-';
  20.     finally
  21.       CloseHandle(Handle);
  22.     end;
  23. end;
  24.  
  25. //....
  26. Writeln(GetProcessFileName(pe.th32ProcessID));

To open a process you need elevated privileges, so for some processes might not work.

Thaddy

  • Hero Member
  • *****
  • Posts: 6359
Re: get process path
« Reply #4 on: October 09, 2017, 03:39:58 pm »
there is no way to do with windows api as Process32First?
with taskmanager you can see the full path of a process and there is no need to be administrator...
That's because they are in-memory processes: you will need to do more to see from where a process is launched.
Why do you really need it?


As usual you can find those things on http://www.delphibasics.info/ btw.
The best source available for anyone dabbling with hacker things in Object Pascal....
You will find it is full of useful snippets for the idiots, malware writers and "system protectors".

Why do you need such techniques?

It would also help if you are able to translate C code into Object Pascal and examine anything sysinternals...
« Last Edit: October 09, 2017, 03:54:25 pm by Thaddy »
I am enjoining wine, not whine....

GetMem

  • Hero Member
  • *****
  • Posts: 3083
Re: get process path
« Reply #5 on: October 09, 2017, 06:15:25 pm »
@mcland
Quote
i'm building my own antivirus for my company.
OMG this is a good one! Thaddy will help you with this project.  :D
Now seriously listing processes won't help you detecting viruses/trojans/rootkits. A malware can take many form, it can be a driver, a dll injected in another process, a hijecked dll, exe injected inside another exe(PE injection) etc. By the way that Aphex code won't work with vista+, since services are isolate in session0. The only method which will work with services is a WMI query, using win32_process(https://msdn.microsoft.com/en-us/library/windows/desktop/aa394372(v=VS.85).aspx). AFAIK the same method is used by Process Explorer, Process Hacker etc...

Thaddy

  • Hero Member
  • *****
  • Posts: 6359
Re: get process path
« Reply #6 on: October 09, 2017, 07:32:42 pm »
OMG this is a good one! Thaddy will help you with this project.  :D
Well, can't hurt too much if he can't find the sourcecode on the website I pointed him to anyway... Can it? And these techniques are all covered nowadays...  :D :D O:-)

(For noobs and scriptkiddies, I forgot those two...the sourcecode is there....)
« Last Edit: October 09, 2017, 07:36:32 pm by Thaddy »
I am enjoining wine, not whine....

Remy Lebeau

  • Sr. Member
  • ****
  • Posts: 426
    • Lebeau Software
Re: get process path
« Reply #7 on: October 09, 2017, 09:15:28 pm »
Try something like this:
Code: Pascal  [Select]
  1.    Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID);
  2.    ...
  3.    if GetModuleFileNameEx(Handle, 0, Pchar(Result), MAX_PATH) > 0 then
  4.  

To open a process you need elevated privileges, so for some processes might not work.

You should be using GetProcessImageFileName() or QueryFullProcessImageName() instead.  Even the documentation for GetModuleFileNameEx() says so:

Quote
To retrieve the name of the main executable module for a remote process, use the GetProcessImageFileName or QueryFullProcessImageName function. This is more efficient and more reliable than calling the GetModuleFileNameEx function with a NULL module handle.

The upside is that they both work with PROCESS_QUERY_LIMITED_INFORMATION access, and do not require PROCESS_VM_READ access, so a non-elevated process can get the path+filename of an external process.
« Last Edit: October 09, 2017, 09:21:23 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

RAW

  • Hero Member
  • *****
  • Posts: 667
Re: get process path
« Reply #8 on: October 09, 2017, 09:38:49 pm »
My recommendation...
Windows 7 Pro (x64 Sp1) And Windows XP Pro (x86 Sp3) - LAZARUS 1.8.4 FPC 3.0.4 // 1.7 FPC 3.1.1

Remy Lebeau

  • Sr. Member
  • ****
  • Posts: 426
    • Lebeau Software
Re: get process path
« Reply #9 on: October 10, 2017, 08:49:41 pm »
Code: [Select]
      s2 := OpenProcess(PROCESS_QUERY_INFORMATION, False, PID);
      GetModuleFileName(s2, path, sizeof(path));

You can't use GetModuleFileName() to query the filename of a module that is outside of your own process.  The first parameter is a module handle relative to your own process, but you are passing it a process handle instead.  You must use GetModuleFileNameEx() (or GetProcessImageFileName() or QueryFullProcessImageName()) to query the filename of a module in another process.

if change GetModuleFileName for GetModuleFileNameEx then the first letter of the path is unreadable (and the path is always the same)

Then you are using it wrong.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Remy Lebeau

  • Sr. Member
  • ****
  • Posts: 426
    • Lebeau Software
Re: get process path
« Reply #10 on: October 10, 2017, 09:13:59 pm »
Sorry, i don't know how to use this part of the windows api.

There are plenty of online examples readily available.  You are just guessing instead of actually researching.

This code only prints process name :(

That is because 1) you are using ExtractFileName() to strip off any possible path information, and 2) pe.szExeFile doesn't contain path information to begin with.  Even the documentation says so:

Quote
szExeFile

The name of the executable file for the process. To retrieve the full path to the executable file, call the Module32First function and check the szExePath member of the MODULEENTRY32 structure that is returned. However, if the calling process is a 32-bit process, you must call the QueryFullProcessImageName function to retrieve the full path of the executable file for a 64-bit process.

Try something more like this instead:

Code: [Select]
program myprocess;

uses
  crt, sysutils, dos, jwatlhelp32, windows, process, JwaWindows;

var
  S, proc: HANDLE;
  PE: TProcessEntry32;
  buffer: array[0..MAX_PATH-1] of Char;
  OK: Boolean;
  size: DWORD;
begin
  S := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0); // Create snapshot
  if S = INVALID_HANDLE_VALUE then
  begin
    // handle error as needed...
  end else
  try
    PE.dwSize := SizeOf(PE); // Set size before use
    OK := Process32First(S, PE);
    while OK do
    begin
      writeln('proceso: ', PE.szExeFile);
      proc := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, PE.th32ProcessID);
      if proc = 0 then
      begin
        // handle error as needed...
      end else
      try
        size := MAX_PATH;
        if not QueryFullProcessImageName(proc, 0, buffer, @size) then
        begin
          // handle error as needed...
        end else
          writeln('path: ', buffer);
      finally
        CloseHandle(proc);
      end;
      readkey;
      OK := Process32Next(S, PE);
    end;
    if GetLastError() <>  ERROR_NO_MORE_FILES then
    begin
      // handle error as needed...
    end;
  finally
    CloseHandle(S);
  end;
end.
« Last Edit: October 10, 2017, 09:15:58 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

GetMem

  • Hero Member
  • *****
  • Posts: 3083
Re: get process path
« Reply #11 on: October 10, 2017, 09:52:25 pm »
@Remy Lebeau

Quote
You should be using GetProcessImageFileName() or QueryFullProcessImageName() instead.  Even the documentation for GetModuleFileNameEx() says so:
Thanks.

I did not find PROCESS_QUERY_LIMITED_INFORMATION declared in FPC. The same is true for QueryFullProcessImageName, so I modified the code a little bit. It works fine now with Lazarus trunk/FPC 3.0.2:
Code: Pascal  [Select]
  1. {$mode objfpc}{$H+}
  2.  
  3. uses
  4.   {$IFDEF UNIX}{$IFDEF UseCThreads}
  5.   cthreads,
  6.   {$ENDIF}{$ENDIF}
  7.   Classes,
  8.   JwaWindows;
  9.  
  10.  
  11. const
  12.   PROCESS_QUERY_LIMITED_INFORMATION = $1000;
  13.  
  14. var
  15.   S, proc: HANDLE;
  16.   PE: TProcessEntry32;
  17.   us: UnicodeString;
  18.   OK: Boolean;
  19.   size: DWORD;
  20.  
  21.   function QueryFullProcessImageName(hProcess:HANDLE; dwFlags: DWord; lpExeName:LPWSTR;
  22.     var lpdwSize:DWORD):BOOL; stdcall; external 'kernel32' name 'QueryFullProcessImageNameW';
  23.  
  24. begin
  25.   S := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0); // Create snapshot
  26.   if S = INVALID_HANDLE_VALUE then
  27.   begin
  28.     // handle error as needed...
  29.   end else
  30.   try
  31.     PE.dwSize := SizeOf(PE); // Set size before use
  32.     OK := Process32First(S, PE);
  33.     while OK do
  34.     begin
  35.       writeln('Image name: ', PE.szExeFile);
  36.       proc := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, PE.th32ProcessID);
  37.       if proc = 0 then
  38.       begin
  39.         // handle error as needed...
  40.         writeln('Image path: -');
  41.       end else
  42.       try
  43.         size := MAX_PATH;
  44.         SetLength(us, size);
  45.         if not QueryFullProcessImageName(proc, 0, @us[1], size) then
  46.         begin
  47.           // handle error as needed...
  48.           writeln('Image path: -');
  49.         end else
  50.         begin
  51.           SetLength(us, size);
  52.           writeln('Image path: ', us);
  53.         end;
  54.       finally
  55.         CloseHandle(proc);
  56.       end;
  57.       Readln;
  58.       OK := Process32Next(S, PE);
  59.     end;
  60.     if GetLastError() <>  ERROR_NO_MORE_FILES then
  61.     begin
  62.       // handle error as needed...
  63.     end;
  64.   finally
  65.     CloseHandle(S);
  66.   end;
  67. end.
« Last Edit: October 10, 2017, 10:02:17 pm by GetMem »

ASerge

  • Hero Member
  • *****
  • Posts: 827
Re: get process path
« Reply #12 on: October 11, 2017, 01:11:39 am »
The same with the discussion :): Get list of process

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus