首页
论坛
课程
招聘
[原创]WinDBG插件编写介绍及在Nano Code中加载扩展
2021-8-9 18:26 3704

[原创]WinDBG插件编写介绍及在Nano Code中加载扩展

2021-8-9 18:26
3704

    穷理者,因其所已知而及其所未知,因其所已达而及其所未达。人之良知,本所固有。然不能穷理者,只是足于已知已达,而不能穷其未知未达,故见得一截,又不曾见得一截,此其所以于理未精也。然仍须功夫日日增加。今日既格得一物,明日又格得一物,工夫更不住地做。如左脚进得一步,右脚又进一步;右脚进得一步,左脚又进,接续不已,自然贯通。

    借钟馗与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文件(右键源文件=>添加=>新建项=>代码=>模块定义文件);如下图所示。


    在模块定义文件中编写下方代码。

  • 显然导出的函数为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


[2022冬季班]《安卓高级研修班(网课)》月薪三万班招生中~

最后于 2021-8-10 09:50 被birdring编辑 ,原因:
收藏
点赞2
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回