While performing dll hijacking or dll search order hijacking, you must have noticed that the vulnerable process is opening your malicious dll but the dll doesn't get loaded or your payload in DllMain
never get executed. The reason for this is, the program looks for certain exports using GetProcAddress
, which it expects to present in the target dll. If they are not found then the Dll loading failed or DllMain
never runs. In this short post we will learn how to fix this issue.
Finding Exported function
For a dll or library to be useful it should export functions that others can import.
There are two ways a function can be exported:
- Export by Name
- Export by Ordinal
An export by name is, exporting the function with referring its name in export table. On other hand, export by ordinal is nothing but exporting using an index in export table. Once a function is exported by ordinal, it can only be imported with ordinal value. Most of the time the functions are exported using name rather than ordinals.
You can use CFF explorer to view all the exports present in a dll.
While developing your malicious dll you need to export these functions using one of the below mentioned method.
Generic Export
You can export a function in dll using __declspec(dllexport)
method.
extern "C" __declspec(dllexport) void __cdecl function1(void)
{
...
return;
};
extern "C" __declspec(dllexport) void __cdecl function2(void)
{
...
return;
};
extern "C" __declspec(dllexport) void __cdecl function3(void) { return; };
This way you can export these functions ( function1
, function2
, function3
) to import by other process.
This method has a big drawback that it is easily detectable and most probably will crash the program. Reason for this is because when the program will call these functions, they will receive unexpected returned data that they failed to handle or proceed with.
Export Forwarding or DLL Proxy
This technique(also called as Dll proxy) is much more stealthy and will not break the program execution. We can use export forwarding feature present in windows to export functions. Famous malware like Stuxnet uses this method.
Forwarded Exports: A module can forward a function to be handled by another module. This feature is mostly used to maintain the backward compatibility. For eg: it might be used if code was refactored to move a function to different module, but you want to maintain backward compatibility.
While creating the malicious dll you can forward all the function calls to original dll
#pragma comment(linker, "/export:DllCanUnloadNow=C:\\\\Windows\\\\System32\\\\SHCore.dll.DllCanUnloadNow")
#pragma comment(linker, "/export:CommandLineToArgvW=C:\\\\Windows\\\\System32\\\\SHCore.dll.CommandLineToArgvW")
#pragma comment(linker, "/export:DllGetClassObject=C:\\\\Windows\\\\System32\\\\SHCore.dll.DllGetClassObject")
You can also export by ordinal:
#pragma comment(linker, "/export:ord243=C:\\\\Windows\\\\System32\\\\SHCore.dll.#243,@243")
Here 243 is the ordinal number in original SHCore.dll.
In most sophisticated malwares you will notice that both method direct export and export proxy are used for dll hijacking. They only implement their own exports for functions that they care about or want to trace and for remaining functions they just simply forward the export to original dlls.
That's it for this post. Stay tuned for more stuff.