Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find the parent exe of a dll from inside the dll?

I need to do some stuff in a dll based on which process has loaded it. So being relatively new to windows programming I need help figuring out how to find the exe which loaded the current dll. So far I have been hard coding the exe file name, which is the dumbest thing to do :D

1) Some one suggested using GetModuleFileName() function. But this seems to crash my app.(I used 0 as the module handle). I am doing nothing fancy. I used the following syntax

GetModuleFileName(0,&fileName,MAX_PATH)

EDIT: I understood from here that I cannot get the .exe name with this call as it returns only the dll name :(

2)Is it a good idea to do this in the DllMain ?? I know that DllMain is not the place to do complicated stuff. I also understand loader lock related issues.All I need is to find the name of the parent process.

I appreciate your time !

ADD: I tried to use GetProcessImageFileName after getting the parent process ID. I get an access violation error. When I tried to debug I noticed that the openProcess call leaves my result argument(image file path-LPTSTR) as a bad pointer.
Error code 87-INVALID PARAMETER is returned by the GetProcessImageFileName call.
But the current process id is a valid id.
Here is the code

LPTSTR fileName={0};  
HANDLE hP=OpenProcess(PROCESS_QUERY_INFORMATION ,FALSE, processes[i]) ;
GetProcessImageFileName(hP,fileName,(DWORD)MAX_PATH+1);

What Am I doing wrong??

Thanks

EDIT IMPORTANT:

I found out that I am trying to use openprocess on an idle process. (i.e) I forgot that my parent process could possibly be waiting idle for me since I sync it . So now I got the bad news that I cannot open an idle process using OpenProcess. How else can i get to look into the object of an Idle process?? (I know for sure its idle because I could not find it in the snapshot. I had to use enumerateprocess to locate its id; But i do use normal process enumeration from the snapshot to find the parent process id in the first place)

like image 610
ash Avatar asked Jun 09 '11 00:06

ash


2 Answers

If you have declared your fileName variable as something like char fileName or char fileName[MAX_PATH], you may receive an error because your parameter is incorrect: you use the address of the variable (though, you don't specify whether it is a compile time error or runtime error, you say it crashes your app, so I go with Richard here, you've not allocated your variable).

I tried the following code, which works both from within a DLL (it gets the name of the executable, not the DLL module) or from within the executable itself.
(Note: code updated based on Remy's comments below, thanks)

WCHAR exePath[MAX_PATH + 1];
DWORD len = GetModuleFileNameW(NULL, exePath, MAX_PATH);
if (len > 0) {
    wcout 
       << L"Exe path" 
       << (len == MAX_PATH) ? L" (truncated):" : L":" 
       << exePath 
       << endl;
} else {
    wcout 
       << L"Error getting exe path: " 
       << GetLastError() 
       << endl;
}

Note: if the buffer is not large enough, GetModuleFileName will truncate the result and return nSize.

More on handling filenames in Win32.

like image 85
Abel Avatar answered Nov 07 '22 11:11

Abel


Refer the following link to know about the syntax and the detailed description about the GetModuleFileName()

Steps to do:

First get the full path of the executable file using the code:

TCHAR szEXEPath[2048];
char actualpath[2048];
GetModuleFileName ( NULL, szEXEPath, 2048 );
for(int j=0; szEXEPath[j]!=0; j++)
{
    actualpath[j]=szEXEPath[j];
}

From the full path of the executable file, split the string to get only the executable name using the built in function str.find_last_of()

std::string str (actualpath);
std::size_t found = str.find_last_of("/\\");
std::cout<< str.substr(found+1) << '\n';

Now you can get only the executable file name.

like image 22
Cibin William Avatar answered Nov 07 '22 13:11

Cibin William