I would like to create my first proxy dll to intercept and log the calls that a software uses to one of its dlls. My experience in dll export is still limited.
With the help of some online guide, I was able to use a dll proxy generator and created a first code, which I customised.
I need to export the wrapper function with a specific address name, in my case the name is: "?GetInstance@CRfebUsbApp@@SAPAV1@XZ".
But the original function has its own specific header different from the wrapper function.
Error LNK2001 "public: static class CRfebUsbApp * __cdecl CRfebUsbApp::GetInstance(void)" (?GetInstance@CRfebUsbApp@@SAPAV1@XZ) not solved
code :
#include <windows.h>
static HMODULE dll;
static FARPROC getInstance;
#pragma comment(linker, "/export:My_GetInstance=?GetInstance@CRfebUsbApp@@SAPAV1@XZ")
__declspec(naked) void My_GetInstance()
{
// TODO : Log call
_asm {
jmp[getInstance]
}
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
dll = LoadLibrary("OriginalDll.dll");
if (dll == nullptr)
{
ExitProcess(0);
}
getInstance = GetProcAddress(dll, "?GetInstance@CRfebUsbApp@@SAPAV1@XZ");
break;
}
case DLL_PROCESS_DETACH:
{
FreeLibrary(dll);
}
break;
}
return TRUE;
}
Update 1.
I have found a partial solution although I don't think it is the easiest way.
To satisfy the linker, i define the wrapper functions as required by the original function header
class CRfebUsbApp
{
public:
#pragma comment(linker, "/export:?GetInstance@CRfebUsbApp@@SAPAV1@XZ=?GetInstance@CRfebUsbApp@@SAPAV1@XZ")
static CRfebUsbApp* __cdecl GetInstance();
#pragma comment(linker, "/export:?CmtReadRegs@CRfebUsbApp@@QAEEEQAEG@Z=?CmtReadRegs@CRfebUsbApp@@QAEEEQAEG@Z")
unsigned char __thiscall CmtReadRegs(unsigned char, unsigned char* const, unsigned short);
private:
};
CRfebUsbApp* __cdecl CRfebUsbApp::GetInstance(void)
{
FARPROC proc = GetProcAddress(dll, "?GetInstance@CRfebUsbApp@@SAPAV1@XZ");
// jump to proc with params and return value
return nullptr;
}
unsigned char __thiscall CRfebUsbApp::CmtReadRegs(unsigned char, unsigned char* const, unsigned short)
{
FARPROC proc = GetProcAddress(dll, "?CmtReadRegs@CRfebUsbApp@@QAEEEQAEG@Z");
// jump to proc with params and return value
return 0;
}
now i have 2 problems.
- jump to the original function by passing all parameters with _asm and return the values if present
- simplify this structure as the original dll contains more than 60 functions and I cannot wrapping them all like this.