|
DLL Injection and API Hooking |
| | | | Submitted on: 1/26/2004 8:17:06 PM
By: Daniel Cavalcanti
Level: Advanced User Rating: Unrated Compatibility:C, C++ (general), Microsoft Visual C++
Users have accessed this article 1182 times. | (About the author) |
| | DLL injection and API hooking. Portable executable and IAT table also explained, insert code of yours onto other process. This article has accompanying files | | | Terms of Agreement:
By using this article, you agree to the following terms...
1) You may use
this article in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
2) You MAY NOT redistribute this article (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.
3) You may link to this article from another website, but ONLY if it is not wrapped in a frame.
4) You will abide by any additional copyright restrictions which the author may have placed in the article or article's description. | Used APIs in the source code: MessageBox, GetThreadContext, SetThreadContext, Listview stuff, OpenProcess, OpenThread, WriteProcessMemory, Createtoolhelp32Snapshot for process and threads.
------------------DLL INJECTION------------------
DLL injection stands by loading a DLL (module) into a process memory space, this will give you control over the process functions (you can redirect or use them), APIs (hook them/redirect), memory and anything else you want, even faster memory handling so you won`t have to use ReadProcessMemory.
Methods:
1 - Use CreateProcess with the CREATE_SUSPENDED flag to run a program, this will give the handle of a thread and of the process, then GetThreadContext and patch it using WriteProcessMemory with an array of opcodes (asm hex) for LoadLibrary("yourdll.dll"), SetThreadContext with the new EIP (current offset the processor is reading)
2 - Make use of Windows hacks such as ExtOpenThread9x (you can find it in the net)
3 - Use CreateRemoteThread (there`s a source code here in PSC that deals with it and it`s quite good so I won`t bother explaining it)
4 - Do as I did, which I didn`t find anywhere so I came up with it (source code down there)
Method 1 only works if you create the process (or ordinarily speaking: run the program). Method 2 is way to complicated for some people but very useful and smart (I wonder who created it). Method 3 does not work with all versions of Windows.
Now some info for you:
A process is a program running in an OS (Operational System). A thread is the current part of code in a process that the processor is dealing with, a process can have several threads thus execute several tasks at a time, the processor just keeps switching from thread to thread (MultiThread) to avoid getting stuck (imagine a while(true) loop). Just going a bit further here, there is no such thing as true MultiThread because that requires two processors, what "some" processors do and is called of multithread is simply switch tasks as if there were 2 processors, but still a processor can only run one opcode at a time.
Now that those things are explained, going on.
There are two ways to get a process threads:
1 - Doing some stuff (I won`t explain it here). You can find more about it in a german article written by Yoda.
http://scifi.pages.at/yoda9k/Articles/ForceLibrary.htm
2 - Use Craetetoolhelp32Snapshot to get all current threads on the system. Compare all of their PIDs (process id) to the process you wanna inject a dll into. After getting all threads of a process, check it`s EIP to make sure it is not bellow 0x400000 because that will crash the program or make the thread be closed since there is nothing useful there of code.
I chose the second method because I wanted to do something that would work in all versions of Windows and that it wouldn`t require if(operationalsys == blah) do this...
It took me a couple of days till I remembered that Createtoolhelp32Snapshot got the threads on the system (actually most people don`t remember it) but when I did things came out easy.
After you have teh PID and an useful thread (EIP > 0x400000) things will get easy.
SuspendThread is necessary before finding a good thread and doing all the stuff in the process code space, or else when you reset the EIP later (and you saved the thread`s data before) the program will crash or get some bad data loss because after all you placed old registers above new ones and the program wanted new ones but most times there`s just data loss, no crash.
Then you get the thread`s registers by GetThreadContext (with the thread in suspended state). Build an array with some as code that has mainly:
PUSHFD and PUSHAD: thy shalt always save the stack!
LoadLibrary("yourlib.dll"): the process will load the library as if it was done by itself. If you want something to be executed when loaded (well, you do if you won`t use GetProcAddress) then you have to put the code in DLL_PROCESSS_ATTACH in DllMain
GetProcAddress(GetModuleHandle("yourlib.dll"), "yourfunc") and a JMP to it: this is useful only if you want the process to execute some particular code before resuming it`s normal actions.
POPFD and POPAD: old stack back on
JMP oldEIP: goes back to where it was
and that does it, if you did it right you just injected your dll in a process, if you don`t call a function in your dll the only way it will do something is if you place it in the DLL_PROCESS_ATTACH in DllMain.
I believe this works in all versions of Windows, at least it did in WinXP Pro (heh) but that`s why it`s here.
---------------------API HOOK---------------------
There are two pratical ways to do API hooking
1 - Hook the API at the IAT: GetModuleHandle(NULL) gives you the PE (Portable Executable) header start for it, if you wish to hook one of the DLL`s the process owns instead of hooking the process use GetModuleHandle("dllforhook.dll")
2 - Find the API`s address in the DLL used for it and change the first bytes to JMP MyFunction/RETN, it looks like: {0xe9, 0x00, 0x00, 0x00, 0x00, 0xc3}. Save the bytes there if you plan on re-using it later, you can drop them to an array first of your ownand use it there like if it was a function of yours (hard to do but recomended if it`s a big function or if the process owns way more than one thread that uses the function). Or just save the bytes, and keep restoring and hooking them (like I did in the example) easier if it`s a singlethread process.
In case you do save the function to an array and wanna use it later, you`ll need pointers to use it and change all calls and jmps inside of it to match the jump offset (the processor reads the 4 bytes after the JMP opcode in a manner that is ((to)-(from)-5). This goes for CALL and JMP (all types).
The first metho is valid for one or a few modules (a process and one of it`s DLLs in example). The second goes for general hooking in a process so the process and all of it`s DLLs share the exact same code in an easy way. Very useful for "All Process" hooks.
For learning more on IAT and PE (portable-executable) there`s a .pdf in the .zip cause that would take like another article here.
The IAT hook gets the import address table (ah, IAT means that), goes through the "DLLs to be loaded" section of a module, then finds the function`s name there and changes the address AND/OR ordinal values and changes the address there.
vote for this article if you liked it, learned anything and got useful stuff from it.
Download the .zip for the codes, use it and redistribute it however you like, any doubts email me or leave a message here.
cya ^^ | | Download article
Note: Due to the size or complexity of this submission, the author has submitted it as a .zip file to shorten your download time. Afterdownloading it, you will need a program like Winzip to decompress it.
Virus note:All files are scanned once-a-day by Planet Source Code for viruses,but new viruses come out every day, so no prevention program can catch 100% of them.
FOR YOUR OWN SAFETY, PLEASE: 1)Re-scan downloaded files using your personal virus checker before using it. 2)NEVER, EVER run compiled files (.exe's, .ocx's, .dll's etc.)--only run source code.
If you don't have a virus scanner, you can get one at many places on the net including:McAfee.com
| Terms of Agreement:
By using this article, you agree to the following terms...
1) You may use
this article in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
2) You MAY NOT redistribute this article (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.
3) You may link to this article from another website, but ONLY if it is not wrapped in a frame.
4) You will abide by any additional copyright restrictions which the author may have placed in the article or article's description. | Other 1 submission(s) by this author
| | | Report Bad Submission | | | Your Vote! |
See Voting Log | | Other User Comments | 1/27/2004 11:43:40 PM:Daniel Cavalcanti
Also you might wanna do a SendMessage
with WM_MOUSE message (or pass the
mouse over the screen of the program
you hooked) because usually it`s the
window message handler thread that is
caught
| | Add Your Feedback! | Note:Not only will your feedback be posted, but an email will be sent to the code's author in your name.
NOTICE: The author of this article has been kind enough to share it with you. If you have a criticism, please state it politely or it will be deleted.
For feedback not related to this particular article, please click here. | | |