Dll Injection Methods?

Posts 1–15 of 27 · Page 1 of 2
Dll Injection Methods?
What are the most common or most effective dll or code injection methods for Windows systems? Can someone explain to me the very basics of it? This is one thing I don't quite understand. Do you create a remote thread and make it call LoadLibrary, or what? I'm just now getting into writing trainers and such, and I'd like for someone to explain this. -.-' I have googled it, but couldn't quite find a good article on it. Besides, you guys are better than random shitty articles written by elitist pricks.

Edit: Did a little more reading. So far all I understand is this: Method 1. Allocate memory for the string containing the name of the dll to be loaded in the remote process(VirtualAllocEx), write the string to that memory(WriteProcessMemory), Create a thread in the target process(CreateRemoteThread), load the dll into the remote process by calling LoadLibrary on the new thread, LoadLibrary calls the DllMain function in the injected dll.
And method 2. Allocate memory for code and data in the target process, write a function and whatever data it needs, if it needs any(only allowed a page of data for local variables on a remote thread? not sure.), Create a remote thread and pass it the address of the function you wrote to the target process's memory.
Is that generally how it works, are there other ways, and if games or programs have ways of preventing these methods from working, what other methods do you use or how do you get around the prevention?
There are a bunch of different ways of doing this, as you've noted the most common way is via LoadLibrary. Essentially all you do is write the Dll's path to the remote process's memory, so that you can pass the pointer as a parameter and it will be valid in the remote process, then just create a thread within the remote process using CreateRemoteThread at the address of LoadLibraryA, and pass the pointer to the Dll path c-string as the single param that CreateRemoteThread allows. Simple as a pimple. I wrote a more in depth tutorial on this method which is stickied in the VB section and has code examples.

Point to note: some processes don't like you using CreateRemoteThread, but there is an alternate (albeit less elegant) function you can call with similar parameters and effects: QueueUserAPC, there's a few downsides with this method though, so use only when CreateRemoteThread is detected.

Another method is using Windows Hooks, I'm not so familiar with this method but I know there's a good codeproject article on it here.

Yet another method is to modify the registry to make every process that loads user32.dll load your dll as well. See here
As that wikipedia page lists, you can also hijack threads, again I'm not all that familiar with this method.

A more extreme way of doing it is via manual mapping, this shit is a mindfuck and a half. Darawk has some available public code to achieve this in C++ here. It is more in depth and gets right down the PE layer. Basically manual mapping mirrors the functionality of LoadLibraryA in that it prepares a dll so that it can be successfully loaded into the process and have the right relative offsets etc, thus eliminating the need to call LoadLibraryA which is VERY easy for the remote process to hook and detect seeing as it's called within the remote process.

Another great read is here:
DLL Injection and function interception tutorial - CodeProject®

Enjoy.
The QueueUserAPC() won't always work, it works only if the target uses thread and i/o synchronization api's.
What's typically better, writing a function to the process via WriteProcessMemory, or calling LoadLibrary in the remote process?
Quote Originally Posted by t7ancients View Post
What's typically better, writing a function to the process via WriteProcessMemory, or calling LoadLibrary in the remote process?
Bit hard to say as we have no idea what function you're writing to memory but calling LoadLibrary in the remote process typically requires use of WriteProcessMemory anyway, so if your function can circumvent the need to call LoadLibrary at all, there's less chance of detection.

@.::SCHiM::. I did say it had downsides hehe, personally I've never used it but I did see someone use it as an alternative to avoid calling CRT so I thought I'd throw it in/
i have tried to make one with the calling LoadLibraryA method but it doesnt work
The best would be to manualmap the dll files into the remote process. This way the module won't show up inside the ldr->module list and will therefore not appear in api calls like GetModuleHandle nor will it in any of the CreateSnapshot() functions since it has not been registered.

It's not that hard to load a dll file manually, especially if you compile that dll yourself. You only need to take some extra care to insure proper execution. For example you can use dynamic linking so that you don't have to patch the import table with your injector, the only thing you'll have to do is insure that the dll is at the proper place. When it's all done you start a remote thread at it's entrypoint and watch the show.
How would you do that? Get the dll into a byte array or something and write the entire thing to the target process's memory?
Quote Originally Posted by t7ancients View Post
How would you do that? Get the dll into a byte array or something and write the entire thing to the target process's memory?
Slightly harder than that, as you can see from my example code post above. You need to fix a bunch of values in the image before writing it to memory, such as the import table and section headers. Requires some knowledge of the PE architecture if you're not planning on straight leeching
Are there any articles or e-books, or something like that, about PE/PE+? I'd love to learn about it, just not sure where to look.
Quote Originally Posted by t7ancients View Post
Are there any articles or e-books, or something like that, about PE/PE+? I'd love to learn about it, just not sure where to look.
Microsoft provides a fairly comprehensive PE-COFF specification guide on its website. 97 pages of victory.

Microsoft PE and COFF Specification

Matt Pietrek is also something of an authority on the PE architecture so read any of his articles on MSDN.
@Jason What's that image title you have?

I learned a great deal about the PE structure on this website, they are assembly tutorials, but the images and overviews are very clear. He also offers demo code you can use to see if files are PE or not, and how to extract information from the various fields.
Quote Originally Posted by .::SCHiM::. View Post
@Jason What's that image title you have?

I learned a great deal about the PE structure on this website, they are assembly tutorials, but the images and overviews are very clear. He also offers demo code you can use to see if files are PE or not, and how to extract information from the various fields.
Former Staff .

Spent the day trying to write some manual mapping code, failed dismally. Just a FYI, after rereading Darawks code you'll notice many bugs. I spent like 3 hours figuring out how loaders resolve the IAT named entries , even now mine isn't perfect.


This worked for me for as far as I needed it to work:

Code:
void Pe32_load_init::PatchImportTable(){

	IMAGE_DOS_HEADER*		 dos = (IMAGE_DOS_HEADER*)ImageBase; 
	IMAGE_NT_HEADERS*		 nt  = (IMAGE_NT_HEADERS*)((int)dos+dos->e_lfanew);
	IMAGE_IMPORT_DESCRIPTOR* iid = (IMAGE_IMPORT_DESCRIPTOR*)(nt->OptionalHeader.ImageBase + nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

	for(int i = 0; iid[i].Characteristics != 0; i++){


		 IMAGE_THUNK_DATA* first_thunk = (IMAGE_THUNK_DATA*)((int)dos +  iid[i].FirstThunk);
		 IMAGE_THUNK_DATA* orig_first_thunk = (IMAGE_THUNK_DATA*)((int)dos + iid[i].OriginalFirstThunk);

			for(int y = 0; orig_first_thunk[y].u1.Function != NULL; y++){
  				IMAGE_IMPORT_BY_NAME* orig_imports_by_name = orig_first_thunk[y].u1.AddressOfData;
				orig_imports_by_name = (IMAGE_IMPORT_BY_NAME*)((int)dos + (int)orig_imports_by_name);
				char* ModuleName = (char*)((int)iid[i].Name + (int)dos);
				first_thunk[y].u1.Function = (DWORD*) GetProcAddress( LoadLibrary( ModuleName ), (char*)orig_imports_by_name->Name );                                     // set the hook

		 }


	}


}
Quote Originally Posted by .::SCHiM::. View Post


This worked for me for as far as I needed it to work:

Code:
void Pe32_load_init::PatchImportTable(){

	IMAGE_DOS_HEADER*		 dos = (IMAGE_DOS_HEADER*)ImageBase; 
	IMAGE_NT_HEADERS*		 nt  = (IMAGE_NT_HEADERS*)((int)dos+dos->e_lfanew);
	IMAGE_IMPORT_DESCRIPTOR* iid = (IMAGE_IMPORT_DESCRIPTOR*)(nt->OptionalHeader.ImageBase + nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

	for(int i = 0; iid[i].Characteristics != 0; i++){


		 IMAGE_THUNK_DATA* first_thunk = (IMAGE_THUNK_DATA*)((int)dos +  iid[i].FirstThunk);
		 IMAGE_THUNK_DATA* orig_first_thunk = (IMAGE_THUNK_DATA*)((int)dos + iid[i].OriginalFirstThunk);

			for(int y = 0; orig_first_thunk[y].u1.Function != NULL; y++){
  				IMAGE_IMPORT_BY_NAME* orig_imports_by_name = orig_first_thunk[y].u1.AddressOfData;
				orig_imports_by_name = (IMAGE_IMPORT_BY_NAME*)((int)dos + (int)orig_imports_by_name);
				char* ModuleName = (char*)((int)iid[i].Name + (int)dos);
				first_thunk[y].u1.Function = (DWORD*) GetProcAddress( LoadLibrary( ModuleName ), (char*)orig_imports_by_name->Name );                                     // set the hook

		 }


	}


}
LoadLibrary internally calls the LdrpResolveDllName, however the point of manual mapping is to avoid any calls to LoadLibrary, so you need to resolve the dll into a harddisk location. Unfortunately I'm shit at reversing so I couldn't find the address of LdrpResolveDllName as it's a private function in ntdll.dll and thus GetProcAddress doesn't work, I had to go deeper and I found the public function "RtlDosSearchPath_U" in ntdll.dll, but this requires a lot of fucking around to get the parameters right.
Posts 1–15 of 27 · Page 1 of 2

Post a Reply

Similar Threads

Tags for this Thread

None

Talk with us