劫持
劫持的原理就是把目标函数的指针的指向修改为自定义函数的地址。
函数是放在内存中的代码区,所以劫持与代码区密切相关。
实现劫持需要使用detours。
detours
detours是微软亚洲研究院出口的信息安全产品,主要用于劫持。这个工具使用C语言实现,所以是跨平台的。
detours根据函数指针改变函数的行为,可以拦截任何函数,即使操作系统函数。
detours下载地址:
下载地址1: http://research.microsoft.com/en-us/downloads/d36340fb-4d3c-4ddd-bf5b-1db25d03713d/default.aspx
下载地址2: http://pan.baidu.com/s/1eQEijtS
实现劫持
开发环境说明:win7、vs2012
步骤:
1.安装Detours。
2.编译Detours工程。
在安装目录C:\Program Files\Microsoft Research\Detours Express 3.0\src目录下的是工程的源文件。
(1)打开VS2012命令行工具,进入src目录。
(2)使用nmake(linux下是make)命令编译生成静态库。
(3)在lib.x86目录下的.lib文件是win32平台下的静态库文件
(4)在include目录下的是Detours工程的头文件
3.把静态库和头文件引入工程
// 引入detours头文件
#include "detours.h"
// 引入detours.lib静态库
#pragma comment(lib,"detours.lib")
4.函数指针与函数的定义
(1)定义一个函数指针指向目标函数,这里目标函数是system
例如:
detour在realse模式生效(因为VS在Debug模式下已经把程序中的函数劫持了)
static int ( *oldsystem)(const char * _Command) = system;//定义一个函数指针指向目标函数
(2)定义与目标函数原型相同的函数替代目标函数
例如:
//3.定义新的函数替代目标函数,需要与目标函数的原型相同
int newsystem(const char * _Command){
int result = MessageBoxA(0,"是否允许该程序调用system命令","提示",1);
//printf("result = %d", result);
if (result == 1)
{
oldsystem(_Command); //调用旧的函数
}else{
MessageBoxA(0,"终止调用system命令","提示",0);
}
return 0;
}
5.拦截
//开始拦截
void Hook()
{
DetourRestoreAfterWith();//恢复原来状态(重置)
DetourTransactionBegin();//拦截开始
DetourUpdateThread(GetCurrentThread());//刷新当前线程(刷新生效)
//这里可以连续多次调用DetourAttach,表明HOOK多个函数
DetourAttach((void **)&oldsystem, newsystem);//实现函数拦截
DetourTransactionCommit();//拦截生效
}
//取消拦截
void UnHook()
{
DetourTransactionBegin();//拦截开始
DetourUpdateThread(GetCurrentThread());//刷新当前线程
//这里可以连续多次调用DetourDetach,表明撤销多个函数HOOK
DetourDetach((void **)&oldsystem, newsystem); //撤销拦截函数
DetourTransactionCommit();//拦截生效
}
劫持QQ
实现劫持system函数。
1.设置项目生成dll
2.源文件(注意:需要保存为.c文件,或者加上extern C,因为detours是使用C语言实现的,表示代码使用C的规则进行编译)
4.把dll注入到QQ.exe
DLL注入工具下载: https://coding.net/u/linchaolong/p/DllInjector/git/raw/master/Xenos.exe
(1)打开dll注入工具,点击add,选择"劫持1.dll"。
(2)在Process中选择QQ.exe,点击Inject进行注入。
(3)点击菜单栏Tools,选择Eject modules显示当前QQ.exe进程中加载的所有模块,如果有"劫持1.dll"表示注入成功。
5.拦截QQ执行system函数
(1)点击Advanced,在Init routine中填写动态库(dll)中的函数的名称,如Hook,然后点击Inject进行调用。此时,我们已经把system函数劫持了。
(2)点击Advanced,在Init routine中填写main,执行动态库中的main函数。
此时,弹出一个对话框,问是否允许执行tasklist指令,表示成功把system函数拦截下来了。
在任务管理器中选中对话框,右键—转到进程,可以看到是从QQ.exe中弹出来的对话框。
DLL注入工具源码地址: https://coding.net/u/linchaolong/p/DllInjector/git
说明:
该工具来自以下两个项目
Xenos: https://github.com/DarthTon/Xenos.git
Blackbone: https://github.com/DarthTon/Blackbone