What happened to OC? - CLOSED Carnage?!
Sign in to follow this  
Followers 0
WaeV

[C++][C#] True Dll Injection

19 posts in this topic

Tiddy-bits:

Nicely written article.

Code injection can be done without dll injection, dll injection just wraps it up nice and pretty in PE format so the ldr will initialize imports/exports/alignment/relocations/etc etc etc when LdrLoadDll is called on it. CreateProcess follows a similar process once it gets past the allocation and creation of main structs (PEB, TIB, EPROCESS linking, etc) in the process's va space. You can hook LdrIntializeThunk and just trace that into the PE loading if you ever get bored ;) Anyways, manual loading is mainly used for adversarial purposes as there is hardly any use of creating your own loader besides the education, which is pretty cool but hey, one already exists. The people who are doing this via dll loading are either stupid due to traces it leaves in memory that cannot be erased from usermode, or are smart enough to be using proxies/apc/other injection methods that Windows does automatically and don't require LoadLibrary/LdrLoadDll. Dlls for code injection/thread hijacking as such as you're describing above generally aren't used much outside game mods, tbh straight up code injection and manually loading your PE is better than dll injection, it's a lot more flexible and allows you to embed your exe in the target seeing as you don't have to load exclusively from a file.

As for DllMain, remember that you're fine as long as you're not creating another thread (which will make a race condition while the loader finishes and who knows what else is happening) and you DisableThreadLibraryCalls and just expect DLL_PROCESS_ATTACH to be the initialization function, you will be fine calling standard winapi stuff despite whatever Microsoft may say. The only difference between a dll and exe physically is one bit, but the loader is quite a bit different.

If you locate all statically [terminology?] loaded dlls in your own process you can count on the fact that they'll be mapped to the same address in your target btw, so kernel32, ntdll, and kernelbase/wow64cpu for wow64. Also, the A is for Ascii ;)

/digression or random info dump

WaeV likes this

7oWRJVS.gif

Share this post


Link to post
Share on other sites

DllMain is a tricky area. You can't create new threads, you can't load other dlls, you can't create any GUI elements, and you can't create any objects with thread affinity. There are probably other things to avoid. In fact, there is a lock on each process's dll loader, so as long as you're doing processing in DllMain no other thread in that process can load new dlls. The general strategy is "do what you need as quick as possible, then exit". I can't think of much that I would do in DllMain that can't be done with WriteProcessMemory.

Very good points regarding code injection, though. I know it's possible to remove traces of dlls - you can modify the linked list of loaded modules to hide the fact that your dll is loaded, for example. Using WriteProcessMemory to copy your code over is definitely more customizeable. I suppose it's up for debate which is more fragile of a process - WPM or unhooking your dll from the loaded modules list.

Haha, yup. A for ascii, W for wide. I think wchars are UTF-16 on Windows, but UTF-32 on other platforms.

Share this post


Link to post
Share on other sites

You can create threads and load other DLLs (with caution) in DLLMain. The problems arise when you try and wait on them to complete some task, since they can't run until the loader lock is released.

As a general rule, there shouldn't be any need to do anything heavy in your DLLMain anyway. In the case of HAC where it needs to do a bunch of initialisation but doesn't have the benefit of any external process to control it, it simply uses DLLMain to write a hook to the code that gets called immediately following LoadLibrary that detours the main thread to some initialisation function that can safely kick everything off without worrying about causing deadlock.

It sounds like you've already seen Raymond Chen's articles on the subject, so I won't link them. ;)

Edited by Btcc22

Share this post


Link to post
Share on other sites

Certain calls, including ones for thread creation, are perfectly okay as long as you're aware of the fact that they won't run immediately. From MSDN:

Because Kernel32.dll is guaranteed to be loaded in the process address space when the entry-point function is called, calling functions in Kernel32.dll does not result in the DLL being used before its initialization code has been executed. Therefore, the entry-point function can create synchronization objects such as critical sections and mutexes, and use TLS, because these functions are located in Kernel32.dll. It is not safe to call the registry functions, for example, because they are located in Advapi32.dll.
Edited by Btcc22

Share this post


Link to post
Share on other sites

Sort of. I create an initialisation thread in DLLMain and then install a hook right after the LoadLibrary call for synchronisation purposes.

Here's a terrible sequence diagram in screenshot form since I couldn't format it nicely with preview post.

L9qEogP.png

The WaitForSingleObject call is inside the HookedFunction().

Edited by Btcc22

Share this post


Link to post
Share on other sites

Indeed. Halo itself loads the DLL so there's no external process to set things up correctly and since it's important for certain tasks to be completed before the game finishes loading, it has to either keep the main thread hanging for a few moments or risk a bunch of nasty race conditions. ^_^

Edited by Btcc22

Share this post


Link to post
Share on other sites
Sign in to follow this  
Followers 0
  • Recently Browsing   0 members

    No registered users viewing this page.