我正在玩微软的Detours以挂钩api,例如,我可以改变MessageBoxA
时发生的事情
以这种方式调用:
int (WINAPI* pMessageBoxA)(HWND, LPCTSTR, LPCTSTR, UINT) = MessageBoxA;
int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{
printf("A function is called here!\n");
return pMessageBoxA(hWnd, lpText, lpCaption, uType); // call the regular MessageBoxA
}
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)pMessageBoxA, MyMessageBoxA);
因此,当您致电MessageBoxA
时,您实际上正在呼叫MyMessageBoxA
现在我想编写一个函数Hook()
,它可以在运行时执行上面的代码。例如,如果我将函数指针MessageBoxA
传递给函数,它将完全按照上面的代码执行
当然,我也可以将其他函数指针传递给它
然后有一个问题,当我在Hook
中得到一个函数指针时,我如何定义一个具有与给定函数相同的返回值和参数的函数(在这种情况下,MessageBoxA
到{{1然后填充函数的函数体?
答案 0 :(得分:1)
在C ++中,函数不是first-class object,这意味着它们无法在运行时创建。
但是,您可以使用函数指针数组,每个指针指向已定义的函数,并根据某些条件在运行时选择适当的函数指针,并调用它。看起来你已经在代码片段中使用了函数指针。
答案 1 :(得分:0)
哪个不完全正确。您可以轻松地存储(成员)函数引用,这样您就可以让函数调用另一个函数(在运行时可以判断)。
您还可以使用functor
这是一个结构/类olverloading()运算符。然后,可以使用类的状态来记住要调用的实际函数。仿函数的一个例子:
STL有一个<functional>
标头,其中包含大量有用的实用程序,使处理(成员)函数引用“更容易”(略)。来自cplusplus.com的随机示例:
// mem_fun example
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
int main ()
{
vector <string*> numbers;
// populate vector of pointers:
numbers.push_back ( new string ("one") );
numbers.push_back ( new string ("two") );
numbers.push_back ( new string ("three") );
numbers.push_back ( new string ("four") );
numbers.push_back ( new string ("five") );
vector <int> lengths ( numbers.size() );
transform (numbers.begin(), numbers.end(), lengths.begin(), mem_fun(&string::length));
for (int i=0; i<5; i++) {
cout << *numbers[i] << " has " << lengths[i] << " letters.\n";
}
return 0;
}
c ++ 0x有很多漂亮的新功能(包括'自动'类型推断和lambda表达式),这将使这很容易