2011-04-16 31 views
-1

我与微软的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时,我怎么能定义一个函数具有与给定函数相同的返回值和参数(在这种情况下,MessageBoxAint WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)),然后填充函数的函数体?

+0

听起来你寻找eval() - 动态类型语言的圣杯。但它在C++中不可用。当然,您可以将函数写入文件,调用编译器以便生成可加载的库,加载它,获取指向该函数的指针。 – Ingo 2011-04-16 14:36:42

+1

这听起来像你想钩住整个Win32 API。要做到这一点与Detours将要求您为每个API函数生成存根。您可以在运行时执行此操作,但会涉及运行时代码生成。这是可能的,但在C++中自然比在Python,.net等中有点难。因为你不想为所有API函数生成存根,所以你已经陷入了僵局。也许你可以告诉我们你的最终目标。例如,你是否想要测试应用程序对Win32 API的使用? – 2011-04-16 15:32:44

+0

@大卫我想做的事:第一,得到所有的程序将其exe文件使用,然后勾具有新功能的那些功能,将打印功能的名称的API,这样我就可以得到怎样的API序列在程序中调用,然后使用这些信息做一些安全检查 – wong2 2011-04-16 15:44:53

回答

1

在C++中,功能不是first-class object,这意味着它们不能在运行时被创建。

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

+0

我不能做一个预定义的函数指针数组......有太多的API函数。 – wong2 2011-04-16 14:38:47

+0

@ wong2:你的问题不够清楚。基于我从你的问题的措词中理解的内容,我只能说在函数运行时不能在C++中创建函数。 – Nawaz 2011-04-16 14:41:03

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表达式),这将使很多这更容易

相关问题