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文件夾放到程序根目錄,不然須要給出絕對路徑。(儘量複製)spa
2.要對掛鉤函數進行保存。先定義一個函數指針保存要掛鉤的函數,目的是爲了最後的還原。操作系統
3.掛鉤的函數必定要與原函數的原型如出一轍(除函數名外)。包含返回值、參數類型。線程
4.掛鉤的思路:
(1)找到要掛鉤函數的原型,並提取出來。
(2)定義一個與函數原型同樣的新函數。
(3)進行掛鉤
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());指針
DetourAttach();code
DetourTransactionCommit();
(4)解除鉤子
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());blog
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()); //將攔截的函數附加到原函數的地址上 DetourDatach(&(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; }