【C/C++】劫持技术

本文探讨了C/C++中的劫持技术,详细介绍了如何使用Detours库来实现函数劫持,并且具体展示了劫持QQ相关功能的实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

劫持


劫持的原理就是把目标函数的指针的指向修改为自定义函数的地址。
函数是放在内存中的代码区,所以劫持与代码区密切相关。
实现劫持需要使用detours。

detours


detours是微软亚洲研究院出口的信息安全产品,主要用于劫持。这个工具使用C语言实现,所以是跨平台的。
detours根据函数指针改变函数的行为,可以拦截任何函数,即使操作系统函数。

detours下载地址:

实现劫持


开发环境说明: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的规则进行编译)
#include 
   
    
#include 
    
     
#include 
     
      
// 引入detours头文件
#include "detours.h"

//1.引入detours.lib静态库
#pragma comment(lib,"detours.lib")

//2.定义函数指针
static int ( *oldsystem)(const char * _Command) = system;//定义一个函数指针指向目标函数

//3.定义新的函数替代目标函数,需要与目标函数的原型相同
int newsystem(const char * _Command){
	
	char cmd[100] = {0};
	int result = 0;
	sprintf_s(cmd,100, "是否允许该程序执行%s指令", _Command);

	result = MessageBoxA(0,cmd,"提示",1);
	//printf("result = %d", result);
	if (result == 1) // 允许调用
	{
		oldsystem(_Command); //调用旧的函数
	}else{
		// 不允许调用
	}
	return 0;
}

// 4.拦截
//开始拦截
_declspec(dllexport) void Hook()  // _declspec(dllexport)表示外部可调用,需要加上该关键字其它进程才能成功调用该函数
{
	DetourRestoreAfterWith();//恢复原来状态(重置)
	DetourTransactionBegin();//拦截开始
	DetourUpdateThread(GetCurrentThread());//刷新当前线程(刷新生效)
	//这里可以连续多次调用DetourAttach,表明HOOK多个函数

	DetourAttach((void **)&oldsystem, newsystem);//实现函数拦截

	DetourTransactionCommit();//拦截生效
}


//取消拦截
_declspec(dllexport) void UnHook()
{
	DetourTransactionBegin();//拦截开始
	DetourUpdateThread(GetCurrentThread());//刷新当前线程
	//这里可以连续多次调用DetourDetach,表明撤销多个函数HOOK
	DetourDetach((void **)&oldsystem, newsystem); //撤销拦截函数
	DetourTransactionCommit();//拦截生效
}

// 劫持别人的程序:通过DLL注入,并调用Hook函数实现劫持。
// 劫持系统:通过DLL注入系统程序(如winlogon.exe)实现劫持系统函数。

_declspec(dllexport)  void main(){

	Hook(); // 拦截
	system("tasklist"); //弹出提示框

	UnHook(); // 解除拦截
	system("ipconfig"); //成功执行

	system("pause"); // 成功执行

}

     
    
   
3.生成"劫持1.dll"文件
4.把dll注入到QQ.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中弹出来的对话框。


说明:
该工具来自以下两个项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值