DLL injection
Computer programming technique
- 4 min read
- 2 chapters
Related on Lably
Through Computer programming, Process (computing) and Password
Approaches on Microsoft Windows
There are multiple ways on Microsoft Windows to force a process to load and execute code in a DLL that the authors did not intend:
- DLLs listed in the registry entry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLsare loaded into every process that loads User32.dll during the initial call of that DLL. Beginning with Windows Vista, AppInit_DLLs are disabled by default. Beginning with Windows 7, the AppInit_DLL infrastructure supports code signing. Starting with Windows 8, the entire AppInit_DLL functionality is disabled when Secure Boot is enabled, regardless of code signing or registry settings. - DLLs listed under the registry key
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\AppCertDLLsare loaded into every process that calls the Win32 API functionsCreateProcess,CreateProcessAsUser,CreateProcessWithLogonW,CreateProcessWithTokenWandWinExec. That is the right way to use legal DLL injection on current version of Windows - Windows 10. DLL must be signed by a valid certificate. - Process manipulation functions such as
CreateRemoteThreador code injection techniques such as AtomBombing, can be used to inject a DLL into a program after it has started.- Open a handle to the target process. This can be done by spawning the process or by keying off something created by that process that is known to exist – for instance, a window with a predictable title, or by obtaining a list of running processes and scanning for the target executable's filename.
- Allocate some memory in the target process, and the name of the DLL to be injected is written to it.
- This step can be skipped if a suitable DLL name is already available in the target process. For example, if a process links to User32.dll, GDI32.dll, Kernel32.dll or any other library whose name ends in
32.dll, it would be possible to load a library named32.dll. This technique has in the past been demonstrated to be effective against a method of guarding processes against DLL injection.
- This step can be skipped if a suitable DLL name is already available in the target process. For example, if a process links to User32.dll, GDI32.dll, Kernel32.dll or any other library whose name ends in
- Create a new thread in the target process with the thread's start address set to be the address of
LoadLibraryand the argument set to the address of the string just uploaded into the target.- Instead of writing the name of a DLL-to-load to the target and starting the new thread at
LoadLibrary, one can write the code-to-be-executed to the target and start the thread at that code.
- Instead of writing the name of a DLL-to-load to the target and starting the new thread at
- The operating system then calls the initialization routine of the injected DLL.
- Note that without precautions, this approach can be detected by the target process due to the
DLL_THREAD_ATTACHnotifications sent to every loaded module as a thread starts.
- Windows hooking calls such as
SetWindowsHookEx. - Use the
SuspendThreadorNtSuspendThreadfunction to suspend all threads, and then useSetThreadContextorNtSetContextThreadfunction to modify an existing thread's context in the application to execute injected code, that in turn could load a DLL. - Exploit design limitations in Windows and applications that call the
LoadLibraryorLoadLibraryExfunction without specifying a full-qualified path to the DLL being loaded. - Operating system-level shims.
- Substituting an application-specific DLL with a rogue replacement that implements the same function exports as the original.
- Reflective DLLs or DLLs that are able to load themselves. The reflective DLL is copied into memory space of the target process and execution is passed to the entry point of the DLL which then loads itself from memory.
Sign in to keep reading
One more chapter is free with a Lably account.
Approaches on Unix-like systems
On Unix-like operating systems with the dynamic linker based on ld.so (on BSD) and ld-linux.so (on Linux), arbitrary libraries can be linked to a new process by giving the library's pathname in the LD_PRELOAD environment variable, that can be set globally or individually for a single process.
For example, on a Linux system, this command launches the command "prog" with the shared library from file "test.so" linked into it at the launchtime:
<span id="mwASg"></span><span class="nv" id="mwASk">LD_PRELOAD</span><span class="o" id="mwASo">=</span><span class="s2" id="mwASs">"./test.so"</span><span class="w" id="mwASw"> </span>prog
Such a library can be created in the same way as other shared objects. With GCC, this involves compiling the source file containing the new globals to be linked, with the -fpic or -fPIC option, and linking with the -shared option. The library has access to external symbols declared in the program like any other library.
On macOS, the following command launches the command "prog" with the shared library from file "test.dylib" linked into it at the launchtime:
<span id="mwAUY"></span><span class="nv" id="mwAUc">DYLD_INSERT_LIBRARIES</span><span class="o" id="mwAUg">=</span><span class="s2" id="mwAUk">"./test.dylib"</span><span class="w" id="mwAUo"> </span><span class="nv" id="mwAUs">DYLD_FORCE_FLAT_NAMESPACE</span><span class="o" id="mwAUw">=</span><span class="m" id="mwAU0">1</span><span class="w" id="mwAU4"> </span>prog
It is also possible to use debugger-based techniques on Unix-like systems.

