I'm playing with Microsoft's Detours to hook api, for example, I can change what happens when MessageBoxA
is called in this way:
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);
So when you call MessageBoxA
, you are actually calling MyMessageBoxA
.
Hook()
, which would do what codes above do at runtime. For example, if I pass function pointer MessageBoxA
to the function, it will do exactly what the above开发者_Python百科 code did.
Of course, I can pass other function pointer to it too.
Then there is a question, when I get a function pointer in Hook
, how could I define a function with the same return value and parameter as the given function(in this case, MessageBoxA
to int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
) and then fill the function's function body?In C++, functions aren't first-class object, that means they cannot be created at runtime.
However, you can use an array of function-pointers, each pointer pointing to an already defined function, and choosing the appropriate function-pointer at runtime based on some conditions, and call it. And it looks like you're already using function-pointer in the code-snippet.
Which isn't entirely true. You can easily store a (member) function reference, so you can have a function call another function (decidable at runtime).
You can also use a functor
which is a struct/class olverloading the () operator. This can then use the class's state to remember which actual function to call. An example of a functor:
STL has a <functional>
header that contains a load of helpful utilities to make handling (member) function references 'easier' (slightly). Random example from 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 has a lot of nifty new features (including 'auto' type inference and lambda expressions) that will make a lot of this easier
精彩评论