windows使用detours实现进程拦截实操
Detours是微软开发的一个函数库,可用于捕获系统API。可以从github下载源码并编译。Detours通过更改被拦截的API函数的跳转地址为用户自定义的函数地址来实现拦截。比如我们知道要拦截API函数A,我们需要自定义一个函数B,在实现拦截之前,此时函数A所在的线程正常调用A。开始拦截的时候,Detours库函数将A的入口地址修改为B的函数指针。此前线程对函数A的调用将会被替换为被函数B的调用,当然前提是函数A和函数B的函数签名完全一致。在将函数A的入口地址修改函数B的地址时已经保留了函数A的原始地址,所以函数B的函数形式形如
void* funcB(arg1,arg2,...){
void* retPtr= funcA(arg1,arg2,...)
}
所以我们在函数B中能做的事情就是拦截并修改目标函数参数或者修改原函数的返回值。那么我们如何拦截一个进程的命令行参数呢。在windows系统中,进程是存在父子关系的树状结构。每一个子进程都由它的父进程所创建。一般的 我们都是在资源管理器中点击程序的exe可执行文件来启动进程,那么此时资源管理器进程(explorer.exe) 就是被启动进程的父进程,还有我们熟悉的命令行程序cmd.exe,还有开发者们常用的开发工具如idea,visual studio,eclipse 等等都扮演着父进程的角色。父进程一般通过CreateProcess来创建子程,CreateProcess函数通过命令行参数即可以启动子进程。所以拦截进程的创建和启动就是通过拦截父进程中CreateProcess函数的参数和返回值来实现。我们要实现的函数B需要在一个独立的dll中实现,这个dll可以通过detours工具setdll.exe插入目标父进程的导入表
或者detours工具withdll.exe启动时被目标父进程加载到进程空间,
以下的例子程序通过拦截idea64.exe中的CreateProcess函数 实现打印CreateProcess函数的命令行参数。如果原函数CreateProcess为A,那么MyCreateProcessW则为B。
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include "detours.h"
#pragma comment(lib,"detours.lib")
typedef BOOL(WINAPI* PMyCreateProcessW)(
_In_opt_ LPCWSTR lpApplicationName,
_Inout_opt_ LPWSTR lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCWSTR lpCurrentDirectory,
_In_ LPSTARTUPINFOW lpStartupInfo,
_Out_ LPPROCESS_INFORMATION lpProcessInformation
);
PMyCreateProcessW gOldCreateProcessW = NULL;
BOOL
WINAPI
MyCreateProcessW(
_In_opt_ LPCWSTR lpApplicationName,
_Inout_opt_ LPWSTR lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCWSTR lpCurrentDirectory,
_In_ LPSTARTUPINFOW lpStartupInfo,
_Out_ LPPROCESS_INFORMATION lpProcessInformation
) {
printf("lpApplicationName:【%ls】,lpCommandLine【%ls】\n\n", lpApplicationName, lpCommandLine);
return gOldCreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes,
bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation
);
}
void Hook(){
AllocConsole();
freopen("CON", "r", stdin);
freopen("CON", "w", stdout);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
gOldCreateProcessW = (PMyCreateProcessW)DetourFindFunction("kernel32.dll", "CreateProcessW");
DetourAttach(&gOldCreateProcessW,MyCreateProcessW);
LONG ret = DetourTransactionCommit();
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
//printf("命令行参数:%s\n", GetCommandLineA());
//MessageBoxA(NULL, GetCommandLineA(),GetCommandLineA(),MB_OK);
Hook();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
extern "C" _declspec(dllexport) void _stdcall add() {
printf("zzz\n");
}
//CreateProcessW
编译后得到DetourJavaCDemo.dll
此时 我们使用setdll.exe将编译好的dll插入idea64.exe的导入表
D:\test4\Detours\bin.X64\setdll /d:D:\Users\DELL\source\repos\DetourJavaCDemo\x64\Release\DetourJavaCDemo.dll "C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.5\bin\idea64.exe"
当然最好是使用管理员权限运行命令、否则报出无权访问(error:5)
成功将dll插入idea64.exe的导入表之后,生成了idea64.exe~,idea64.exe~则是 idea64.exe被插入前的备份
下面再以withdll启动idea64.exe
由于上面代码中使用
AllocConsole();
freopen("CON", "r", stdin);
freopen("CON", "w", stdout);
为idea64分配了一个控制台窗口。可以看出由idea64启动的子进程命令行参数被打印了出来。
windows使用detours实现进程拦截实操相关推荐
- supervisor 守护多个进程_supervisor守护进程管理实操笔记
2020年年后工作中需开发一支持多数据源自动上报业务数据的程序,程序开发完部署上线时需要对其进程进行自动管理,不然哪天程序down了还不知,可就麻烦了,所以这里选用了强大的supervisor,以下文 ...
- Windows MySQL8.0免安装版(实操配置以及多个mysql实例时的踩坑经验)
具体操作 1.下载mysql的免安装压缩包 2.解压缩到指定目录下,并新增配置文件和data目录 3.初始化数据库 4.注册mysql服务 5.登录mysql并且修改root密码 6.开放防火墙端口并 ...
- win python 怎么打开建立一个孤立的进程_python实现在windows服务中新建进程的方法...
本文实例讲述了python实现在windows服务中新建进程的方法.分享给大家供大家参考.具体实现方法如下: 需要安装的软件:python和pywin32,我这里装的分别是python-2.6.amd ...
- Windows自带虚拟化服务工具Hyper-V学习了解和实操
原文地址:https://docs.microsoft.com/zh-cn/virtualization/hyper-v-on-windows/about/ 微软提供的虚拟化服务:https://do ...
- c语言创建windows进程,C语言实现在windows服务中新建进程的方法
本文实例讲述了C语言实现在windows服务中新建进程的方法.分享给大家供大家参考.具体如下: 运行环境:visual stdio 2008 文件名:testService.c #include #i ...
- 【Linux】2. Linux实操命令
Linux实操命令 2. Linux实操 2.1 远程登陆Linux系统 2.2 Vi和Vim编辑器 2.3 开机.重启和用户登陆注销 2.4 用户管理 2.5 指定运行级别指令 2.6 重置root ...
- Linux实操篇笔记
Linux实操篇 远程登陆Linux 先检查一下sshd服务打开没有( " * " 表示打开): setup 选择系统设置,进入下面页面: Xshell 是一个强大的安全终端模拟软 ...
- UnrealEngine5实操--基础概念(持续补充)
UnrealEngine5实操--基础概念 Unreal 术语 UE5 上手指南 关卡快速搭建 视口标准按键操作 Editor 视角移动速度调节 Unreal Editor 快速测距 Actor 操作 ...
- MapReduce入门(一)—— MapReduce概述 + WordCount案例实操
MapReduce入门(一)-- MapReduce概述 文章目录 MapReduce入门(一)-- MapReduce概述 1.1 MapReduce 定义 1.2 MapReduce 优缺点 1. ...
- 002_韦东山嵌入式Linux应用开发基础_实操碰到的问题集锦
嵌入式Linux应用开发基础_韦东山教程思考笔记 配合<嵌入式Linux应用开发完全手册V5.1_IMX6ULL_Pro开发板> 文件目录 访问根/目录下,Filesystem Root目 ...
最新文章
- SQL Server Profiler工具
- SpringCloud使用Sofa-lookout监控(基于Eureka)
- 访问 IIS 元数据库失败解决问题的方法
- c++枚举类型(二) 命名空间
- neo4j cypher_neo4j / cypher:悬挂查询参数
- 如何使用Apache Drill分析高度动态的数据集
- mysql 的标识符_MySQL查询或标识符在Jupyter中太长?
- 计算走线长度_高速走线长度的一些思考
- 高德地图获取经纬度并逆定位获取地理位置名称(原生)
- linux复制dos命令,Linux mcopy复制MSDOS格式档案命令详解
- 【其他】程序员装修指南
- 低成本的电流检测电路
- FingerGestures研究院之初探Unity手势操作(一)
- Android studio显示百度地图及闪退问题的解决
- 屏幕适配入门-了解基本概念-图片适配
- npm配置镜像、设置代理cnpm和取消代理的方法
- 波士顿地区Airbnb价格预测Project (一)
- 中国无线电发射器市场趋势报告、技术动态创新及市场预测
- 《KOF97》彩蛋揭秘:九龙城看台里塞进了21位大佬?
- 2021年伊宁三中高考成绩查询,伊宁三中2015高考榜.doc