【逆向知识】开发WinDBG扩展DLL
如何开发WinDbg扩展DLL
WinDbg扩展DLL是一组导出的回调函数,用于实现用户定义的命令。以便从内存转储中提取特定的信息。扩展dll由调试器引擎加载,可以在执行用户模式或内核模式调试时提供自动化任务的扩展功能。扩展DLL可以导出任意数量用于执行扩展命令的函数。每个函数都被显式地声明为DLL定义文件中的导出函数,.def文件和函数名必须是小写字母。
WinDbg(DbgEng)扩展DLL必须导出DebugExtensionInitialize。 这将在DLL加载时调用,以便于初始化DLL。 它可能被DLL用来初始化全局变量。
扩展DLL导出的可选函数DebugExtensionUninitialize。如果导出这个函数,那么卸载扩展时将调用这个DebugExtensionUninitialize 函数。
扩展DLL导出的DebugExtensionNotify函数。如果导出这个函数将会在会话开始或结束时调用,当目标开始或停止执行时。这些通知还提供给在客户端注册的IDebugEventCallbacks对象。
扩展DLL可以导出KnownStructOutput。如果导出这个函数将会在加载DLL时调用它。该函数返回在一行上打印的结构列表。稍后可以调用它来格式化这些结构的实例以便打印。
开发自己的Windbg扩展DLL,可以按照以下步骤:
- 1.下载并安装Windows的调试工具
http://www.microsoft.com/whdc/devtools/debugging/installx86.Mspx
- 2.使用VS 2008创建“Win32 Console Application”
- 3.选择应用程序类型为“DLL”,然后单击“完成”

图1
- 4.在项目中添加一个名为“wdbrowser”的“Module-Definition File (.def) ”。 导出扩展功能的一种方法是在.def文件的EXPORTS部分中指定函数名称。 也可以使用其他方式导出函数,如__dllexport

图2
5.将“Additional include Directories”配置为指向Windbg附带的头文件的目录。 x86的默认文件夹路径是“C:\Program Files\Debugging Tools for Windows (x86)\sdk\inc”
注:include Directories指include 目录
6.将“Additional Library Directories” 配置为指向Windbg附带库文件的目录。x86库文件的默认文件夹路径是:"C:\Program Files\Debugging Tools for Windows (x86)\sdk\lib\i386″
注:Library Directories指Library 目录
7.“dbgeng.lib ” & “dbgeng.dll” 具有实现调试引擎输出的功能。所以需要添加“dbgeng.lib ”到附加依赖项里
8.添加在步骤#3中创建的模块定义文件名称“wdbrowser.def”

9.在“stdafx.h”中包含以下所需的头文件
#include <windows.h>
#include <imagehlp.h>
#include <wdbgexts.h>
#include <dbgeng.h>
#include <extsfns.h>
10.声明以下两个全局变量
//Version.
EXT_API_VERSION g_ExtApiVersion = {1,1,EXT_API_VERSION_NUMBER,0} ;
WINDBG_EXTENSION_APIS ExtensionApis = {0};
- 11.声明以下调试引擎COM接口指针。
IDebugAdvanced2* gAdvancedDebug2=NULL;
IDebugControl4* gDebugControl4=NULL;
IDebugControl* gExecuteCmd=NULL;
IDebugClient* gDebugClient=NULL;
12.下一步是在DLL Main实现源文件中声明和实现WinDbgExtensionDllInit函数。 在这个例子中是“wdbrowser.cpp”。 WinDbgExntensionDllInit是第一个将被windbg调用的函数。 所以这个函数是空闲的,用于实现任何扩展特定的初始化或相关功能。
有关此功能的更多详细信息,请参阅http://msdn.microsoft.com/en-us/library/cc267872.aspx。
VOID WDBGAPI WinDbgExtensionDllInit (PWINDBG_EXTENSION_APIS lpExtensionApis, USHORT usMajorVersion, USHORT usMinorVersion)
{
ExtensionApis = *lpExtensionApis;
HRESULT hResult = S_FALSE;
if (hResult = DebugCreate(__uuidof(IDebugClient), (void**) &gDebugClient) != S_OK)
{
dprintf(“Acuqiring IDebugClient* Failled\n\n”);
return;
}
if (hResult = gDebugClient->QueryInterface(__uuidof(IDebugControl), (void**) &gExecuteCmd) != S_OK)
{
dprintf(“Acuqiring IDebugControl* Failled\n\n”);
return;
}
if (hResult = gDebugClient->QueryInterface(__uuidof(IDebugAdvanced2), (void**) &gAdvancedDebug2) != S_OK)
{
dprintf(“Acuqiring IDebugAdvanced2* Failled\n\n”);
return;
}
if (hResult = gDebugClient->QueryInterface(__uuidof(IDebugControl4), (void**) &gDebugControl4) != S_OK)
{
dprintf(“Acuqiring IDebugControl4* Failled\n\n”);
return;
}
}
13.声明另一个导出的函数ExtensionApiVersion,向windbg报告扩展版本。
有关此函数的详细信息,请参见http://msdn.microsoft.com/en-us/library/cc267873.aspx。
LPEXT_API_VERSION WDBGAPI ExtensionApiVersion (void)
{
return &g_ExtApiVersion;
}
- 14.定义调试引擎的接口指针,以便扩展模块可以与调试引擎交互。更多信息请参考
http://msdn.microsoft.com/en-us/library/cc265976.aspx – IDebugClient, http://msdn.microsoft.com/en-us/library/cc266102.aspx – IDebugControl
http://msdn.microsoft.com/en-us/library/cc265957.aspx – IDebugAdvanced
IDebugAdvanced2* gAdvancedDebug2=NULL;
IDebugControl4* gDebugControl4=NULL;
IDebugControl* gExecuteCmd=NULL;
IDebugClient* gDebugClient=NULL;
- 下一步是实现调试引擎的回调接口IDebugOutputCallbacks。调试引擎回调IDebugOutCallbacks::Output()的实现,输出扩展函数执行命令后的结果。
有关idebugoutput回调的详细信息,请参见http://msdn.microsoft.com/en-us/library/cc265716.aspx::Output()
- 16.在继承idebugoutputcallback接口的头文件中添加以下新类。
#ifndef __OUT_HPP__
#define __OUT_HPP__
#include <string>
#include <sstream>
class StdioOutputCallbacks : public IDebugOutputCallbacks
{
private:
std::string m_OutputBuffer;
//
//This buffer holds the output from the command execution.
//
CHAR m_OutPutBuffer[4096];
public:
void InitOutPutBuffer();
std::string GetOutputBuffer()
{
return m_OutputBuffer;
};
void ClearOutPutBuffer()
{
m_OutputBuffer = “”;
};
STDMETHOD(QueryInterface)(
THIS_
IN REFIID InterfaceId,
OUT PVOID* Interface
);
STDMETHOD_(ULONG, AddRef)(
THIS
);
STDMETHOD_(ULONG, Release)(
THIS
);
// IDebugOutputCallbacks.
STDMETHOD(Output)(
THIS_
IN ULONG Mask,
IN PCSTR Text
);
};
extern StdioOutputCallbacks g_OutputCb;
#endif // #ifndef __OUT_HPP__
- 17.添加实现IDebugOutputCallbacks接口方法的代码,特别是Output()
#include “stdafx.h”
#include <stdio.h>
#include <windows.h>
#include <dbgeng.h>
#include “OutputCallBack.h”
StdioOutputCallbacks g_OutputCb;
STDMETHODIMP
StdioOutputCallbacks::QueryInterface(
THIS_
IN REFIID InterfaceId,
OUT PVOID* Interface
)
{
*Interface = NULL;
if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) ||
IsEqualIID(InterfaceId, __uuidof(IDebugOutputCallbacks)))
{
*Interface = (IDebugOutputCallbacks *)this;
AddRef();
return S_OK;
}
else
{
return E_NOINTERFACE;
}
}
STDMETHODIMP_(ULONG)
StdioOutputCallbacks::AddRef(
THIS
)
{
// This class is designed to be static so
// there’s no true refcount.
return 1;
}
STDMETHODIMP_(ULONG)
StdioOutputCallbacks::Release(
THIS
)
{
// This class is designed to be static so
// there’s no true refcount.
return 0;
}
STDMETHODIMP
StdioOutputCallbacks::Output(
THIS_
IN ULONG Mask,
IN PCSTR Text
)
{
UNREFERENCED_PARAMETER(Mask);
m_OutputBuffer += Text;
return S_OK;
}
void StdioOutputCallbacks::InitOutPutBuffer()
{
m_OutputBuffer.erase();
}
- 18.添加扩展函数的实现。在本例我们实现了一个扩展,该扩展显示当前线程第2帧中的变量名和类型。实现代码:
DECLARE_API (dvf3)
{
//
// Install output callbacks.
//
if ((gDebugClient->SetOutputCallbacks((PDEBUG_OUTPUT_CALLBACKS) &g_OutputCb))!= S_OK)
{
dprintf(“*****Error while installing Outputcallback.*****\n\n”);
return;
}
//
// Since frame count starts from 0 index, we have to pass 2 as parameter for .frame command for the frame# 2
//
//Execute command to extrac 2nd frame.
if (gExecuteCmd->Execute(DEBUG_OUTCTL_THIS_CLIENT | //Send output to only outputcallbacks
DEBUG_OUTCTL_OVERRIDE_MASK |
DEBUG_OUTCTL_NOT_LOGGED,
“.frame 2”,
DEBUG_EXECUTE_DEFAULT ) != S_OK)
{
dprintf(“Executing .frame 2 failled\n”);
return;
}
//Execute command to extrac 2nd frame.
if (gExecuteCmd->Execute(DEBUG_OUTCTL_THIS_CLIENT | //Send output to only outputcallbacks
DEBUG_OUTCTL_OVERRIDE_MASK |
DEBUG_OUTCTL_NOT_LOGGED,
“dv /i /t /v”,
DEBUG_EXECUTE_DEFAULT ) != S_OK)
{
dprintf(“Executing dv /i /t /v failled\n”);
return;
}
dprintf(“***** Extracting locals & formal params from frame 2 *****”);
dprintf(“\n%s\n”, g_OutputCb.GetOutputBuffer().c_str());
}
- 19.重建项目。将. dll从发布文件夹中复制到Windbg查找扩展dll的文件夹中。
在x86机器上,默认目录为“<Drive letter>\Program Files\ debug Tools for Windows (x86)\winext”。
- 20.扩展已经准备好用于使用或测试。
- 21.启动windbg并打开一个完整的用户模式转储。输入.load myextension和hit enter,将扩展DLL加载到Windbg进程空间中。

22.运行.chain命令来验证是否由WinDbg加载扩展。如果扩展被加载,将看到类似于下面输出的内容。
23.输入!dvf3以运行扩展函数,用于从框架2中提取和显示变量名。

【逆向知识】开发WinDBG扩展DLL的更多相关文章
- windows下开发PHP扩展dll(无需Cygwin)
windows下开发php扩展网上很多资料都说需要Cygwin,其实完全可以不必安装该东东.没错,是可以在linux下生成骨架后拷到windos下来用,但是,如果没有linux环境呢?什么,装虚拟机? ...
- VS 2013驱动开发 + Windbg + VM双机调试(亲测+详解)
------------VS 2013驱动开发 + Windbg + VM双机调试(亲测+详解)------------- WIN10已上线,随之而来的是VS2015:微软在 "WDK760 ...
- 手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单
手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单 手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单 手把手教你开发Chrome扩 ...
- php 扩展dll
一.准备工作: 注:php5.2没有vc9,php5.3.php5.4没有vc6.呵呵.PHP5.5开始,不支持xp和win2003了,更是vc11了.--------------->所以,扩展 ...
- Windbg扩展的一些参考文章
Windbg脚本和扩展工具开篇http://www.cnblogs.com/pugang/archive/2012/11/30/2796617.html WinDbg简单扩展DLL http://ww ...
- 逆向知识之CS辅助/外挂专题.2.实现CS1.6透视原理
逆向知识之CS辅助/外挂专题.2.实现CS1.6透视原理 一丶透视简介 我们涉及到FPS游戏.免不了说透视.自瞄什么的. 在CS1.6中. 有OpenGl.也有D3D. 透视的方法很多. gl透视(也 ...
- 手把手教你开发chrome扩展
转载:http://www.cnblogs.com/walkingp/archive/2011/04/04/2003875.html 手把手教你开发chrome扩展一:开发Chrome Extenst ...
- 手把手教你开发Chrome扩展三:关于本地存储数据
手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单 手把手教你开发Chrome扩展二:为html添加行为 手把手教你开发Chrome扩展三:关于本地存储数据 HTML5 ...
- 手把手教你开发Chrome扩展二:为html添加行为
手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单 手把手教你开发Chrome扩展二:为html添加行为 手把手教你开发Chrome扩展三:关于本地存储数据 上一节我们 ...
随机推荐
- 将javaweb项目部署到阿里云服务器
主要步骤:1. 购买阿里云服务器2. 远程连接3. 在云服务器上配javaweb环境:jdk,tomcat,MySQL4. 将项目的war文件放到Tomcat下关于云服务器ECS:如果还想在买服务器之 ...
- Visual Categorization with Bags of Keypoints
1.Introduction and backgrounds 作为本周的论文之一,这是一篇bag of features的基本文章之一,主要了解其中的基本思路,以及用到的基本技术,尽量使得细节更加清楚 ...
- PGM学习之七 MRF,马尔科夫随机场
之前自己做实验也用过MRF(Markov Random Filed,马尔科夫随机场),基本原理理解,但是很多细节的地方都不求甚解.恰好趁学习PGM的时间,整理一下在机器视觉与图像分析领域的MRF的相关 ...
- BZOJ5302 HAOI2018奇怪的背包(动态规划)
由裴蜀定理,子集S有解当且仅当gcd(S,P)|w. 一个显然的dp是设f[i][j]为前i个数gcd为j的选取方案.注意到这里的gcd一定是P的约数,所以状态数是n√P的.然后可以通过这个得到gcd ...
- [洛谷P4091][HEOI2016/TJOI2016]求和
题目大意:给你$n(n\leqslant10^5)$,求:$$\sum\limits_{i=0}^n\sum\limits_{j=0}^i\begin{Bmatrix}i\\j\end{Bmatrix ...
- Tomcat8.0配置JNDI多数据源
jndi配置 :此种配置需要在Tomcat的server.xml中和context.xml中配置数据源,在项目中引用. 需要在tomcat下加入数据库连接的jar包,相关包(ojdbc14;c3p0数 ...
- Jump Game - LeetCode
目录 题目链接 注意点 解法 小结 题目链接 Jump Game - LeetCode 注意点 解法 解法一:贪心算法,只关注能到达最远距离,如果能到达的最远距离大于结尾说明能到达,否则不能.并且如果 ...
- 移动端图片轮播—swipe滑动插件
swipe是一个轻量级的移动滑动组件,它可以支持精确的触滑移动操作,能解决移动端对滑动的需求. swipe插件的使用主要有四大块: 一.html <div id='slider' class=' ...
- 解题:CQOI 2015 选数
题面 神仙题,不需要反演 首先上下界同时除以$k$,转换成取$n$个$gcd$为$1$的数的方案数,其中上界向下取整,下界向上取整 然后设$f[i]$表示选$n$个互不相同的数$gcd$为$i$的方案 ...
- bzoj 1406
%%% PoPoQQQ x^2=kn+1 x^2-1=kn (x+1)(x-1)=kn 令x+1=k1*n1,x-1=k2*n2,其中k1k2=k,n1n2=n 因此我们可以枚举n的约数中所有大于等于 ...