win7生成生成Detours.lib以及简单使用实例

56 篇文章 5 订阅
3 篇文章 0 订阅

 Detours是微软开发的一个函数库,可用于捕获系统API。在用其进行程序开发之前,得做一些准备工作:

一.下载Detours
     在http://research.microsoft.com/sn/detours 可免费下载Detours
二.安装Detours
        一路NEXT
三.生成Detours库
        在安装后的文件夹下找不到直接可以拿来用的LIB文件,但是却有SRC文件(在**\Microsoft Research\Detours Express 2.1\src下)。该文件夹下还有Makefile,可以直接用来生成库。
        将Detours路径下的SCR文件夹拷贝到**\Microsoft Visual Studio 9.0\VC路径下,注意是整个文件夹(其它版本VC自己照着复制)
        运行cmd,(win7需要在system32目录找到cmd右键以管理员身份运行),切换至 c:\Program Files\Microsoft Visual Studio 9.0\VC\bin目录运行vcvars32.bat
        切换到\Microsoft Visual Studio9.0\VC\SRC,然后输入..\bin\nmake指令,编译成功后在\Microsoft Visual Studio9.0\VC\Lib文件下就能找到detoured.lib与detours.lib文件了。

 

来看几个关键函数:

在Detours库中,驱动detours执行的是函数

LONG DetourAttach(
	PVOID * ppPointer,
	PVOID pDetour);

这个函数的职责是挂接目标API,函数的第一个参数是一个指向将要被挂接函数地址的函数指针,第二个参数是指向实际运行的函数的指针,一般来说是我们定义的替代函数的地址。但是,在挂接开始之前,还有以下几件事需要完成:
需要对detours进行初始化. DetourTransactionBegin()
需要更新进行detours的线程. DetourUpdateThread(GetCurrentThread())
在这两件事做完以后,detour函数才是真正地附着到目标函数上。
在此之后,调用DetourTransactionCommit()是detour函数起作用并检查函数的返回值判断是正确还是错误。

想把HOOK的函数改回來则可以使用:

LONG WINAPI DetourDetach(
	PVOID *ppPointer,
	PVOID pDetour)

参数与DetourAttach相同

简单例子:HOOK MessageBoxW函数:

#include "stdafx.h"
#include <detours.h>
#pragma comment(lib, "detours.lib")

static int (WINAPI* OLD_MessageBoxW)(
	HWND hWnd,
	LPCWSTR lpText,
	LPCWSTR lpCaption,
	UINT uType)=MessageBoxW;

int WINAPI NEW_MessageBoxW(HWND hWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType)
{
	//修改输入参数,调用原函数
	int ret=OLD_MessageBoxW(hWnd,L"输入参数已修改",L"[测试]",uType);
	return ret;
}

VOID Hook()
{
	DetourRestoreAfterWith();
	DetourTransactionBegin();
	DetourUpdateThread(GetCurrentThread());

	//这里可以连续多次调用DetourAttach,表明HOOK多个函数
	DetourAttach(&(PVOID&)OLD_MessageBoxW,NEW_MessageBoxW);

	DetourTransactionCommit();
}

VOID UnHook()
{
	DetourTransactionBegin();
	DetourUpdateThread(GetCurrentThread());

	//这里可以连续多次调用DetourDetach,表明撤销多个函数HOOK
	DetourDetach(&(PVOID&)OLD_MessageBoxW,NEW_MessageBoxW);

	DetourTransactionCommit();
}

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	MessageBoxW(0,L"正常消息框",L"测试",0);
	Hook();
	MessageBoxW(0,L"正常消息框",L"测试",0);
	UnHook();
	return 0;
}

还有一個DetourCreateProcessWithDll函数,该函数是在以DLL注入方式拦截API时使用的,它其实就是封装“CreateProcess”,以“CREATE_SUSPEND”方式创建进程,然后修改IAT,把Detoured.dll和您的*.dll插入到它的导入表,然后再启动进程。所以它的参数就是在普通的CreateProcess基础上增加了两个DLL的路径参数,最后一个参数为创建进程的函数指针,默认为CreateProcessA,简单的说就是可以在创建进程的時候加载一個dll吧

示例代码:

#undef UNICODE
#include <cstdio>
#include <windows.h>
#include <detours\detours.h>
int main()
{
	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	ZeroMemory(&si, sizeof(STARTUPINFO));
	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
	si.cb = sizeof(STARTUPINFO);
	char* DirPath = new char[MAX_PATH];
	char* DLLPath = new char[MAX_PATH]; //testdll.dll
	char* DetourPath = new char[MAX_PATH]; //detoured.dll
	GetCurrentDirectory(MAX_PATH, DirPath);
	sprintf_s(DLLPath, MAX_PATH, "%s\\testdll.dll", DirPath);
	sprintf_s(DetourPath, MAX_PATH, "%s\\detoured.dll", DirPath);
	DetourCreateProcessWithDll(NULL, "C:\\windows\\notepad.exe",
	  NULL,NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL,&si, &pi, DetourPath, DLLPath, NULL);
	delete [] DirPath;
	delete [] DLLPath;
	delete [] DetourPath;
	return 0;
}

当我们需要hook的函数既不是一个标准的WIN32 API,也不是导出函数。这时我们需要把我们的程序和被所要注入的程序同时编译,或者,把函数的地址硬编码:

#undef UNICODE
#include <cstdio>
#include <windows.h>
#include <detours\detours.h>
typedef void (WINAPI *pFunc)(DWORD);
void WINAPI MyFunc(DWORD);
pFunc FuncToDetour = (pFunc)(0x0100347C); //Set it at address to detour in the process

INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)
{
	switch(Reason)
	{
	case DLL_PROCESS_ATTACH:
	    {
	        DisableThreadLibraryCalls(hDLL);
	        DetourTransactionBegin();
	        DetourUpdateThread(GetCurrentThread());
	        DetourAttach(&(PVOID&)FuncToDetour, MyFunc);
	        DetourTransactionCommit();
	    }
	    break;
	case DLL_PROCESS_DETACH:
	    DetourTransactionBegin();
	    DetourUpdateThread(GetCurrentThread());
	    DetourDetach(&(PVOID&)FuncToDetour, MyFunc);
	    DetourTransactionCommit();
	    break;
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	    break;
	}
	return TRUE;
}

void WINAPI MyFunc(DWORD someParameter)
{
	//Some magic can happen here
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值