-1

我正在玩微软的Detours to hook 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为 to int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)),然后填充函数的函数体?

4

2 回答 2

1

在 C++ 中,函数不是一等对象,这意味着它们不能在运行时创建。

但是,您可以使用函数指针数组,每个指针指向一个已经定义的函数,并在运行时根据某些条件选择适当的函数指针,然后调用它。看起来您已经在代码片段中使用了函数指针。

于 2011-04-16T14:33:36.470 回答
0

这并不完全正确。您可以轻松存储(成员)函数引用,因此您可以让函数调用另一个函数(可在运行时确定)。

您还可以使用 a functor,它是一个结构/类,用于加载 () 运算符。然后,这可以使用类的状态来记住要调用的实际函数。一个仿函数的例子:

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 表达式),这将使这一切变得更容易

于 2011-04-16T14:46:28.960 回答