Here is another way you can make a proxy fairly easy and slim. Since you do not need to know the actual function prototype/parameters when exporting things that are just using direct jumps via inline asm, you can mix and abuse macros with inline asm to export things easy.
PHP Code:
#include <Windows.h>
HMODULE g_ModuleHandle = nullptr; // This proxies module handle.
HMODULE g_RealModuleHandle = nullptr; // The real modules handle being proxied.
/**
* Obtains the original export from the real module.
*/
BOOL APIENTRY GetRealExport(const char* name, FARPROC* out)
{
// Ensure the real module is loaded..
if (g_RealModuleHandle == nullptr)
return FALSE;
// Todo: Add any type of function caching if you want here..
// Obtain the real export function..
*out = ::GetProcAddress(g_RealModuleHandle, name);
return (*out == nullptr);
}
/**
* Generates an export function wrapper for the given exported function by name.
*/
#define EXPORTORIG(n) \
FARPROC orig_##n = nullptr; \
__declspec(naked) void __stdcall real_##n() { \
GetRealExport(#n, &orig_##n); \
__asm jmp orig_##n \
}
EXPORTORIG(Direct3DCreate9);
/**
* Initialize the proxy for use.
*/
BOOL APIENTRY InitializeProxy(HINSTANCE hinstDLL)
{
// Store the modules handle..
g_ModuleHandle = hinstDLL;
// Build the path to the original module..
char path[MAX_PATH] = { 0 };
::GetSystemDirectory(path, MAX_PATH);
strcat_s(path, "\\d3d9.dll");
// Load the original module..
g_RealModuleHandle = ::LoadLibrary(path);
if (g_RealModuleHandle == nullptr)
return FALSE;
return TRUE;
}
/**
* Entry point.
*/
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
::DisableThreadLibraryCalls(hinstDLL);
return InitializeProxy(hinstDLL);
}
return TRUE;
}
And in the .def file:
PHP Code:
LIBRARY
EXPORTS
Direct3DCreate9 = real_Direct3DCreate9
Beings that this is using a macro for the dirty work/heavy lifting you can easy create a template/skeleton project to auto-generate the entire proxy dll for you like this just by having it read the original exports from the target file and generating the rest.
Note, this method as-is will have issues with exports that are by ordinal and not by name. You would have to tweak the generated names a tad to work with ords instead.