最近有用到detour,属于一种api拦截的方式了,是微软研究院出的一个库(可以网上下载,是源码形式,有makefile,可用vs的命令行工具来编译出来)。可以替换掉我们关心的api,进入到我们的处理中。
当然,api拦截,首先需要借助Dll注入,才能够去影响你想改变的进程,这可通过上篇文章中全局hook来实现:可在hookProc回调中,进行detour,然后在DLL的proc_detach中undetour就可以了。
其实detour的使用倒是很简单了。直接几个接口就可以了,具体看下面代码。
static bool _apihooked = false;
static int (WINAPI *SysMessageBox)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
= MessageBox;
// detour function that replaces the MessageBox API
int WINAPI HookMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{
using namespace std;
wofstream ofs(L"record.txt", ios::app);
ofs.write(lpText, _tcslen(lpText));
ofs.close();
return SysMessageBox(hWnd, lpText, lpCaption, uType);
}
static bool _detourStart()
{
DetourRestoreAfterWith();//
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)SysMessageBox, HookMessageBox);
LONG ret = DetourTransactionCommit();
if (ret != NO_ERROR)
{
assert(false && "detour start failed");
return false;
}
return true;
}
static bool _detourStop()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)SysMessageBox, HookMessageBox);
LONG ret = DetourTransactionCommit();
if (ret != NO_ERROR)
{
assert(false && "detour stop failed");
return false;
}
return true;
}
bool DetourStart()
{
if (!_apihooked)
{
if (!_detourStart())
return false;
_apihooked = true;
}
return true;
}
bool DetourStop()
{
if (_apihooked)
{
if (!_detourStop())
return false;
_apihooked = false;
}
return true;
}