Detours注入DLL钩子入门教程

本教程非常初级,适合新手食用        

开发环境,WIN10 64bit, VS2022

首先在GITHUB下载源码。GitHub - microsoft/Detours: Detours is a software package for monitoring and instrumenting API calls on Windows. It is distributed in source code form.Detours is a software package for monitoring and instrumenting API calls on Windows. It is distributed in source code form. - GitHub - microsoft/Detours: Detours is a software package for monitoring and instrumenting API calls on Windows. It is distributed in source code form.https://github.com/microsoft/detours

点击右侧

下载后解压到例如 E:\Detours-4.0.1

然后打开VS2022的自带命令行工具(如果要注入的目标为64请选择x64

在这里我需要对32位程序进行注入,所以我选择x86的命令提示工具

通过命令提示进入到E:\Detours-4.0.1 

输入nmake

等待编译完成

编译完成后在E:\Detours-4.0.1会得到3个文件夹

bin.X86里面是所有sample的编译后的文件。其中还有一个重要的setdll.exe工具

include是自己创建钩子dll时需要引用的头文件

lib.X86是Detours的本体静态链接库detours.lib

自此编译就OK了。

然后我们新建一个winform程序。

我习惯用C#作为win视图程序的语言,可以根据自己爱好选择例如MFC或者其他语言。

这里先用C#作为演示

创建好项目后在窗体上拖入一个button 控件,然后双击button进入到点击事件的代码逻辑

在中间写一个弹出窗口的代码即可。

 private void button1_Click(object sender, EventArgs e)
 {
  MessageBox.Show("窗口文字随便写");
 }

准备生成EXE文件,这里要注意,32位和64位不能混用,不然会注入失败。

我们上面选了32位,那么这个应用程序也必须是32位(x86)

按F5如果弹出一个框,选择

 禁用仅我的代码并继续

 点击按钮测试下弹窗是否正常。

然后到 我们项目的\bin\x86\Release\net6.0-windows

会看到我们生成的exe程序

=============================分割线==============================

然后重点来了,我们要开始做钩子DLL了。

此时偷懒的话,可以直接在刚才创建的项目里,在解决方案管理器树状目录的顶层右键

添加-新建项目选择C++动态链接库

注意这两个项目代码没有任何关联,只是我为了方便把两个项目放到一个解决方案里了。

默认生成的项目里有两个文件

1个是dllmain.cpp(DLL入口)

1个是pch.cpp(预编译头)

我们添加一个新的myhook.cpp文件到项目,内容如下

#include <Windows.h>
#include "detours.h"

//真实的调用函数,函数原型必须和真实API一致。部分类型如果无法声明可以用void *替代
static int (WINAPI* REALMessageBox) (HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) = MessageBox;
//伪造的调用函数,也就是我们的钩子,参数类型和返回值必须和真实的一样,
static int WINAPI MYMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) 
{
	//在这里可以任意发挥~~~
	//在函数末尾调用真正的API来返回
	return  REALMessageBox(NULL, L"MyHook!! MessageBoxCRACK!!", L"Please", MB_OK);
}

void StartHook()
{
	long err;
	DetourRestoreAfterWith();
	//开始事务
	DetourTransactionBegin();
	//更新线程信息  
	DetourUpdateThread(GetCurrentThread());
	//将拦截的函数附加到原函数的地址上
	DetourAttach(&(PVOID&)REALMessageBox, MYMessageBox);
	//结束事务
	err = DetourTransactionCommit();
}

//解除钩子
void EndHook()
{
	//开始事务
	DetourTransactionBegin();
	//更新线程信息 
	DetourUpdateThread(GetCurrentThread());
	//将拦截的函数从原函数的地址上解除
	DetourDetach(&(PVOID&)REALMessageBox, MYMessageBox);
	//结束事务
	DetourTransactionCommit();
}

此时提示一堆错误,因为我们没有把头文件导入进来。

去我们刚才生成的E:\Detours-4.0.1\include里将detours.h放到到项目根目录。

然后在解决方案资源管理器点击显示所有文件按钮,找到detours.h (有个红色的减号很明显)

右键——包括在项目。再点一下显示所有文件按钮。

此时错误全部消失。

这时我们还差一步: 在dllmain.cpp里调用StartHook函数

extern void StartHook();//新增

//新增一个导出函数,这个可以随便写,但必须至少有一个导出函数才能使用setdll远程注入
VOID __declspec(dllexport) test()
{
    OutputDebugString(L"__declspec(dllexport) test() \r\n");
}

{StartHook();} //新增

dllmain代码看起来应该是这样的。 

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include "framework.h"

extern void StartHook();//新增

//新增一个导出函数,这个可以随便写,但必须至少有一个导出函数才能使用setdll远程注入
VOID __declspec(dllexport) test()
{
	OutputDebugString(L"__declspec(dllexport) test() \r\n");
}

BOOL APIENTRY DllMain(HMODULE hModule,
	DWORD  ul_reason_for_call,
	LPVOID lpReserved
)
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	{StartHook();} //新增
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}

右键项目——生成。

如果出现  C1010    在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "pch.h"”?   

将这个头文件添加到相应CPP的文件头部即可

或者右键项目——属性——C/C++——预编译头——使用(/Yu)改为不使用预编译头

是不是非常简单!!!~

此时再生成,会出现一堆无法解析的外部符号。

是因为我们没有导入我们刚才nmake生成的detours.lib

将E:\Detours-4.0.1\lib.X86\detours.lib拷贝到项目根目录

右键项目添加现有项选择detours.lib。

再次生成。

生成OK

在输出控制台要记住我们生成的dll文件位置,因为我们下面要用到

===========================分割线又来了==================================

所有代码都编写完成后,我们需要将DLL注入到目标程序。

打开cmd进入到E:\Detours-4.0.1\bin.X86目录

setdll /?

 会打印出注入工具的帮助命令

开始注入:

在命令提示符里输入格式如下的命令

setdll /d:【自己的DLL】 【目标exe程序】

setdll /d:C:\Users\g\source\repos\LotTest\Release\lotDll.dll C:\Users\g\source\repos\LotTest\bin\x86\Release\net6.0-windows\LotTest.exe

应该会得到以下输出 

 再去执行窗口程序。

如果想要撤销注入

setdll /r C:\Users\g\source\repos\LotTest\bin\x86\Release\net6.0-windows\LotTest.exe 

 

写于2022年3月26日,CSDN博客。 

  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值