c++ export with specific address for dll proxy

Viewed 115

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.

  1. jump to the original function by passing all parameters with _asm and return the values if present
  2. simplify this structure as the original dll contains more than 60 functions and I cannot wrapping them all like this.
0 Answers
Related