экспорт c с определенным адресом для прокси-сервера dll

#c #dllexport

Вопрос:

Я хотел бы создать свою первую прокси-библиотеку dll для перехвата и регистрации вызовов, которые программное обеспечение использует для одной из своих библиотек DLL. Мой опыт в экспорте dll все еще ограничен.

С помощью некоторого онлайн-руководства я смог использовать генератор прокси dll и создал первый код, который я настроил.

Мне нужно экспортировать функцию-оболочку с определенным именем адреса, в моем случае это имя: "?GetInstance@CRfebUsbApp@@SAPAV1@XZ" . Но исходная функция имеет свой собственный заголовок, отличный от функции-оболочки.

 Error LNK2001 "public: static class CRfebUsbApp * __cdecl CRfebUsbApp::GetInstance(void)" (?GetInstance@CRfebUsbApp@@SAPAV1@XZ) not solved
 

код :

 #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;
}
 

Обновление 1.

Я нашел частичное решение, хотя и не думаю, что это самый простой способ.

Чтобы удовлетворить компоновщику, я определяю функции-оболочки в соответствии с требованиями исходного заголовка функции

 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;
}
 

теперь у меня есть 2 проблемы.

  1. перейдите к исходной функции, передав все параметры с помощью _asm, и верните значения, если они есть
  2. упростите эту структуру, так как исходная библиотека dll содержит более 60 функций, и я не могу обернуть их все так.

Комментарии:

1. Не делай этого сам, github.com/microsoft/detours