Assaf_Gantz
asked on
How to get Process/Service full path using the process id only, mainly on Itanuim with windows 2003 R2
can you recommend an easy way to find running process binary path by pid on window only.
For example I would like to take process pid (1234) and trace the full path to the binary that is running (c:\program files\...\abc.exe).
I am getting errors while trying to investigate a process under windows 2003 R2
I need the solution to be in C++ and won't involve anything that can be consider as a security holes.
10x
Assaf
For example I would like to take process pid (1234) and trace the full path to the binary that is running (c:\program files\...\abc.exe).
I am getting errors while trying to investigate a process under windows 2003 R2
I need the solution to be in C++ and won't involve anything that can be consider as a security holes.
10x
Assaf
you have to get in to the parent process of all.( desktop window). check process explorer tool of sysinternals for detailed process in tree view.
yu can get the desktop window using GetDesktopWindow function.
Then you have to get in to each process using the getchildprocess handle, using Enumerate all windows (EnumWindows()),
you can check the name of the process. and if it matches with your criteria. then you can get the details of the particular process.
or else if you have pid. then you have to get to the pid from getting handle. and you have to compare with the pid you have
to get pid from handle GetWindowThreadProcessId(I ntPtr hwnd, out uint lpdwProcessId);
in windows you can control everything only with the handle.
from the handle you can get the path of the particular process
yu can get the desktop window using GetDesktopWindow function.
Then you have to get in to each process using the getchildprocess handle, using Enumerate all windows (EnumWindows()),
you can check the name of the process. and if it matches with your criteria. then you can get the details of the particular process.
or else if you have pid. then you have to get to the pid from getting handle. and you have to compare with the pid you have
to get pid from handle GetWindowThreadProcessId(I
in windows you can control everything only with the handle.
from the handle you can get the path of the particular process
this what you are exactly looking for..
get use of the same function in vc++, and solve it.
http://www.elists.org/pipermail/delphi-talk/2004-September/019577.html
get use of the same function in vc++, and solve it.
http://www.elists.org/pipermail/delphi-talk/2004-September/019577.html
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
All your answers are being tried but my main issue those process
I am looking for are SERVICES and I just can get the OpenProcess command open them without getting any errors.
I have Admin privilages on the box and still I am not able to view the process information.
I am looking for are SERVICES and I just can get the OpenProcess command open them without getting any errors.
I have Admin privilages on the box and still I am not able to view the process information.
ASKER
Here some additional info This is the error message when ever I try to investigate the Process:
error failed to open process
Failed to open process. pid: 7772, error 5
.\main.cpp:855, Win32 error: Access is denied, code: 5
Please choose pid to memdump 0 to quit [7772]: 7916
error failed to open process
Failed to open process. pid: 7772, error 5
.\main.cpp:855, Win32 error: Access is denied, code: 5
Please choose pid to memdump 0 to quit [7772]: 7916
As I mentioned earlier, your process needs special privilages to open other processes.
Copy th efollowing function to your source and call it once before you make OpenProcess() call.
BOOL GrabKillerPrivilage()
{
TOKEN_PRIVILEGES Priv, PrivOld;
DWORD cbPriv = sizeof(PrivOld);
HANDLE hToken;
DWORD dwError;
// get current thread token
if (!OpenThreadToken(GetCurre
TOKEN_QUERY|TOKEN_ADJUST_P
FALSE, &hToken))
{
if (GetLastError() != ERROR_NO_TOKEN)
return FALSE;
// revert to the process token, if not impersonating
if (!OpenProcessToken(GetCurr
TOKEN_QUERY|TOKEN_ADJUST_P
&hToken))
return FALSE;
}
Priv.PrivilegeCount = 1;
Priv.Privileges[0].Attribu
LookupPrivilegeValue(NULL,
// try to enable the privilege
if (!AdjustTokenPrivileges(hT
FALSE,
&Priv,
sizeof(Priv),
&PrivOld,
&cbPriv))
{
dwError = GetLastError();
CloseHandle(hToken);
return SetLastError(dwError), FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
// the SE_DEBUG_NAME privilege is not in the caller's token
CloseHandle(hToken);
return SetLastError(ERROR_ACCESS_
}
return TRUE;
}
ASKER
We are slowly getting closer, below my code and the output
Still we fail on Itanium
Output:
C:\>proc_test2.exe 476
Pid to examine 476
*** OpenThreadToken failed is it ERROR_NO_TOKEN ?
*** EnumProcessModules failed
C:\Documents and Settings\agantz\My Documents\Visual Studio Projects\proc_test2\proc_t est.cpp:12 5, Win32 error: Only par
t of a ReadProcessMemory or WriteProcessMemory request was completed, code: 299
CODE:
// proc_cmd.cpp : Defines the entry point for the application.
//
// #include "stdafx.h"
#include <iostream.h>
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
#include <Aclapi.h>
#include <stdlib.h>
PCHAR GetLastWin32ErrorMsg(int ErrorCode)
{
int Len;
__declspec(thread) static char Buffer[255];
Len = FormatMessage(FORMAT_MESSA GE_FROM_SY STEM | FORMAT_MESSAGE_ARGUMENT_AR RAY, NULL, ErrorCode, 0, Buffer,
sizeof(Buffer), NULL);
while (Len > 0 && Buffer[Len - 1] > 0 && Buffer[Len - 1] < 32 || Buffer[Len - 1] == '.')
Len--;
Buffer[Len] = '\0';
return Buffer;
}
#define CHECK_ERROR_CODE(Result) { \
if (Result != ERROR_SUCCESS) { \
fprintf(stderr, "%s:%d, Win32 error: %s, code: %d\n", __FILE__, __LINE__, GetLastWin32ErrorMsg(Resul t), Result); \
}}
#define WIN32CHECK(Result) if (!Result) {CHECK_ERROR_CODE(GetLastE rror())}
BOOL GrabKillerPrivilage()
{
TOKEN_PRIVILEGES Priv, PrivOld;
DWORD cbPriv = sizeof(PrivOld);
HANDLE hToken;
DWORD dwError;
// get current thread token
if (!OpenThreadToken(GetCurre ntThread() ,
TOKEN_QUERY|TOKEN_ADJUST_P RIVILEGES,
FALSE, &hToken))
{
cout << "*** OpenThreadToken failed is it ERROR_NO_TOKEN ?" << endl;
if (GetLastError() != ERROR_NO_TOKEN) {
cout << "*** OpenThreadToken failed" << endl;
return FALSE;
}
// revert to the process token, if not impersonating
if (!OpenProcessToken(GetCurr entProcess (),
TOKEN_QUERY|TOKEN_ADJUST_P RIVILEGES,
&hToken)) {
cout << "*** OpenProcessToken failed" << endl;
return FALSE;
}
}
Priv.PrivilegeCount = 1;
Priv.Privileges[0].Attribu tes = SE_PRIVILEGE_ENABLED;
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Priv.Privileges[0].Luid);
// try to enable the privilege
if (!AdjustTokenPrivileges(hT oken,
FALSE,
&Priv,
sizeof(Priv),
&PrivOld,
&cbPriv))
{
cout << "*** AdjustTokenPrivileges failed" << endl;
dwError = GetLastError();
CloseHandle(hToken);
return SetLastError(dwError), FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
cout << "*** SE_DEBUG_NAME privilege is not in the caller's token" << endl;
// the SE_DEBUG_NAME privilege is not in the caller's token
CloseHandle(hToken);
SetLastError(ERROR_ACCESS_ DENIED);
return FALSE;
//return SetLastError(ERROR_ACCESS_ DENIED), FALSE;
}
return TRUE;
}
int main (int argc, char *argv[])
{
if (argc < 2) {
cout << "Usage: " << argv[0] << " <PID>" << endl;
return -1;
}
int nPid = atoi(argv[1]);
cout << "Pid to examine " << nPid << endl;
WIN32CHECK(GrabKillerPrivi lage());
HANDLE hProc = OpenProcess(PROCESS_QUERY_ INFORMATIO N | PROCESS_VM_READ, FALSE, nPid);
char ProcessCmd[1024];
if(hProc){
HMODULE hMod;
DWORD needed;
if(EnumProcessModules(hPro c, &hMod, sizeof(hMod), &needed)) {
WIN32CHECK(GetModuleFileNa meEx(hProc , hMod, ProcessCmd, sizeof(ProcessCmd)/ sizeof(ProcessCmd[0])));
cout << "Process CMD = " << ProcessCmd << endl;
} else {
cout << "*** EnumProcessModules failed" << endl;
WIN32CHECK(0);
}
CloseHandle(hProc);
} else {
cout << "*** OpenProcess failed" << endl;
WIN32CHECK(0);
}
return 0;
}
Still we fail on Itanium
Output:
C:\>proc_test2.exe 476
Pid to examine 476
*** OpenThreadToken failed is it ERROR_NO_TOKEN ?
*** EnumProcessModules failed
C:\Documents and Settings\agantz\My Documents\Visual Studio Projects\proc_test2\proc_t
t of a ReadProcessMemory or WriteProcessMemory request was completed, code: 299
CODE:
// proc_cmd.cpp : Defines the entry point for the application.
//
// #include "stdafx.h"
#include <iostream.h>
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
#include <Aclapi.h>
#include <stdlib.h>
PCHAR GetLastWin32ErrorMsg(int ErrorCode)
{
int Len;
__declspec(thread) static char Buffer[255];
Len = FormatMessage(FORMAT_MESSA
sizeof(Buffer), NULL);
while (Len > 0 && Buffer[Len - 1] > 0 && Buffer[Len - 1] < 32 || Buffer[Len - 1] == '.')
Len--;
Buffer[Len] = '\0';
return Buffer;
}
#define CHECK_ERROR_CODE(Result) { \
if (Result != ERROR_SUCCESS) { \
fprintf(stderr, "%s:%d, Win32 error: %s, code: %d\n", __FILE__, __LINE__, GetLastWin32ErrorMsg(Resul
}}
#define WIN32CHECK(Result) if (!Result) {CHECK_ERROR_CODE(GetLastE
BOOL GrabKillerPrivilage()
{
TOKEN_PRIVILEGES Priv, PrivOld;
DWORD cbPriv = sizeof(PrivOld);
HANDLE hToken;
DWORD dwError;
// get current thread token
if (!OpenThreadToken(GetCurre
TOKEN_QUERY|TOKEN_ADJUST_P
FALSE, &hToken))
{
cout << "*** OpenThreadToken failed is it ERROR_NO_TOKEN ?" << endl;
if (GetLastError() != ERROR_NO_TOKEN) {
cout << "*** OpenThreadToken failed" << endl;
return FALSE;
}
// revert to the process token, if not impersonating
if (!OpenProcessToken(GetCurr
TOKEN_QUERY|TOKEN_ADJUST_P
&hToken)) {
cout << "*** OpenProcessToken failed" << endl;
return FALSE;
}
}
Priv.PrivilegeCount = 1;
Priv.Privileges[0].Attribu
LookupPrivilegeValue(NULL,
// try to enable the privilege
if (!AdjustTokenPrivileges(hT
FALSE,
&Priv,
sizeof(Priv),
&PrivOld,
&cbPriv))
{
cout << "*** AdjustTokenPrivileges failed" << endl;
dwError = GetLastError();
CloseHandle(hToken);
return SetLastError(dwError), FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
cout << "*** SE_DEBUG_NAME privilege is not in the caller's token" << endl;
// the SE_DEBUG_NAME privilege is not in the caller's token
CloseHandle(hToken);
SetLastError(ERROR_ACCESS_
return FALSE;
//return SetLastError(ERROR_ACCESS_
}
return TRUE;
}
int main (int argc, char *argv[])
{
if (argc < 2) {
cout << "Usage: " << argv[0] << " <PID>" << endl;
return -1;
}
int nPid = atoi(argv[1]);
cout << "Pid to examine " << nPid << endl;
WIN32CHECK(GrabKillerPrivi
HANDLE hProc = OpenProcess(PROCESS_QUERY_
char ProcessCmd[1024];
if(hProc){
HMODULE hMod;
DWORD needed;
if(EnumProcessModules(hPro
WIN32CHECK(GetModuleFileNa
cout << "Process CMD = " << ProcessCmd << endl;
} else {
cout << "*** EnumProcessModules failed" << endl;
WIN32CHECK(0);
}
CloseHandle(hProc);
} else {
cout << "*** OpenProcess failed" << endl;
WIN32CHECK(0);
}
return 0;
}
You can try these:
1) Change the hMod parameter of EnumProcesModule to an array - like this
HMODULE hMod[1024];
EnumProcessModules(hProc, &hMod, sizeof(hMod), &needed)) ;
2) If you are interesed only the exe file name you don't have to call EnumProcessModules.
Call GetModuleBaseName instead.
1) Change the hMod parameter of EnumProcesModule to an array - like this
HMODULE hMod[1024];
EnumProcessModules(hProc, &hMod, sizeof(hMod), &needed)) ;
2) If you are interesed only the exe file name you don't have to call EnumProcessModules.
Call GetModuleBaseName instead.
ASKER
1. I am getting the same error
2. I need the full path to the binary not just the name
I think the problem related to 64 bits and I saw online that EnumProcessModulesEx
https://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/enumprocessmodulesex.asp
2. I need the full path to the binary not just the name
I think the problem related to 64 bits and I saw online that EnumProcessModulesEx
https://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/enumprocessmodulesex.asp
ASKER
I see that some others identify this problem
http://www.64bit-world.com/forums/archive/index.php/t-5367.html
http://www.64bit-world.com/forums/archive/index.php/t-5367.html
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I know it is not the full answer but it was helping me understand what's going on
10x
Assaf
10x
Assaf
Take a look at
http://msdn2.microsoft.com/en-gb/library/ms683196.aspx
They also have an example
http://msdn2.microsoft.com/en-gb/library/ms682621.aspx
Basically you need to do a OpenProcess() on your target process id to get a handle to the process.
Then use that handle as described in above article to query file names.
Hope you are aware that your monitor process need proper privilages to query these kind of information.
Please let us know if you have trouble settings process privilages.
best
~J