Detour的简单使用
Detours的安装:
下载部分:
1.直接在百度搜"detour",进对应的网站下载。
2.或以下链接
https://www.microsoft.com/en-us/research/project/detours/?from=http%3A%2F%2Fresearch.microsoft.com%2Fsn%2Fdetours
安装部分:
1.在对应的编译器找到终端。32位找到“VS2013 x86 本机工具命令提示”(本人的是VS2013),64位找到“VS2013 x64 本机工具命令提示”(注意:32或64是
指编译的程序,而不是操作系统)。
2.在上面的命令工具找到对应下载文件的路径,并在终端转到"Detours"文件夹下的"src"文件。如:D:\VS2013\VC\Detours\src。再一次输入"nmake"。
3.此时,已经完成编译了。可以在“Detour”的文件夹下出现“bin.X86”“include”“lib.X86”三个心文件夹。里面包含的就是可以直接导入的头文件和库文件。
注意点:
1.导入Detour时,需要导入头文件和库文件。
#include "../Detours/include/detours.h"
#pragma comment (lib,"../Detours/lib.X86/detours.lib")
本人已将编译好的Detour文件夹放到程序根目录,否则需要给出绝对路径。(尽可能复制)
2.要对挂钩函数进行保存。先定义一个函数指针保存要挂钩的函数,目的是为了最后的还原。
3.挂钩的函数一定要与原函数的原型一模一样(除函数名外)。包含返回值、参数类型。
4.挂钩的思路:
(1)找到要挂钩函数的原型,并提取出来。
(2)定义一个与函数原型一样的新函数。
(3)进行挂钩
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach();
DetourTransactionCommit();
(4)解除钩子
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach();
DetourTransactionCommit();
为什么使用DLL
1.扩展了应用程序的特性
2.简化了项目管理
3.节省内存
4.促进资源共享
5.促进本地化 本地有一个DLL不需要重复下载
6.解决各版本的差异
注意:
DLL与应用程序共享一个进程空间
在DLL中分配的内存必须由DLL来进行释放
应用程序不会因为DLL的卸载而释放空间
DLL与EXE的不同点:
1.生成的程序属性不同。
2.入口函数不同。DLL是DllMain()
源代码: #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <Windows.h> //包含Detour的头文件和库文件 #include "../Detours/include/detours.h" #pragma comment (lib,"../Detours/lib.X86/detours.lib") //保存函数原型 static int (WINAPI *OldMesssageBoxW)( _In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)=MessageBoxW; //改写函数 static int WINAPI NewMessageBoxW( _In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType) { return OldMesssageBoxW(NULL, L"new MessageBox", L"Please", MB_OK); } //开始下钩子 void StartHook() { //开始事务 DetourTransactionBegin(); //更新线程信息 DetourUpdateThread(GetCurrentThread()); //将拦截的函数附加到原函数的地址上 DetourAttach(&(PVOID&)OldMesssageBoxW, NewMessageBoxW); //结束事务 DetourTransactionCommit(); } //解除钩子 void EndHook() { //开始事务 DetourTransactionBegin(); //更新线程信息 DetourUpdateThread(GetCurrentThread()); //将拦截的函数从原函数的地址上解除 DetourDetach(&(PVOID&)OldMesssageBoxW, NewMessageBoxW); //结束事务 DetourTransactionCommit(); } int _tmain(int argc, _TCHAR* argv[]) { //应原样输出 MessageBoxW(NULL, L"old MessageBox", L"Please", MB_OK); //应改变输出 StartHook(); MessageBoxW(NULL, L"old MessageBox", L"Please", MB_OK); //应原样输出 EndHook(); MessageBoxW(NULL, L"old MessageBox", L"Please", MB_OK); system("pause"); return 0; }