Injecting a DLL prior to process execution
Why inject a DLL?
Dll Injection is a well known technique and is most often used to perform some kind of API hooking. As soon as the dll has been injected into a remote process, hooking APIs or patching existing functionality is easy because everything happens inside one address space.
Apart from hooking APIs to change existing program logic, there are several other reasons why one would want to inject a dll into another process, especially in the field of Reverse Engineering.
Once injected one could
- perform complex IAT rebuilding by injecting code into a process
- allocate a console and printout parameters gained from hooking interesting API functions
- disable anti-debugging techniques used by the process by hooking some APIs and/or patching known memory locations
- implement a fast in-process debugger/tracer by catching exceptions via vectored exception handling
- ...
or just to execute any kind of code inside another process to do some fancy things.
After a process has been created, the process of injecting a dll is pretty straight forward - write some shellcode to the memory of the remote process and create a remote thread at that location to carry out the actual dll loading.
Depending on the goal which needs to be achieved, it can be a requirement to inject the respective dll as early as possible in the stage of process creation. Especially in the case where a dll would perform some countermeasures against anti-debugging techniques, it is crucial that control flow reaches the injected dll before any code of the process itself gets executed.
Early injection
The idea to force a process to load a dll before anything else is quite simple: create the process in suspended state and add another entry in the import descriptor table which references the dll to be injected. We can then resume the main thread, which has the effect that all dlls are loaded and finally control flow is dispatched to the applications entry point.
Here is how it works:
- create the process in suspended state, i.e. the main thread is suspended before any code in the process has been executed and before any dll has been loaded.
- Find the IMAGE_IMPORT_DESCRIPTOR table of the module and copy the existing table to a new location
- Add a new IMAGE_IMPORT_DESCRIPTOR structure for every dll to be injected into the new table.
- Fill OriginalFirstThunk as well as FirstThunk and the dll name field of the IMAGE_IMPORT_DESCRIPTOR structure
- Finally, fix the RVA in the IMAGE_DATA_DIRECTORY to point to the new table and let the process continue execution

PE header with import table
Source code
C++ classes to perform injection prior to process creation as well as after the process has been started can be downloaded from the project site.
Besides, an IDA plugin - IDA Inject - implementing these techniques is available (requires IDA 5.x) and can be downloaded from this page.
what if no space is available
what if no space is available in the section in which IMAGE_IMPORT_DESCRIPTOR resides.
I mean if it is on the page boundary or if there are very less bytes available to insert a new entry.
Please correct me if I am saying something wrong or getting something incorrectly.
Cheers
Deepak
What about bound imports
I have already tried this technique by inserting my dll entry in "calc.exe".
But didn't work for it.
After few days it came to me that it is becoz of the bound imports.
I think it will be a problem with N-InjectLib too.
Cheers
Deepak
What about bound imports
Bounded imports are handled since 1.0.2
A quick test with calc.exe worked for me. If you think you found a bug, could you send me some source to reproduce this? I'll look into it then
Cheers
Jan
cool... So what do you do
cool...
So what do you do handle the bound imports?
Do you alter the timestamp or checksums to force the loader to follow the normal way of resolving the imports?
Cheers
Deepak
What about bound imports
The bound directory is simply cleared and everything is rebuild. You might want to have a look at the source code - everything is commented pretty good i think :)
what if no space is available
The library will create a new IID by copying the old one and change the PE header appropriately.
ok good. Got your idea. One
ok good.
Got your idea.
One more question--
Is reading/writing to another process's memory is barred in vista? (I don't think it should be)
or does it require some more authentication?
Cheers
Deepak
ok good. Got your idea. One
If you have the appropriate rights, there is nothing which prevents you from writing to a foreign process address space under vista just in the way you would do under XP. I guess UAC won't raise any additional trouble here.
hello
Its realy good,very helper thanks.