Windbg 从 .foreach 值解析变量
Windbg parse variable from .foreach value
正在 WinDbg 中执行下一个命令
.foreach (function_name {x /1 JittyProject!*}) {.echo function_name}
结果应该是
JittyProject!ApplyAsync
....
是否有可能以某种方式从一个变量 JittyProject
中的 function_name
解析到另一个 ApplyAsync
!for_each_function 过去和现在都是越野车
它需要私有 pdbs
如果您使用未记录的 -f 开关强制它使用 public pdbs
它将无限期挂起,直到您终止 windbg
从 .foreach 输出中解析完整的字符串是 PITA
基本上函数名可以而且确实包含 spaces
.foreach 将每个 space 视为分隔符
所以它会把一个函数名分成多个标记
并且 .foreach 不支持 ctrl+c 或 ctrl+break 或 alt+delete 因此它将继续喷出毒液直到它死去
如果你可以使用最新的 windbg,我建议你切换到 javascript 或 natvis
下面是仅使用 dx natvis 表达式计算器的输出
执行命令并将结果数组获取到用户变量中
dx @$foo = Debugger.Utility.Control.ExecuteCommand("x /1 calc!*")
上面数组的一些示例成员(注意下面的最后一个条目有很多 space 和
.foreach 会将其切成 spaces )
0:000> dx -r0 @$foo[4]
@$foo[4] : calc!CContainer::ToggleHistoryFunc
0:000> dx -r0 @$foo[101]
@$foo[101] : calc!`ATL::CAtlRECharTraitsW::GetAbbrevs'::`2'::s_szAbbrevs
0:000> dx -r0 @$foo[861]
@$foo[861] : calc!ATL::AtlAdd<unsigned int>
0:000> dx -r0 @$foo[1684]
@$foo[1684] : calc!ATL::CAtlMap<ATL::CStringT<unsigned short,ATL::StrTraitATL<unsigned short,ATL::ChTraitsCRT<unsigned short> > > *,FORMULA_DEFINTION *,MyCStringPtrTrait,ATL::CElementTraits<FORMULA_DEFINTION *> >::GetKeyAt
数组中有 2925 或 0xb6d 个函数
0:000> dx @$foo.Count(),x; dx @$foo.Count(),d
@$foo.Count(),x : 0xb6d
@$foo.Count(),d : 2925
0:000> dx -r0 @$foo[2925]
Error: <Unable to get error code text> (0x8000000b) <<< out of bounds
0:000> dx -r0 @$foo[2924]
@$foo[2924] : calc!Gdiplus::Image::`vector deleting destructor'
现在你有了一个数组,你可以使用 !作为分隔符
0:000> dx -r1 @$foo.Select(p=> new{ Module = p.Substring(0,p.IndexOf("!")), FName = p.Substring(p.IndexOf("!")) })[2924]
@$foo.Select(p=> new{ Module = p.Substring(0,p.IndexOf("!")), FName = p.Substring(p.IndexOf("!")) })[2924]
Module : calc
FName : !Gdiplus::Image::`vector deleting destructor'
0:000> dx -r1 @$foo.Select(p=> new{ Module = p.Substring(0,p.IndexOf("!")), FName = p.Substring(p.IndexOf("!")) })[864]
@$foo.Select(p=> new{ Module = p.Substring(0,p.IndexOf("!")), FName = p.Substring(p.IndexOf("!")) })[864]
Module : calc
FName : !_real
0:000> dx -r1 @$foo.Select(p=> new{ Module = p.Substring(0,p.IndexOf("!")), FName = p.Substring(p.IndexOf("!")) })[1684]
@$foo.Select(p=> new{ Module = p.Substring(0,p.IndexOf("!")), FName = p.Substring(p.IndexOf("!")) })[1684]
Module : calc
FName : !ATL::CAtlMap<ATL::CStringT<unsigned short,ATL::StrTraitATL<unsigned short,ATL::ChTraitsCRT<unsigned short> > > *,FORMULA_DEFINTION *,MyCStringPtrTrait,ATL::CElementTraits<FORMULA_DEFINTION *> >::GetKeyAt
或从所有加载的模块中获取所有函数名称
0:000> dx @$foo = Debugger.Utility.Control.ExecuteCommand("x /1 *!*")
0:000> dx @$foo.Count()
@$foo.Count() : 0x1d4b9
0:000> dx -r1 @$foo.Select(p=> new{ Module = p.Substring(0,p.IndexOf("!")), FName = p.Substring(p.IndexOf("!")+1) })[15084]
Module : COMCTL32
FName : CCalendar::_DateSetMax
这个包含 11993 个函数的庞大数组的模块
0:000> dx -r1 @$foo.Select(p=>p.Substring(0,p.IndexOf("!"))).Distinct()
@$foo.Select(p=>p.Substring(0,p.IndexOf("!"))).Distinct()
[0x0] : SharedUserData
[0x1] : calc
[0x2] : WINMM
[0x3] : gdiplus
[0x4] : UxTheme
[0x5] : COMCTL32
[0x6] : VERSION
[0x7] : KERNELBASE
[0x8] : msvcrt
[0x9] : GDI32
[0xa] : USER32
[0xb] : LPK
[0xc] : OLEAUT32
[0xd] : ADVAPI32
[0xe] : SHLWAPI
[0xf] : USP10
[0x10] : SHELL32
[0x11] : RPCRT4
[0x12] : kernel32
[0x13] : ole32
[0x14] : ntdll
[0x15] : sechost
正在 WinDbg 中执行下一个命令
.foreach (function_name {x /1 JittyProject!*}) {.echo function_name}
结果应该是
JittyProject!ApplyAsync
....
是否有可能以某种方式从一个变量 JittyProject
中的 function_name
解析到另一个 ApplyAsync
!for_each_function 过去和现在都是越野车
它需要私有 pdbs
如果您使用未记录的 -f 开关强制它使用 public pdbs
它将无限期挂起,直到您终止 windbg
从 .foreach 输出中解析完整的字符串是 PITA
基本上函数名可以而且确实包含 spaces
.foreach 将每个 space 视为分隔符
所以它会把一个函数名分成多个标记
并且 .foreach 不支持 ctrl+c 或 ctrl+break 或 alt+delete 因此它将继续喷出毒液直到它死去
如果你可以使用最新的 windbg,我建议你切换到 javascript 或 natvis
下面是仅使用 dx natvis 表达式计算器的输出
执行命令并将结果数组获取到用户变量中
dx @$foo = Debugger.Utility.Control.ExecuteCommand("x /1 calc!*")
上面数组的一些示例成员(注意下面的最后一个条目有很多 space 和
.foreach 会将其切成 spaces )
0:000> dx -r0 @$foo[4]
@$foo[4] : calc!CContainer::ToggleHistoryFunc
0:000> dx -r0 @$foo[101]
@$foo[101] : calc!`ATL::CAtlRECharTraitsW::GetAbbrevs'::`2'::s_szAbbrevs
0:000> dx -r0 @$foo[861]
@$foo[861] : calc!ATL::AtlAdd<unsigned int>
0:000> dx -r0 @$foo[1684]
@$foo[1684] : calc!ATL::CAtlMap<ATL::CStringT<unsigned short,ATL::StrTraitATL<unsigned short,ATL::ChTraitsCRT<unsigned short> > > *,FORMULA_DEFINTION *,MyCStringPtrTrait,ATL::CElementTraits<FORMULA_DEFINTION *> >::GetKeyAt
数组中有 2925 或 0xb6d 个函数
0:000> dx @$foo.Count(),x; dx @$foo.Count(),d
@$foo.Count(),x : 0xb6d
@$foo.Count(),d : 2925
0:000> dx -r0 @$foo[2925]
Error: <Unable to get error code text> (0x8000000b) <<< out of bounds
0:000> dx -r0 @$foo[2924]
@$foo[2924] : calc!Gdiplus::Image::`vector deleting destructor'
现在你有了一个数组,你可以使用 !作为分隔符
0:000> dx -r1 @$foo.Select(p=> new{ Module = p.Substring(0,p.IndexOf("!")), FName = p.Substring(p.IndexOf("!")) })[2924]
@$foo.Select(p=> new{ Module = p.Substring(0,p.IndexOf("!")), FName = p.Substring(p.IndexOf("!")) })[2924]
Module : calc
FName : !Gdiplus::Image::`vector deleting destructor'
0:000> dx -r1 @$foo.Select(p=> new{ Module = p.Substring(0,p.IndexOf("!")), FName = p.Substring(p.IndexOf("!")) })[864]
@$foo.Select(p=> new{ Module = p.Substring(0,p.IndexOf("!")), FName = p.Substring(p.IndexOf("!")) })[864]
Module : calc
FName : !_real
0:000> dx -r1 @$foo.Select(p=> new{ Module = p.Substring(0,p.IndexOf("!")), FName = p.Substring(p.IndexOf("!")) })[1684]
@$foo.Select(p=> new{ Module = p.Substring(0,p.IndexOf("!")), FName = p.Substring(p.IndexOf("!")) })[1684]
Module : calc
FName : !ATL::CAtlMap<ATL::CStringT<unsigned short,ATL::StrTraitATL<unsigned short,ATL::ChTraitsCRT<unsigned short> > > *,FORMULA_DEFINTION *,MyCStringPtrTrait,ATL::CElementTraits<FORMULA_DEFINTION *> >::GetKeyAt
或从所有加载的模块中获取所有函数名称
0:000> dx @$foo = Debugger.Utility.Control.ExecuteCommand("x /1 *!*")
0:000> dx @$foo.Count()
@$foo.Count() : 0x1d4b9
0:000> dx -r1 @$foo.Select(p=> new{ Module = p.Substring(0,p.IndexOf("!")), FName = p.Substring(p.IndexOf("!")+1) })[15084]
Module : COMCTL32
FName : CCalendar::_DateSetMax
这个包含 11993 个函数的庞大数组的模块
0:000> dx -r1 @$foo.Select(p=>p.Substring(0,p.IndexOf("!"))).Distinct()
@$foo.Select(p=>p.Substring(0,p.IndexOf("!"))).Distinct()
[0x0] : SharedUserData
[0x1] : calc
[0x2] : WINMM
[0x3] : gdiplus
[0x4] : UxTheme
[0x5] : COMCTL32
[0x6] : VERSION
[0x7] : KERNELBASE
[0x8] : msvcrt
[0x9] : GDI32
[0xa] : USER32
[0xb] : LPK
[0xc] : OLEAUT32
[0xd] : ADVAPI32
[0xe] : SHLWAPI
[0xf] : USP10
[0x10] : SHELL32
[0x11] : RPCRT4
[0x12] : kernel32
[0x13] : ole32
[0x14] : ntdll
[0x15] : sechost