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文件夾放到程序根目錄,不然須要給出絕對路徑。(儘量複製)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;
}
相關文章
相關標籤/搜索