【问题标题】:C++ hooking Member function and original function returns garbage value.C++挂钩成员函数和原始函数返回垃圾值。
【发布时间】:2019-01-02 04:45:55
【问题描述】:

我想要钩子类成员函数(使用 dll 注入)。目前,钩子是成功的。 但在挂钩函数中,我用返回编码调用原始函数。 结果,原始函数返回垃圾值。我的工作有什么问题?

目标.cpp

#include <iostream>
#include <windows.h>

class Target
{
    private:
        int _member;

    public:
        Target()
        : _member(0)
        {
        }

        Target(int i)
        : _member(i)
        {
        }

        virtual ~Target()
        {
        }

        int getValue() // I want to hooking this function.
        {
            return _member;
        }
};

int main(int argc, char **argv)
{
    while(1){
        Sleep(10000);        
        Target objA, objB(7);
        std::cout << objA.getValue() << " " << objB.getValue() << std::endl;
    }
    return 0; 
}

注入.dll

#include <windows.h>
#include <detours.h>
#include <iostream>
#include <sstream>

#pragma comment(lib, "detours.lib")

static const int ADDRESS = 0x2180;
int (__thiscall * original_func)(void *);

int hookedFunction(void *obj)
{
    uintptr_t base = (uintptr_t)GetModuleHandle(0);
    std::cout << obj << " Hooked Obj Address.\n";
    int result = original_func(obj);
    std::cout << "original function returns " << result << '\n';
    return result; 
}

DWORD WINAPI Attach(LPVOID param)
{
    uintptr_t base = (uintptr_t)GetModuleHandle(0);

    original_func = (decltype(original_func)) (base + ADDRESS);

    OutputDebugString(TEXT("Attach approach!"));
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourAttach(&(PVOID&)original_func, hookedFunction);

    LONG lError = DetourTransactionCommit();
    if (lError != NO_ERROR) {
        OutputDebugString(TEXT("Attach fail!"));
    } else {
        OutputDebugString(TEXT("Attach Sucess!!"));
    }
    return 0;
}

DWORD WINAPI Detach(LPVOID param)
{
    OutputDebugString(TEXT("Detach approach!"));
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourDetach(&(PVOID&)original_func, hookedFunction);

    LONG lError = DetourTransactionCommit();
    if (lError != NO_ERROR) {
        OutputDebugString(TEXT("Detach fail!"));
    } else {
        OutputDebugString(TEXT("Detach Sucess!!"));
    }
    return 0;
}

BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
    switch(dwReason)
    {
        case DLL_PROCESS_ATTACH:
        {
            CreateThread(0, 0, Attach, hModule, 0, 0); 
            break;
        }
        case DLL_PROCESS_DETACH:
        {
            CreateThread(0, 0, Detach, hModule, 0, 0); 
            break;
        }
    }
    return TRUE;
}

target.cpp 程序的控制台输出。

0 7
0 7
0 7
0 7
0 7
0 7
0 7 <-- (DLL injection!)
000D1069 Hooked Obj Address.
original function returns 843966720 <-- why not 0 or 7?
000D8B30 Hooked Obj Address.
original function returns 890668
890668 843966720
000D1069 Hooked Obj Address.
original function returns 843966720
000D8B30 Hooked Obj Address.
original function returns 890668

正如您在控制台输出中看到的,原始函数返回垃圾值。 为什么原始函数返回垃圾值?

【问题讨论】:

    标签: c++ winapi dll hook detours


    【解决方案1】:

    来自Using Detours:

    为了正确拦截目标函数、迂回函数和目标指针,必须具有完全相同的调用签名,包括参数数量和调用约定。使用相同的调用约定可确保正确保留寄存器,并确保堆栈在 detour 和目标函数之间正确对齐

    int hookedFunction(void *obj) 与 __thiscall 的调用约定不匹配。

    可能还有其他错误,但这是显而易见的。

    【讨论】:

    • 好的,我解决了这个问题,只是在 hookedFunction 中添加了调用约定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-30
    • 2014-06-06
    • 2023-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-13
    相关资源
    最近更新 更多