概述
Windbg脚本和扩展工具开篇
好长一段时间没写文章了,最近一直忙于为项目的可调式性做一些脚本和扩展工具,鉴于对windbg强大威力的震撼,以及相对较少的资料,笔者决定写一系列关于如何开发Windbg脚本和扩展命令的文章,您的支持是我最大的动力,希望本系列文章对您有所帮助。
那么一个完整的windbg script是什么样子的呢?首先让我们看如下示例:
$$ 该脚本是列出用户进程和栈
r $t0 = nt!PsActiveProcessHead
. for (r $t1 = poi(@$t0); (@$t1 != 0) & (@$t1 != @$t0); r $t1 = poi(@$t1))
{
r? $t2 = #CONTAINING_RECORD(@$t1, nt!_EPROCESS, ActiveProcessLinks);
.process @$t2
.reload
!process @$t2
}
. for (r $t1 = poi(@$t0); (@$t1 != 0) & (@$t1 != @$t0); r $t1 = poi(@$t1))
{
r? $t2 = #CONTAINING_RECORD(@$t1, nt!_EPROCESS, ActiveProcessLinks);
.process @$t2
.reload
!process @$t2
}
相对于Windbg脚本,windbg扩展比较复杂,而且通常需要花费更大的精力写出同样的功能,但是它带来的一个好处就是你可以获得更多的功能,你甚至可以通过这些扩展写一个调试器,那么一个完整的windbg扩展又是什么样子的呢?该扩展dll打印出一个全局字符串的值。
以C++语言编写的windbg扩展示例:
HRESULT CALLBACK
PrintPTR(PDEBUG_CLIENT pDebugClient, PCSTR args)
{
UNREFERENCED_PARAMETER(args);
IDebugSymbols* pDebugSymbols;
if (SUCCEEDED(pDebugClient->QueryInterface(__uuidof(IDebugSymbols), ( void **)&pDebugSymbols)))
{ // Resolve the symbol
ULONG64 ulAddress = 0;
if (SUCCEEDED(pDebugSymbols->GetOffsetByName( " TestSTLMap!g_wString ", &ulAddress)))
{
IDebugDataSpaces* pDebugDataSpaces;
if (SUCCEEDED(pDebugClient->QueryInterface(__uuidof(IDebugDataSpaces), ( void **)&pDebugDataSpaces)))
{ // Read the value of the pointer from the target address space
ULONG64 ulPtr = 0;
if (SUCCEEDED(pDebugDataSpaces->ReadPointersVirtual( 1, ulAddress, &ulPtr)))
{
PDEBUG_CONTROL pDebugControl;
if (SUCCEEDED(pDebugClient->QueryInterface(__uuidof(IDebugControl), ( void **)&pDebugControl)))
{ // Output the values
pDebugControl->Output(DEBUG_OUTPUT_NORMAL, " %p TestSTLMap!g_wString= 0x%pn ", ulAddress, ulPtr);
pDebugControl->Output(DEBUG_OUTPUT_NORMAL, " %mun ", ulPtr);
pDebugControl->Release();
}
}
pDebugDataSpaces->Release();
}
pDebugSymbols->Release();
}
}
return S_OK;
}
PrintPTR(PDEBUG_CLIENT pDebugClient, PCSTR args)
{
UNREFERENCED_PARAMETER(args);
IDebugSymbols* pDebugSymbols;
if (SUCCEEDED(pDebugClient->QueryInterface(__uuidof(IDebugSymbols), ( void **)&pDebugSymbols)))
{ // Resolve the symbol
ULONG64 ulAddress = 0;
if (SUCCEEDED(pDebugSymbols->GetOffsetByName( " TestSTLMap!g_wString ", &ulAddress)))
{
IDebugDataSpaces* pDebugDataSpaces;
if (SUCCEEDED(pDebugClient->QueryInterface(__uuidof(IDebugDataSpaces), ( void **)&pDebugDataSpaces)))
{ // Read the value of the pointer from the target address space
ULONG64 ulPtr = 0;
if (SUCCEEDED(pDebugDataSpaces->ReadPointersVirtual( 1, ulAddress, &ulPtr)))
{
PDEBUG_CONTROL pDebugControl;
if (SUCCEEDED(pDebugClient->QueryInterface(__uuidof(IDebugControl), ( void **)&pDebugControl)))
{ // Output the values
pDebugControl->Output(DEBUG_OUTPUT_NORMAL, " %p TestSTLMap!g_wString= 0x%pn ", ulAddress, ulPtr);
pDebugControl->Output(DEBUG_OUTPUT_NORMAL, " %mun ", ulPtr);
pDebugControl->Release();
}
}
pDebugDataSpaces->Release();
}
pDebugSymbols->Release();
}
}
return S_OK;
}
总结
基于笔者的研究发现,国内做相关研究的人并不多,其实国外也就几个业内比较牛的人做的相对比较好,但是这些工具的作用足以让你震撼,今天开个头,有兴趣的朋友可以继续关注后续文章。
转载于:https://www.cnblogs.com/pugang/archive/2012/11/30/2796617.html
最后
以上就是傻傻猎豹为你收集整理的Windbg脚本和扩展工具开篇的全部内容,希望文章能够帮你解决Windbg脚本和扩展工具开篇所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复