bester 发表于 2019-8-18 18:38

Detour hook 4.0库安装使用以及原理详解

Detour hook库是经过微软认证的一个开源HOOK库,今天找资料发现了这个东西,特来体验一下,弄了很久找了很多资料才弄好,大部分都是教使用,没有教怎么一步一步安装,另外我只成功了X86的LIB生成,X64的不会,有会的可以回帖

首先先打开GitBub地址:https://github.com/Microsoft/Detours

进去以找到一个绿绿的按钮,上面写着clone or download,如果找不到 请在浏览器ctrl+F 查找这3个单词

下载完以后得到Detours-master文件夹,然后放到VS的安装目录,比如我的VS2015是放在D:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe

那么我就将文件放在D:\Program Files (x86)\Microsoft Visual Studio 14.0\

这个时候打开


我的VS只有这个,没有别的教程中的X64位,导致我只能生成X86版本,另外用CMD和PowerShell都无法生成,只能用这个,有会的大佬可以教一下

打开以后输入pushd D:\Program Files (x86)\Microsoft Visual Studio 14.0\Detours-master
按一下回车

再输入 nmake

再按一下回车
这个时候会在目录下多出3个文件夹


这个时候新建一个WIN32控制台,我实在不明白为什么C++会区分MFC项目和Win32项目,两个合为一个不好么?

然后记下我们的项目地址是C:\Users\Administrator\Documents\Visual Studio 2015\Projects\ConsoleApplication1,因为我名字取的是ConsoleApplication1,所以就是这个文件夹
然后就是空项目


这个时候就点完成,然后把我们的三个文件夹复制到这个C:\Users\Administrator\Documents\Visual Studio 2015\Projects\ConsoleApplication1项目地址
然后在头文件这里--右键---添加--现有项

导入我们include文件夹中的3个头文件,有多少个就添加多少个,我这里是三个


然后在我们的源文件这里--右键--新建项--C++文件,用来写我们自己的代码


然后在源CPP文件中写代码
#include <iostream>//添加这个头文件,用来在控制台显示内容,也就是cout的头文件
#include <Windows.h>//这个是windows库,可以调用API
#include "../include/detours.h"//这个就是加载当前工程目录下的include文件夹中的detours.h头文件,这里是声明,注意的是一定要用/符号不能用\符号表示目录文件夹,因为\后面的字符会被转义
using namespace std; //使用std空间,因为cout就是在这个命名空间里面
#pragma comment(lib, "../lib.X86/detours.lib") //这个就是加载lib静态库,这里应该是实现,至少我是这么理解,声明在头文件,实现在lib库,不对请指正

static int (WINAPI *OldMessageBoxW)(HWND, LPCWSTR, LPCWSTR, UINT) = MessageBoxW;//这里是声明一个API函数,不是很能理解为什么要加static,然后写法是如此的,看不懂

int WINAPI NewMessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)//这个就好理解了,这个是我们自定义的API函数,然后他把第二个参数的内容修改成了“经过修改的MessageBox”
{
        return OldMessageBoxW(hWnd, L"经过修改的MessageBox", lpCaption, uType);   //这里就是调用了,因为从HOOK的API头跳到我们自定义的函数头,总不能什么都不干吧?所以要调用他
}

void Hook()    //这里是HOOK的实现,反正不是很能看得懂
{
        int error = DetourTransactionBegin();
        if (error != NO_ERROR)
        {
                cout << ("DetourTransactionBegin Error\r\n");
        }
        error = DetourUpdateThread(GetCurrentThread());
        if (error != NO_ERROR)
        {
                cout << ("DetourUpdateThread Error\r\n");
        }
        error = DetourAttach(&(PVOID&)OldMessageBoxW, NewMessageBoxW);
        if (error != NO_ERROR)
        {
                cout << ("DetourAttach Error\r\n");
        }
        error = DetourTransactionCommit();
        if (error != NO_ERROR)
        {
                cout << ("DetourTransactionCommit Error\r\n");
        }
}

int main()   //Main 函数不用多解释了吧?程序运行必经之路
{
        MessageBoxW(nullptr, L"Test", L"Tips", MB_OK);//先未HOOK调用,发现是正常的提示test
        Hook();//然后调用HOOK函数
        MessageBoxW(nullptr, L"Test", L"Tips", MB_OK);//接着再调用一次,发现内容有所变化

        system("pause");//让控制台窗口暂停,否则会一闪而过看不到任何内容哟
        return 0;
}


然后我们在OD中,看一下他的实现,分析一下原理,找到main函数

然后F2下断后F9运行,F8往下走

然后我们看分析

F7跟进这个call,发现将API头部的5个字节改了

继续F8跟着走

重点是这个call里面的内容

最后我们看这个JMP跳转的位置


这下原理就明白了,他首先把参数推栈,接着call调用补码,最后跳回到未修改的第6个字节的地址这个位置,因为前5个字节已经被破坏了,思路还是很不错的,跳到原函数执行完毕以后的代码就是处理堆栈了。

优点:免去频繁挂钩导致安全以及效率问题,我们传统的inline hook是跳到我们自定义的函数当中,还需要先把5个字节恢复才能调用API,这个的话是不需要的恢复的,因为他在自定义函数当中已经补码过了。
缺点:容易被检测挂钩,没有恢复,这个其实算小问题,可以自己脱钩的,我想应该提供了脱钩函数,虽然我不知道怎么用。

bester 发表于 2019-8-19 11:13

本帖最后由 bester 于 2019-8-19 11:21 编辑

加油 发表于 2019-8-18 23:01
造轮子浪费时间。
如果你会,那么用库,如果你不会,轮子给你你也走不起来,就像CPU,我们都能买国外的,为什么要自己花钱自研?买不就完了吗?你再去问问真正的大佬,他们会不会只用库?脱离库会不会自己写?

bester 发表于 2019-9-2 21:00

qing666888 发表于 2019-8-19 15:23
参考我转载的那篇csdn文章,文章开头有我编译好的x32 x64版本的下载地址。

没有看到你转载的文章呀,可否给个链接哦

bester 发表于 2019-8-18 18:43

参考图文:https://blog.csdn.net/qing666888/article/details/81540683

佚丶名 发表于 2019-8-18 18:48

学习了 下载下来试试看

加油 发表于 2019-8-18 18:49

2019想想 发表于 2019-8-18 19:03

学习了。谢谢!

315215 发表于 2019-8-18 20:36

厉害了,我的国

bester 发表于 2019-8-18 21:01

加油 发表于 2019-8-18 18:49
库掌握越多 感觉越来越象易语言的模块了那样方便使用了。

我的建议是不用库,自己写。

gavinfeng 发表于 2019-8-18 21:12

学习了。。。。

Norton 发表于 2019-8-18 21:32

不错,挺详细的。

加油 发表于 2019-8-18 23:01

页: [1] 2
查看完整版本: Detour hook 4.0库安装使用以及原理详解