Detours是微软官方发布的一个函数库,可用于捕获系统API函数。GitHub下载地址:Github源码地址
下载解压以后,得到Detours-master文件夹,打开vs的开发人员控制台命令行
在管理员模式下的命令行里转到Detours-master/sc所在的文件夹下,比如我的是在cd C:\Program Files (x86)\Microsoft Visual Studio 14.0\Detours-master\src下,然后输入nmake执行编译,如图所示:
编译成功后可以在Detours-master目录下看到一个lib.X86文件夹,里面的detours.lib就是我们所需要的文件
1.包含头文件和库文件
将编译好的detours.lib文件和detours-master/include文件夹下的文件拷贝到项目文件目录下
引入库和头文件
#include "detours.h" //载入头文件
#pragma comment(lib, "detours.lib")//载入库
2.定义旧的函数指针指向原来的函数
比如劫持MessageBoxA函数,在Windows.h文件里可以找到它的函数原型为:
int
WINAPI //指针 #define WINAPI _stdcall 标准调用
MessageBoxA(
_In_opt_ HWND hWnd, //_In_opt可以删掉
_In_opt_ LPCSTR lpText,
_In_opt_ LPCSTR lpCaption,
_In_ UINT uType);
声明旧的函数指针并指向MessageBoxA
int (WINAPI* OldMessageBoxA)(HWND hWnd,LPCSTR lpText, LPCSTR lpCaption, UINT uType) = MessageBoxA;
3.定义新的函数
int WINAPI NewMessageBoxA(HWND hWnd,LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
//重新定义函数行为
//为空可以禁止函数的调用
//加上if else可以限制、同意或者不同意
return;
}
4.开始拦截
void Hook()
{
DetourRestoreAfterWith();//恢复原来状态
DetourTransactionBegin();//拦截开始
DetourUpdateThread(GetCurrentThread());//刷新当前线程
//可以多次调用DetoursAttach
DetourAttach((void **)&OldMessageBoxA, NewMessageBox);//实现拦截, void **二级指针,改变地址
DetourTransactionCommit();拦截生效
}
5.取消拦截
void UnHook()
{
DetourTransactionBegin();//拦截开始
DetourUpdateThread(GetCurrentThread());//刷新当前线程
//可以多次调用DetourDetach撤销调用
DetourDetach((void **)&OldMessageBoxA, NewMessageBox);//实现拦截
DetourTransactionCommit();//拦截生效
}
完整代码测试
注意:需要在Release模式下才能实现拦截
#include
#include
#include
#include "detours.h" //载入头文件
#pragma comment(lib, "detours.lib")//载入库
//定义新的函数指针指向原来的函数
static int (WINAPI* OldMessageBoxA)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) = MessageBoxA;
//定义新的函数
int WINAPI NewMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
//重新定义函数行为
//为空可以禁止函数的调用
//加上if else可以限制、同意或者不同意
MessageBoxW(0, L"拦截成功", L"3", 0);
return 0;
}
void Hook()
{
DetourRestoreAfterWith();//恢复原来状态
DetourTransactionBegin();//拦截开始
DetourUpdateThread(GetCurrentThread());//刷新当前线程
//可以多次调用DetoursAttach
DetourAttach((void**)&OldMessageBoxA, NewMessageBoxA);//实现拦截
DetourTransactionCommit(); //拦截生效
}
void UnHook()
{
DetourTransactionBegin();//拦截开始
DetourUpdateThread(GetCurrentThread());//刷新当前线程
//可以多次调用DetoursDetach撤销调用
DetourDetach((void**)&OldMessageBoxA, NewMessageBoxA);//实现拦截
DetourTransactionCommit();//拦截生效
}
int main()
{
MessageBoxA(0, "窗口1", "1", 0);
Hook();
MessageBoxA(0, "窗口2", "2", 0);
UnHook();
getchar();
return 0;
}
#include
#include
#include"detours.h"
#pragma comment(lib, "detours.lib")
//定义指针指向原函数
static int (*oldsystem)(char const* _Comman) = system;
int newsystem(char const* _Comman)
{
//过滤
char* p = strstr(_Comman, "tasklist");//判断tasklist是否是_Comman的子串
if (p == NULL)//
{
oldsystem(_Comman);//允许执行
}
else
{
printf("禁止执行\n");
}
}
void Hook()
{
DetourRestoreAfterWith();//恢复原来状态
DetourTransactionBegin();//拦截开始
DetourUpdateThread(GetCurrentThread());//刷新当前线程
//可以多次调用DetoursAttach
DetourAttach((void**)&oldsystem, newsystem);//实现拦截
DetourTransactionCommit(); //拦截生效
}
void UnHook()
{
DetourTransactionBegin();//拦截开始
DetourUpdateThread(GetCurrentThread());//刷新当前线程
//可以多次调用DetoursDetach撤销调用
DetourDetach((void**)&oldsystem, newsystem);//实现拦截
DetourTransactionCommit();//拦截生效
}
int main()
{
Hook();
system("calc");
system("tasklist");
getchar();
return 0;
}
通过编写dll动态链接库,将dll文件注入别的程序即可实现劫持。