您的位置:首页 > 其它

windows下的API拦截---利用detours库操作

2016-01-29 14:51 330 查看
API拦截技术是一种比较常见的技术,对某个软件使用的系统API进行拦截,可以改变软件的行为,从而达到自己的目的。关于拦截技术的原理,Jeffy在《Windows核心编程》里面介绍的非常详尽,就是通过PE文件的导入表获取到保存了Windows
API函数地址的那个地方,然后把API的内存地址保存起来,把存放API地址的那个地方的内容改成我们自定义函数的地址,这样就实现拦截效果了。可以简单看下流程图:



我们今天使用detours开源库来进行拦截,这个库操作起来非常简单,只需要定义我们自定义的函数,detours库就会自动的进行拦截。如果自己去修改导入表的话,不仅复杂而且容易出错。
1 下载detours开源库
detours 是开源的库,由微软提供。谷歌下然后可以到官网下载。注意,32位的detours是开源的,但64位的detours库是闭源的。谷歌输入detours,很容易找到这个地址:http://research.microsoft.com/en-us/projects/detours/
下载下来,是一个DetoursExpress30.msi文件。然后安装,看下安装后的文件夹:



现在还不能用,因为没有编译,没有头文件和lib文件。
1.我们需要利用nmake编译,这是VS自带的工具,它对Makefile文件进行解析。为了能够在所有目录中使用nmake命令,需要在环境变量Path中配置下路径。我用的是VS2013,所以配置的路径是C:\Program Files (x86)\Microsoft
Visual Studio 12.0\VC\bin;这个配置可能需要重启下电脑才能生效。
2.运行这个文件:C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\vcvars32.bat。打开一个命令行窗口,直接拖过去回车即可,这个批处理用来设置一些变量,如果不运行会导致找不到所需的文件。
3.将命令行切换到detours目录,我本地是C:\Program Files (x86)\Microsoft Research\Detours Express 3.0。然后输入nmake回车即可。
然后 开始编译,编译结束后的目录如下:





有了头文件和detours.lib,我们就可以进行拦截了。其他的并不需要。detours库里提供了很多的例子程序,可作参考。下面我们开始API拦截工作。
我们 试验一下detours库,这次来对PPLive.exe中的WriteFile函数进行拦截,新建一个简单的DLL工程。我对自己的工程的目录进行了一些调整,看起来更加的直观一些:



把detours库的lib文件和头文件放到我们工程的里面,就可以开始写我们的程序了。
#include "DetourInjectTools.h"
#include "detours.h"

BOOL(WINAPI *pWriteFile)(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) = WriteFile;

BOOL WINAPI myself_WriteFile(HANDLE hFile, LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
{
BOOL nResult = pWriteFile(hFile, lpBuffer, nNumberOfBytesToWrite,
lpNumberOfBytesWritten, lpOverlapped);
wchar_t data[MAX_PATH] = L"我们成功了";
OutputDebugStringA(data);
return nResult;
}

__declspec(dllexport) VOID ExportFuncForSetDll(VOID)
{
OutputDebugStringA("ExportFuncForSetDll");
}

void AttachMiFlash()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)pWriteFile, myself_WriteFile);
if (DetourTransactionCommit() == NO_ERROR)
{
//Success
}
}

void DetachMiFlash()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)pWriteFile, myself_WriteFile);
DetourTransactionCommit();
}


detours的使用非常简单,至于为什么这样使用,请参考我的另一篇博客:点击打开链接 ,里面介绍的很详细。这里需要注意的一个点就是一定要写一个导出函数,即使它什么也不做,这是DLL的要求,否则编译通不过。
将工程编译即可得到一个dll文件:DetourTools.dll。注意,我们这次是拦截PPLive的WriteFile,但也可以拦截其他程序,只要注入进去即可。那如何注入呢?
我们需要用到一个工具:setdll.exe。这个工具会将我们的dll注入到目标进程中,这样目标进程在每次启动的时候会自动的调用我们的dll,然后我们的dll又会去拦截目标API。setdll.exe可以网上下载一个。然后将它目标程序的目录里,如下图:



然后启动命令行,切换到该目录下,输入命令“setdll /d:file.dll file.exe”我本地的命令是:



这时候,我们打开PPLive,因为我将在自定义的函数里调用了OutputDebugStringW来显示信息,所以我们打开DebugView工具进行查看:



这说明我们成功的拦截了API,以后想干啥就是自己的了。
这里说明的是,注入的dll的路径和名字是不能改变的,改变了目标进程就会找不到,然而显示错误。
如果不想再注入目标进程,需要手动解除注入,命令行是:setdll /r:file.dll file.exe 这样就取消注入了。
代码放到了csdn资源里,可以进行下载参考。地址:点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: