Dynamic Link Library (dll
) are compiled shared function libraries that can be dynamically loaded by Windows programs. Linux uses Shared Object (so
) files for the same purpose.
dll search order
Order of locations in which dll is searched for depends if SafeDllSearchMode
is set to true (default) or not.
To disable SafeDllSearchMode
we can create following registry key and set its value to 0:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode
If SafeDllSearchMode
is enabled, the search order for desktop applications is as follows:
- The directory from which the application loaded.
- The system directory. Use the
GetSystemDirectory
function to get the path of this directory. - The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
- The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
- The current directory.
- The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
If SafeDllSearchMode
is disabled, the search order is as follows:
- The directory from which the application loaded.
- The current directory.
- The system directory. Use the
GetSystemDirectory
function to get the path of this directory. - The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
- The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
- The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
Before the system searches for a DLL, it checks the following:
- If a DLL with the same module name is already loaded in memory, the system uses the loaded DLL, no matter which directory it is in. The system does not search for the DLL.
- If the DLL is on the list of known DLLs for the version of Windows on which the application is running, the system uses its copy of the known DLL (and the known DLL's dependent DLLs, if any). The system does not search for the DLL. For a list of known DLLs on the current system, see the following registry key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
Dll search order can also be changed programmatically. More information on dll load order can be found here.
dll injection
Dll injection happens if we can insert our own dll in a location with higher search priority then real dll or replace it. If we want to be stealthy, with this approach, we also need to export all functions that real dll provides (by loading it as a dependency and re-exporting its functions).
Sometimes applications try to load dlls that don't exist on the system. In this case, we don't have to worry about the original functionality of dll. Usually, this type of dll injection is called ghost dll injection.
Finding missing dlls
One of the ways to find dlls that application tries to load is to use Procmon
.
We need to set the following filters:
Process Name is <target.exe> Include
Operation is CreateFile Include
Path ends with .dll Include
Result is not SUCCESS Include
For example lets try it on hl.exe:
We see that p2pvoice.dll
is not found and that is being searched for in different locations according to search order.
Simple practical example
Since p2pvoice.dll
doesn't exist we can create our own. For this, we are going to use C++. C# dll libraries don't have a straightforward way to run code as soon as dll is attached.
To create new dll in visual studio 2017 we go to:
New Project -> Visual C++\Windows Desktop\Dynamic-Link Library(DLL)
We can name the project according to dll we want to create.
For simple example we are just going to edit dllmain.cpp
to:
#include <windows.h>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
WinExec("calc", 0);
return TRUE;
}
This will just start the windows calculator whenever dll is attached and detached to process or thread. After building solution generated dll is going to be placed in Debug
folder. To finish with dll injection we can just copy it to CS game folder.
Now if we start hl.exe we are also going to get tons of calc.exe processes opening.
Have fun.
Comments
comments powered by Disqus