Obtaining the calling .dll .. not process name?

c++ / delphi package - dll injection and api hooking
Post Reply
jonny_valentine
Posts: 109
Joined: Thu Dec 30, 2004 9:59 pm
Location: UK

Obtaining the calling .dll .. not process name?

Post by jonny_valentine »

Not sure if its possible, but ive learned over the years anything is possible with programming. :o

Im wondering if i can somehow get the name of the DLL that called my hooked api function. I can get the process that called it, but i want the dll inside that process that called it.

Is there also a way to block people intercepting my postmessage? Im relying on that message getting to my app, if they block it then its useless.

cheers
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: Obtaining the calling .dll .. not process name?

Post by madshi »

jonny_valentine wrote:Not sure if its possible, but ive learned over the years anything is possible with programming. :o

Im wondering if i can somehow get the name of the DLL that called my hooked api function. I can get the process that called it, but i want the dll inside that process that called it.
Just use madCodeHook.GetCallingModule... :shock:
jonny_valentine wrote:Is there also a way to block people intercepting my postmessage? Im relying on that message getting to my app, if they block it then its useless.
That depends on how they intercept your message. As you say, almost anything is possible with programming. Quite probably you can counteract every intercepting. Might be difficult, though. And first you need to know how they intercept.
jonny_valentine
Posts: 109
Joined: Thu Dec 30, 2004 9:59 pm
Location: UK

Post by jonny_valentine »

Thanks for the reply madshi..

I currently use :

Code: Select all


	// get the name of the current process
	if (!(GetVersion() & 0x80000000)) {
	  GetModuleFileNameW(NULL, arrChW, MAX_PATH);
	  WideToAnsi(arrChW, arrChA);
	} else
	  GetModuleFileNameA(NULL, arrChA, MAX_PATH); //win98
		// we only want the file name
		i2 = 0;
		for (i1 = lstrlenA(arrChA); i1 > 0; i1--)
			if (arrChA[i1] == '\\') {
			i2 = i1 + 1;
			break;
		}	


.. to give me the parent process .exe name, but i was actually wondering if its possible to get the .dll inside the parent process that made the call.

So for example, if the parent process had 4 .dlls as well as my injected one, and one of those .dll's made the call to createprocess, the above code just gives me the process name, not the .dll that called the api inside the process. Prob not possible but worth a try asking.


Off topic, how likely is it that my .dll is not injected into a certain process.. for example, can they HIDE their process from view so i cant hook it?

Regards
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

jonny_valentine wrote:i was actually wondering if its possible to get the .dll inside the parent process that made the call.
Did you actually read my comment? I'll say it again:

Just use madCodeHook.GetCallingModule...
jonny_valentine wrote:Off topic, how likely is it that my .dll is not injected into a certain process.. for example, can they HIDE their process from view so i cant hook it?
If it's a process which is already running when you call InjectLibrary, it can try to resist (possible, but hard). If it's a newly started process, it's even harder to stop your dll from being injected. Still it might be possible, but it's difficult.
jonny_valentine
Posts: 109
Joined: Thu Dec 30, 2004 9:59 pm
Location: UK

Post by jonny_valentine »

SORRY!! :oops:

I thought that getcallingmodule was to get the process name.

Thanks for the help.
jonny_valentine
Posts: 109
Joined: Thu Dec 30, 2004 9:59 pm
Location: UK

Post by jonny_valentine »

Just a quickie.. the following:

Code: Select all

	  char dta [MAX_PATH + 1];
	  char buffer [sizeof(unsigned long)*8+1];
	  lstrcatA(dta, ultoa(GetCallingModule,buffer,10));

	  fout << timeStr << " " << txtToWrite << " " << &arrChA[i2] << " " << mFilename << " " << dta << endl;
produces this error:

error C2664: 'ultoa' : cannot convert parameter 1 from 'unsigned long (__stdcall *)(void)' to 'unsigned long'

if i just do :

Code: Select all

fout << timeStr << " " << txtToWrite << " " << &arrChA[i2] << " " << mFilename << " " << GetCallingModule << endl;
it works but returns the same long number each time for GetCallingModule even if the call was made from different .dlls inside that process.

Thanks for the help.
jonny_valentine
Posts: 109
Joined: Thu Dec 30, 2004 9:59 pm
Location: UK

Post by jonny_valentine »

Ignore above.. im a newbie c++ programmer, i changed to :

Code: Select all

	  unsigned int gcm;
	  
	  gcm=GetCallingModule();

	  lstrcatA(dta, itoa(gcm,buffer,10));
Just in case anyone else has the same problem.

jon
jonny_valentine
Posts: 109
Joined: Thu Dec 30, 2004 9:59 pm
Location: UK

argh!

Post by jonny_valentine »

This is becoming annoying...

does anyone have a c++ example of GetCallingModule.. i cant for the life of me get it to work.

I just want the name of the calling module, something like:

Code: Select all

GetModuleFileNameW(GetCallingModule, buffer, MAX_PATH);
the above does not work, no matter what i try, it either crashes the computer or gives a 'cannot convert param 1 from blah to blah' error when compiling.


Any help much appreciated.
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

How if "buffer" declared? Should be someting like "w_char buffer[MAX_PATH]".
jonny_valentine
Posts: 109
Joined: Thu Dec 30, 2004 9:59 pm
Location: UK

Post by jonny_valentine »

Code: Select all

	WCHAR Buffer [MAX_PATH +1];

	// get the name of the calling .dll
	if (!(GetVersion() & 0x80000000)) {
	  GetModuleFileNameW(GetCallingModule, Buffer, MAX_PATH);
Error message is:

C:\Program Files\Microsoft Visual Studio\MyProjects\mydll\mainc.cpp(178) : error C2664: 'GetModuleFileNameW' : cannot convert parameter 1 from 'unsigned long (__stdcall *)(void)' to 'struct HINSTANCE__ *'
There is no context in which this conversion is possible

When i add brackets to GetCallingModule:

GetModuleFileNameW(GetCallingModule(), Buffer

I get this at the bottom instead:
Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast



----------------------
I may post a different topic for this problem, unless you can figure it out.. im probably the worst person on this forum for problems:

Code: Select all


	HWND pOtherWnd = FindWindow(NULL, "Target");

	if (pOtherWnd)
	{


		char dta [MAX_PATH + 1];
	
		lstrcatA(dta, txtToWrite);
		lstrcatA(dta, " ");
		lstrcatA(dta, mFilename);

		COPYDATASTRUCT cds;

		cds.dwData = 3;
		cds.lpData = (void*) dta;
		cds.cbData = strlen((char*)cds.lpData);

		copyDataResult = SendMessage(pOtherWnd,WM_COPYDATA,NULL,(LPARAM)&cds);

The above does not work but if i replace the cds.lpData = (void*) dta; with cds.lpData = "Message"; it sends it ok.
The .dll also takes about 7 seconds to inject.

I know i shouldnt use sendmessage for IPC, but its to communicate to a VB app, and its too hard to make your IPC thingy work. Its easy to subclass the window and receive messages. Just cant figure out how to pass a variable string instead of a static string.

Thanks again.

Btw. Im buying the full version of madcode hook, coz its gr8, and when ive managed to fully integrate it to VB, i'll gladly write some demo apps for ppl wanting to you it in vb.
[/code]
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

jonny_valentine wrote:GetModuleFileNameW(GetCallingModule(), Buffer
Probably you need to use "&Buffer". Not sure, though, cause I'm a Delphi programmer, not a C++ programmer.
jonny_valentine wrote:cds.lpData = (void*) dta;
Probably that should be "&dta". Again, I'm no C++ programmer. For C++ questions you should probably ask on a C++ programming forum.
dcsoft
Posts: 380
Joined: Sat Dec 11, 2004 2:11 am
Location: San Francisco Bay Area, CA USA
Contact:

Post by dcsoft »

Here's a code snippet that illustrates GetCallingModule() from a C++ program:

Code: Select all

TCHAR szCallingModulePath[MAX_PATH];
HMODULE hCallingModule = (HMODULE) GetCallingModule();
GetModuleFileName ( hCallingModule, szCallingModulePath, sizeof(szCallingModulePath) );

// szCallingModulePath now contains the full path of the DLL that called your intercepted API function
Part of the confusion is that GetCallingModule() is prototyped to return a DWORD, not an HMODULE... madshi, you may want to change this to at least return a HANDLE of some sort and not a DWORD. It's easy to confuse DWORD id's from handles.

Regarding your other code snippet, the correct code is:

Code: Select all

   HWND pOtherWnd = FindWindow(NULL, "Target"); 

   if (pOtherWnd) 
   { 
      char dta [MAX_PATH + 1]; 
    
      lstrcpyA(dta, txtToWrite);   // <-- NOT lstrcatA!
      lstrcatA(dta, " "); 
      lstrcatA(dta, mFilename); 

      COPYDATASTRUCT cds; 

      cds.dwData = 3; 
      cds.lpData = (void*) dta; 
      cds.cbData = strlen((char*)cds.lpData); 

      copyDataResult = SendMessage(pOtherWnd,WM_COPYDATA,NULL,(LPARAM)&cds); 
-- David
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Good to have a C++ expert on board!

In Delphi HANDLE, DWORD and HMODULE are all the same. I'll change GetCallingModule() so that it returns HMODULE.
jonny_valentine
Posts: 109
Joined: Thu Dec 30, 2004 9:59 pm
Location: UK

Post by jonny_valentine »

Thanks David n mads... i'll give that a go.

much appreciated.

jon
Post Reply