C++ Hook 成员函数和原始函数返回垃圾值。

标签 c++ winapi dll hook detours

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

目标.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; 
}

注入(inject).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

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

最佳答案

来自 Using Detours :

For proper interception the target function, detour function, and the target pointer must have exactly the same call signature including number of arguments and calling convention. Using the same calling convention insures that registers will be properly preserved and that the stack will be properly aligned between detour and target functions

int hookedFunction(void *obj) 不符合 __thiscall 的调用约定。

可能还有其他错误,但这是一个明显的错误。

关于C++ Hook 成员函数和原始函数返回垃圾值。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54001303/

相关文章:

c++ - 双重选择对数组进行排序 - honeSTLy stumped

c++ - 线程崩溃后离开临界区

c++ - TCP 温索克 : accept multiple connections/clients

c - mingw-w64 搜索 libws2_32.dll 而不是 ws2_32.dll

c# - 在 Unity 中使用 DLL,MonoBehaviour

c++ - 是否可以在 std::any 中存储引用?

c++ - 在 C++ 中重载 ifstream

python - 需要一种使用 Python 从 Zune 和 Windows Media Player 中检索当前播放歌曲的方法

java - 如何查看 JVM 加载了哪些 native dll?

c++ - 使用 OpenMP 进行约简以计算矩阵元素的最终求和值