Link to home
Start Free TrialLog in
Avatar of Babyworship
Babyworship

asked on

how to inject .dll into another process?

hi

how to inject a .dll into another process?
I want to use setwindowshookex() but i dont know what kind of hook i should creat,mouse ,key or what?
Are there better way?
thanx.




















Avatar of jeremyd
jeremyd

What are you trying to accomplish with this hook?
Check the MSDN help for SetWindowsHookEx. You can install a system wide hook without using a DLL at all by passing hMod a NULL and specifying 0 for the ThreadID.
Babyworship, to your comment:

There are many ways to inject dlls.
It depends on what's the app you want to hook on (GUI,console,has message queue or not, etc), what do you want to do with a hook, what OS you use (95/Nt/2000).
It will take too much to write the 'generic' answer for 50 points only.
Avatar of Babyworship

ASKER

I want to hook the the call of setwindowpos() of a process.
I want to hook the the call of setwindowpos() of a process.
I'm on win98
if i use setwindowshookex().I dont know what kind of hook i should use.
thanks all.
If program calls SetWindowPos, then, most likely, it has the message loop.

Use WH_GETMESSAGE hook.

After installing, post any message to the window belonging to the thread on which hook is installed to force your dll to load immediately, for example:


SetWindowsHookEx(...,WH_GETMESSAGE,threadId )
PostMessage(hWin,WM_GETWINDOWTEXTLENGTH,0,0)
Usually I make the following:

a)Install hook
b)Once hook dll loaded, in creates a working thread which performs all necessary job.
c) This thread calls LoadLibrary(hookDll) to increment the hook dll usage count.
d) Thread uninstalls useless (now) hook by UnhookWindowsEx. Hook dll remains in the address space because of step c)
How can I find the threadID of the process I want to inject?
That depends on what you now about that process. If you have the window handle call GetWindowThreadProcessID. If you only have the executable file name, then it's getting a bit more complicated.
Adjusted points to 100
It sounds very tough !
Madshi,i vaguely remember that you once answered a question like this with jkr,right? Can YOu help me?

I 'm a newbie to some degree on programming and
I think
I need a sample code!!
(only the part to inject a dll to a process ).

btw,i still dont know how to use a hook to do this.what i do in my hook callback function? I just want to intercept the an api from user32 call of that process,not message!Where should I place the code which used to change the process's code ?In dllmain()?

hook is the only way?
Can I use CreateRemoteThread()?

I increase the points for a good way to inject a .dll to a process.
my email
babyworship@163.net
Thanks
Sorry, but before asking so many questions you should explain first what are you going to do with the intercepted API function.

CreateRemoteThread doesn't work on Win95/98.

Here is the code to install the WH_GETMESSAGE hook.

//----------
// Main.cpp
// Main program which installs hook.
//----------

//cl %1 %2 %3 %4 /LD hook.cpp user32.lib
//cl main.cpp hook.lib user32.lib

#include <windows.h>
#include <iostream.h>
#include <conio.h>

bool setHook(DWORD threadId);
void removeHook();

void main(int argc,char* argv[])
{
   // Find any window of the app you want to attach to.
   // For example, find window by the class name or window name.
   HWND hWnd=FindWindow(0,"Window name");

   // Find thread id of hWnd.
   DWORD threadId=GetWindowThreadProcessId(hWnd,0);

   if(setHook(threadId)) {
      cout<<"Press Enter to quit"<<endl;
      _getch();
   }  
   removeHook();
}


//----------
// Hook.cpp
// Hook dll. Build this as DLL.
//----------
#include <windows.h>

#pragma data_seg(".shared")
HHOOK hHook=0;
#pragma data_seg()
#pragma comment(linker,"/SECTION:.shared,RWS")

HINSTANCE hDll;

LRESULT CALLBACK hookProc(int code,WPARAM wParam,LPARAM lParam)
{
   // Do nothing .
   return CallNextHookEx(hHook,code,wParam,lParam);
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID)
{
   if(fdwReason==DLL_PROCESS_ATTACH) {
      hDll=hinstDLL;
      if(hHook!=0) {
         // You are in the foreign process.
         // Do whatever you want.
         // Modify process here.
      }
   }
   return TRUE;
}

_declspec(dllexport) bool setHook(DWORD threadId)
{
   if(hHook==0)
      hHook=SetWindowsHookEx(WH_GETMESSAGE,hookProc,hDll,threadId);
   return hHook!=0;
}

_declspec(dllexport) bool removeHook()
{
   if(hHook) UnhookWindowsHookEx(hHook);
}
Hi Babyworship, well, I could only give you Delphi sources, so Nick is the right man for you...   :-)

Hmmm... Intercepting APIs? Well, I had a link for something good, but I don't find it in the moment. I'll come back later.
Nick, do you have a link to Oleg Kagan's Syringe dll homepage?
http://www.geocities.com/SiliconValley/1741/

But syringe is much more complex that windows hook.
Madshi, it may be interesting for you.

http://www.geocities.com/SiliconValley/1741/geobook.html
Read the comment from Reed Mangino - 10/21/99 01:47:56
how can I get the hmodule of the process I inject?
My code above doesn't use hmodule of the foreign process.

Or is it a new question not related to my code above?
Yes, Nick, you're right. Syringe is much more complex, but since Babyworship talked about CreateRemoteThread and intercepting APIs I thought, it would be at least something to look at. If the SetWindowsHookEx method works okay for Babyworship's needs, it's surely the way to go.

Hmmm... The comment from Reed Mangino is really interesting. But the problem he describes should only occur, if you use CreateRemoteThread on a newly started (with CREATE_SUSPENDED) process, right? If you use it on an already running process, there should be no problem, is that right?
Adjusted points to 170
I need the hmodule to find the starting address of the process .exe.Right?
You are so serious about new question or not,but this is a question regarding this question.I raise 70 points and I need know 3 simple answers all related to this question:

1:how to get the starting addres of the .exe file.i.e the hmodule.
2:how to get the thread handle from threadID,i need them.
3:do i need to suspend the process i inject?why?
Babyworship, I think you should tell us exactly what you want to do. Otherwise we can not really recommend which method you should use.
For which purpose do you need the hmodule of the process? And you didn't answer my question yet: What do you know about this process? The processID? A window handle? The filename?
>>The comment from Reed Mangino
Madshi,would you please give me some useful infomation on this?
if you need email,mine is babyworship@163.net.
>>For which purpose do you need the hmodule of the process?
I think the hmodule of the proces is the starting address of the .exe in the memory.I need it to find the import table to intercept api.
and I need thread handle to suspend the process  during change .exe.I 'm sure if it's necessary,would you comment?

I know the window name.i can use findwindow.
Call GetModuleHandle(NULL) to get the hModule handle of the current process.

I don't think that you need to suspend the process while you're digging in the import tables.

If you really want to go this way and mess up with the import tables, then you should really look at the Syringe stuff (see the link in Nick's comment above). It's all in there.
>>If you really want to go this way and mess up with the import tables

Oh? dear Madshi,are there some better ways than import table?

styring stuff i have a look but strang why the code create the process as suspend ? and after change the code and then resume it ,why?
Well, if you change the import tables, it's the best way to do that BEFORE anything happens. Otherwise you'll loose some API calls. That's why the process is created as suspended. And the second reason is simply security. You asked how to suspend the threads, do you remember? When you create the process as suspended, you don't have this problem/question.

>> Oh? dear Madshi,are there some better ways than import table?

You didn't say yet why you can't use Nick's suggestion/code. If it fits your needs, it's surely better/easier/shorter/safer than patching import tables.
>>you'll loose some API calls
what does this mean?
You mean lose?

>>You didn't say yet why you can't use Nick's suggestion/code.

What is Nick's suggestion?
He just tells me use hook to inject the .dll .but how to intercept apis are another question.That's the reason I raise thepoints.


>> If it fits your needs, it's surely better/easier/shorter/safer than patching import tables.
What is better /easier/shorter?I don't
understand you.
Thank for you help,

Babyworship, sorry, but I cannot help you more.
Hi,Babyworship.
I can help you more...
In your case
You should not suspend it because you use window hook to inject the .dll.
So, if you suspend it then even the code in DllMain() will not be called.

>>Oh? dear Madshi,are there some better ways than import table.
It's best to only intercept a few APIs.

>>you'll loose some API calls
>>what does this mean?
>>You mean lose?

Yes,you will lose some like CreateWindow() and so on.
If you want to intercept APIs like CreateWindow(),you will fail if you dont suspend it because you use FindWindow to get the ThreadId but before that,CreateWindow has already be called.You'v got to createProcess and suspend it.
Regards
Wyn
Is this your want?
>> You mean lose?

Yes, of course. Sorry, but English is not my natural language...   :-)

Let's say you start the process without CREATE_SUSPENDED, then afterwards you inject your dll in that process and patch the import tables. Between starting the process and patching the import tables there is a significant time delay. In this time delay the programming is already running and perhaps calling SetWindowPos several times. You would miss these calls in this situation. You don't have this problem if you create the process with CREATE_SUSPENDED.

>> What is Nick's suggestion?
>> He just tells me use hook to inject the .dll .but how to intercept apis are another question.That's the reason I raise thepoints.

Well, if you "only" want to catch the SetWindowPos calls, why don't you just handle the message WM_WINDOWPOSCHANGING? You can do almost *everything* with this message. Wouldn't that be good enough? Then you don't need to intercept any APIs. You could just call SetWindowsHookEx and you would be ready.

>> What is better /easier/shorter?

Writing in the import tables is always a bit dangerous (e.g. if the program stores the address of an API in another global variable, then you undo the import table and unload your dll, then the process uses this global variable to call the function, it would try to jump to your unloaded dll -> crash). Using SetWindowsHookEx is much less dangerous.
SetWindowsHookEx is easier to understand and to use and the source code is smaller/shorter. Look at how complex/complicated Syringe is. Then look at Nick's easy sources. Do you see what I mean?

But that's really not good enough for you, I have even another link for intercepting APIs:

http://research.microsoft.com/sn/detours/

Regards, Madshi.
>>then you undo the import table and unload your dll

Madshi,How can you unload a .dll?
FreeLibrary...   :-)

Look at Syringe. It's all in there...
>>Using SetWindowsHookEx is much less dangerous.
I use it for inject the dll and change the table.
Do you mean using it to intercept message is less dangerous?


Madshi,please check the answer button.You help me alot and give me alot info,.

Thank you ,Wyn,for you help the same.
so,does UnhookWindowsHookEx(hHook) call the freelibrary?
ASKER CERTIFIED SOLUTION
Avatar of Madshi
Madshi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Okay,thanx and my final question:

under win95/98
Are there other ways to inject .dll into other processes ?
Under win9x we have no CreateRemoteThread, so you have 2 options:

(1) SetWindowsHookEx
(2) wild hacks (e.g. overwriting the wndProc of a window that belongs to the other process with your own code by calling WriteProcessMemory or hijacking a thread of the other process by calling GetThreadContext/SetThreadContext)

The wild hacks don't always work. But SetWindowsHookEx doesn't work always, either. It doesn't e.g. work for non-GUI applications.

The GetThreadContext/SetThreadContext method is used in Syringe. (BTW, this part of Syringe is a co-delevopment of the Syringe author and me).