-
-
[原创]WinDBG插件编写介绍及在Nano Code中加载扩展
-
2021-8-9 18:26 4977
-
穷理者,因其所已知而及其所未知,因其所已达而及其所未达。人之良知,本所固有。然不能穷理者,只是足于已知已达,而不能穷其未知未达,故见得一截,又不曾见得一截,此其所以于理未精也。然仍须功夫日日增加。今日既格得一物,明日又格得一物,工夫更不住地做。如左脚进得一步,右脚又进一步;右脚进得一步,左脚又进,接续不已,自然贯通。
借钟馗与GDK7之合力捉”鬼“,保佑代码平安顺利、风调雨顺,再无”鬼怪出现“。
Nano Code扩展说明
扩展也可以被称为是插件,通过DLL以导出函数的形式供调试器加载扩展;扩展用于实现用户自定义的功能,便于用户基于自己的调试需求去扩展调试功能。
无论是Nano Code还是WinDBG都拥有着丰富的扩展命令;但即使是这样,也难免也会有一些不足之处,让用户在调试过程中觉得现有的命令并不大够用,扩展也因此而出现。
Nano Code是一款功能强大的调试器,它兼容WinDBG;因此在WinDBG上可以使用的扩展在Nano Code上也可以照常使用。
在调试器中以!开头的命令就是扩展命令。
通过Dependence Walker来查看DLL的导出函数(以adp_ext.dll为例);如下图所示。
Nano Code与WinDBG
最近在使用GDK7+Nano Code进行调试,感受到了GDK7及Nano Code的强大功能(张银奎老师的NB),同时Nano Code还兼容WinDBG;尽管如此现有的命令仍然不大够使用,因此需要一些额外的扩展命令,因为Nano Code兼容WinDBG,因此就以WinDBG扩展编写为例,来写Nano Code的插件。
WinDBG扩展类型的简单介绍
WinDBG主要支持2种类型的扩展,分别是DBGEng类型的扩展及WDBGExts类型的扩展;当然也可以说是WinDBG提供了DBGEng的API接口及WDBGExts的API接口两种API接口类型供我们来调用,从而写出WinDBG扩展。
WDBGExts类型的扩展:调用在wdbgexts.h 中定义的 WinDBG 。
DBGEng类型的扩展:调用在dbgeng.h 中定义的Debugger Engine API 。
WinDBG任何1种类型的扩展编写都可以分成2个步骤,这2个步骤分别是生成动态链接库模块(DLL)及利用DLL的导出函数供WinDBG加载;在WinDBG完成加载以后,就可以使用扩展命令来
WinDBG扩展-Hello World的编写
打开Visual Studio创建一个动态链接库的新项目;如下图所示。
删除头文件及源文件中自带的文件。
复制inc文件夹下的dbgeng.h到项目文件夹下,在头文件内打开dbgeng.h(右键=>添加=>现有项=>dbgeng.h);如下图所示。
- Inc文件夹为WinDBG自带的文件夹;路径特征为Windows Kits\10\Debuggers\inc。
创建新的头文件(右键头文件=>添加=>新建项=>头文件);在头文件中编写下方代码。
这一种方法适用于编写WDBGExts类型的扩展;如果想要编写DNGEng类型的扩展,则还需要再#include <dbgeng.h>下面添加#pragma comment (lib ,"dbgeng.lib")。
#pragma once #include <dbgeng.h>
创建源代码文件(右键源文件=>添加=>新建项=>C++文件);如下图所示。
在C++文件中编写下方代码。
- DebugExtensionInitialize是我们需要导出的函数且此函数必须被导出,此函数含有2个参数,分别是Version(版本)及Flags(暂时不用)。
- 我们利用DEBUG_EXTENSION_VERSION设置高版本及低版本。
Test函数用于实现扩展命令(这个扩展命令就是输出一段文字,如同Hello World一样,非常简单);Release()用于释放API接口。
#include "Test.h" HRESULT CALLBACK DebugExtensionInitialize(PULONG Version, PULONG Flags) { *Version = DEBUG_EXTENSION_VERSION(1, 0); *Flags = 0; // 暂时不用 return S_OK; } HRESULT CALLBACK Test(PDEBUG_CLIENT pDebugClient, PCSTR args) { UNREFERENCED_PARAMETER(args); IDebugControl* pDebugControl; if (SUCCEEDED(pDebugClient->QueryInterface(__uuidof(IDebugControl4), (void **)&pDebugControl))) { pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "Hello Nano Code,Here is GDK7!!!"); pDebugControl->Release(); } return S_OK; }
创建def文件(右键源文件=>添加=>新建项=>代码=>模块定义文件);如下图所示。
- 用于指定所需导出的函数;在文章1中我们知道DLL通过导出函数供调试器加载扩展。
文章1链接:https://blog.csdn.net/birdring_0xx0/article/details/119424688
在模块定义文件中编写下方代码。
显然导出的函数为Test及DebugExtensionInitialize。
LIBRARY "Test" EXPORTS Test DebugExtensionInitialize
开始编译,等待编译成功;如下图所示。
- 如果编译时报错[在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加”#include “xxxx.h””],则应不使用预编译头(右键项目=>属性=>配置属性=>C/C++=>预编译头=>不使用预编译头)。
- 如果缺少头文件及静态链接库文件,则添加它们的路径到项目中(去WinDBG文件夹里面找,都是自带的文件)。
在Nano Code中载入Test.dll
进入Nano Code,启动内核调试,断下GDK7。
在命令行内输入.load Test.dll;如下图所示。
执行!Test;会输出如下内容。
[ndb]!Test !Test Hello Nano Code,Here is GDK7!!!
GDK7的介绍
GDK7通过专用调试电缆与调试目标进行连接,二者通过DCI协议进行通信,也不需要专用的ITP硬件就可以实现JTAG调试和系统追踪。
GDK7提供了一个完整的被调试目标系统,大大减少准备调试环境所需的时间,省去各种因为软件和硬件不兼容所带来的烦恼。
与传统的ITP/XDP硬件调试器相比,GDK7的传输速度高达5Gbps,比XDP和ITP提高了10倍还多;可以把GDK7中的数据实时传输到调试主机内,让全量分析多线程软件的执行轨迹成为可能,当然GDK7的强大功能不局限于此。
其他说明
若您有问题咨询及出现链接失效等其他情况请联系邮箱:birdring_NULL@outlook.com。
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。