! For_each_function был и глючит
он требует приватных pdbs
, если вы используете недокументированный ключ -f, чтобы заставить его использовать publi c pdbs
, он будет зависать бесконечно до тех пор, пока вы не завершите windbg
при анализе полной строки из вывода .foreach будет PITA
, в основном имена функций могут содержать пробелы
.foreach и считает, что каждый пробел является разделителем, поэтому он будет отбираться имя функции в нескольких токенах
, и .foreach не поддерживает ctrl + c или ctrl + break или alt + delete, поэтому он будет продолжать извергать яд до тех пор, пока не умрет
, если вы можете используйте последнюю версию windbg, я бы посоветовал вам переключиться на javascript, или natvis
ниже - это вывод, использующий только dx, оценщик выражений natvis
выполнит команду и получит массив результатов в uservariable
dx @$foo = Debugger.Utility.Control.ExecuteCommand("x /1 calc!*")
некоторые примеры элементов указанного массива (обратите внимание, что в последней записи ниже много пробелов и
.foreach разрезает его на столько частей, сколько sp aces)
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