InjectLibrary - C++

c++ / delphi package - dll injection and api hooking
Post Reply
RollnThndr
Posts: 8
Joined: Thu Mar 03, 2005 12:52 am

InjectLibrary - C++

Post by RollnThndr »

If I use madCHooks CreateProcessEx to start my form and DLL, the DLL operates fine. If I open form on it's own and try to inject the dll, it doesn't load the DLL.

I've tried putting the DLL in both the starter apps folder as well as the System32 folder (WinXP). The dWord variable is something I statically changed when I was testing this. I would open the form, get it's ProcessID, and hardcode it to make sure I was getting the right ID, and try to inject that specific form. I notice the madCHook documentation it's looking for a ProcessHandle, is this different than a ProcessID?

For the below example, the ProcessID for the Form1 window (using MS SPY++) is 00000A98.

Anyways, here's my starter app using InjectLibrary:

Code: Select all

// Injection.cpp : Defines the entry point for the console application.

#include "stdafx.h"
#include "windows.h"
#include "madCHook.h"

int _tmain(int argc, _TCHAR* argv[])
{
	InitializeMadCHook();

	DWORD dWord = (DWORD)0x00000A98;
	InjectLibrary(dWord,(LPCWSTR)"NSR_SM.dll");

	FinalizeMadCHook();
	return 0;
}
Below is the starter app that uses CreateProcessEx. It works fine.

Code: Select all

// NSR_Shell.cpp : Defines the entry point for the console application.

#include "stdafx.h"
#include "windows.h"
#include "madCHook.h"

int _tmain(int argc, _TCHAR* argv[])
{
	STARTUPINFO si;
    PROCESS_INFORMATION pi;

	ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );

	InitializeMadCHook();

	CreateProcessEx("NSR_Form.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi, "NSR_SM.dll");

	FinalizeMadCHook();
	return 0;
}
The DLL I'm injecting is nothing special. It's just watching the MESSAGES in it's own process and catching LB_ADDSTRING on a ListBox. I can provide the DLL code is needed.

-Rolln
RollnThndr
Posts: 8
Joined: Thu Mar 03, 2005 12:52 am

Post by RollnThndr »

Ok I understand now that a processID is definately different than a processHandle.

So now I use:

Code: Select all

HANDLE ph;
ph = OpenProcess(PROCESS_ALL_ACCESS, false, 0x00000A98);
but InjectLibrary needs a DWORD, so this blows up

Code: Select all

InjectLibrary(ph,"NSR_SM.dll");
If I CAST it as a DWORD it says I'm truncating which is probably why I still can't get it to work.

Code: Select all

InjectLibrary((DWORD)ph,"NSR_SM.dll");
This is where I loose my patients :sorry: using c++. I'm definately not up to speed in the different types and coverting/casting them back and forth.

Any ideas?

-Rolln
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

RollnThndr wrote:

Code: Select all

InjectLibrary((DWORD)ph,"NSR_SM.dll");
This one is basically correct.

However, you must make sure that the other process will find both your hook dll and madCodeHook.dll. So you need to copy madCodeHook.dll to the system32 folder. You can leave your hook dll in your private folder, but when calling InjectLibrary give in the full path to your hook dll.
RollnThndr
Posts: 8
Joined: Thu Mar 03, 2005 12:52 am

Post by RollnThndr »

Ok, that's what I thought as well, they are both 32-bit unsigned ints... go figure. I added the full path to DLL and it is now getting loaded at least.

The DLL isn't working properly when injected, it's getting loaded now, but it doesn't work like it does when its starting up using CreateProcessEx.

Thanks for you help... I'm off to go figure out what I've done wrong my little DLL..
RollnThndr
Posts: 8
Joined: Thu Mar 03, 2005 12:52 am

Post by RollnThndr »

I think I'm misunderstanding some fundemental ideas here. Like I said previously, my DLL works fine if my app is started using CreateProcessEx but if I try to inject it, it 'attached' to the apps process but doesn't do anything.

What am I miss understanding? I just want to hook the form and capture the LB_ADDSTRING message of my listbox. Again, this works properly if I use my above listed starter app with the DLL

DLL Code:

Code: Select all

// NSR_SM.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "windows.h"
#include <stdlib.h>
#include "NSR_SM.h"

HHOOK hH;

LRESULT CALLBACK CallWndRetProc(int hCode,WPARAM ww,LPARAM ll)
{
	if (hCode < 0)
		return CallNextHookEx(hH,hCode,ww,ll);
	else
    {
        LPCWPRETSTRUCT msg = (LPCWPRETSTRUCT)ll;
		if(msg->message == LB_ADDSTRING)
			SendMessage(msg->hwnd,LB_ADDSTRING,0,(LPARAM)"Input from DLL");
        return CallNextHookEx(hH,hCode,ww,ll);
      }
}

BOOL WINAPI DllMain( HANDLE hModule, 
                       DWORD reason, 
                       LPVOID lpReserved)
{
	if (reason == DLL_PROCESS_ATTACH)
	{
		hH = SetWindowsHookEx(WH_CALLWNDPROCRET,CallWndRetProc,NULL,GetCurrentThreadId());
		MessageBox(0,"Init", "Debug", 0);
	}
	else if (reason == DLL_PROCESS_DETACH)
	{
		UnhookWindowsHookEx(hH);
		MessageBox(0,"Detached", "Debug", 0);
	}	
    return TRUE;
}
I realize the DLL isn't a madCHook issue, but I have been trying to solve this for days without any luck. Just hoping that someone around here may be able to help. As I mentioned, I'm probably not understanding how to properly use SetWindowsHookEx. I only want to hook my form for messages and nothing else.

Thanks for any input.
RollnThndr
Posts: 8
Joined: Thu Mar 03, 2005 12:52 am

Post by RollnThndr »

It looks like I'm not getting the correct ThreadID (of my app) when this is called from the injected DLL

Code: Select all

hH = SetWindowsHookEx(WH_CALLWNDPROCRET,CallWndRetProc,NULL,GetCurrentThreadId()); 
dcsoft
Posts: 380
Joined: Sat Dec 11, 2004 2:11 am
Location: San Francisco Bay Area, CA USA
Contact:

Post by dcsoft »

RollnThndr wrote:It looks like I'm not getting the correct ThreadID (of my app) when this is called from the injected DLL

Code: Select all

hH = SetWindowsHookEx(WH_CALLWNDPROCRET,CallWndRetProc,NULL,GetCurrentThreadId()); 
Perhaps you shouldn't be calling SetWindowsHookEx() in DllMain. Why don't you export another function in your hook dll (i.e. call it SetHook) and call it right after you call the madCodeHook API InjectLibrary() ?

-- David
RollnThndr
Posts: 8
Joined: Thu Mar 03, 2005 12:52 am

Post by RollnThndr »

dcsoft wrote: call it right after you call the madCodeHook API InjectLibrary() ?
First off, thanks for the reply.

That is something I haven't tried and sounds like it may be the answer. Other than using LoadLibrary, GetProcAddress, etc., I'm not sure how I would call this new SetHook function. I mean, I wouldn't want to load the library again, that defeats the purspose obviously. I hate to ask, but could you outline how I would go about it?

Sorry for the newbie questions, you guys must get sick of us at times... :oops:
RollnThndr
Posts: 8
Joined: Thu Mar 03, 2005 12:52 am

Post by RollnThndr »

Maybe I have been misunderstood. I have 3 seperate things...

1)started app
2)a dll
3)another application

Eventually item #3 will be a program that I haven't written, I'm obviusly using my own for testing purposes
call it right after you call the madCodeHook API InjectLibrary() ?
What you have suggested to me it to call a function in #2 (the dll) from #1 (the started app) after #1 has called InjectLibrary. How do I call this function as though #3 (the main app) has called it. The function only has anything to do with #3 and will not work if I use something like LoadLibrary from #1.

I'm about ready to just walk away from all this, it getting frusterating as hell. All I want to do is spy on a listbox of another freaking progam, is it really this hard?

It can't be if I can launch the application using CreateProcessEx and it works fine...

Maybe the question I should be asking is:
Can someone outline (no need for details) the way I should go about spying on the listbox of another application?

The reason I have been using InjectLibrary is because in the end, I will have to monitor for new instances of app #3 and "inject" the listbox spy as these new instances startup. I just assumed that I would only want to use SetWindowsHookEx in a DLL and hook the 'process' that it is injected into. Should I be going about this a totally different way?

-Rolln
dcsoft
Posts: 380
Joined: Sat Dec 11, 2004 2:11 am
Location: San Francisco Bay Area, CA USA
Contact:

Post by dcsoft »

You're right that you need to call SetWindowsHookEx() in the context of the injected app (App #3). My suggestion to call an exported function in the .dll from your App #1 wouldn't work, because that would execute in the context of App #1, not App #3.

So how do you trigger the execution of code in the .dll in the context of App #3? Well, I haven't thought of any easy ways to do that. It seems DllMain is your one shot of executing your init code in the context of App #3.

The problem with SetWindowsHookEx() might be that GetCurrentThreadId() doesn't return something valid in DllMain. I'm not sure which thread of App #3 DllMain() is executed in. All threads of App #3 are supposedly suspended when DllMain() executes.

Anyway, now that you have explained you want to spy on a listbox, it's easy. Just subclass the listbox in DllMain. You can find more about subclassing on MSDN. Basically, subclassing replaces a window's window procedure with your function, so you can intercept all the messages going to the window (the window in your case is the listbox). It gives you the same as the WH_CALLWNDPROC hook, but it's simpler and I know it will work (as I have a project that does subclass a window in DllMain).

Hope this helps,
David
RollnThndr
Posts: 8
Joined: Thu Mar 03, 2005 12:52 am

Post by RollnThndr »

Thanks David!

Subclassing seems to be working. Granted I just tried a very small test, but now I can inject the DLL into another process, get the listbox handle and subclass it's events. This is what I was looking to do, or at least I hope I'm going about it the right way, seems to work.

I can usually fumble through this stuff so you pointing me in the right direction is great.

Thanks!

PS
Madshi, love these tools!
Post Reply