article

DLL Injection and API Hooking

Email
Submitted on: 1/6/2015 5:28:00 AM
By: Daniel Cavalcanti (from psc cd)  
Level: Advanced
User Rating: By 2 Users
Compatibility: C, C++ (general), Microsoft Visual C++
Views: 4092
 
     DLL injection and API hooking. Portable executable and IAT table also explained, insert code of yours onto other process.

This article has accompanying files
 
				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 ^^

winzip iconDownload 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


Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this article (in the Advanced category)?
(The article with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments


 There are no comments on this submission.
 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular article, please click here instead.)
 

To post feedback, first please login.