<格蠹汇编>_第13章_SDK安装程序卡壳之谜

上调试器

         利用~*e ? @$tid;!gle命令,去显示进程中每个线程的TID和LastError值。其中~*查看所有线程,e选项是支持多条命令,不然只是显示最后一条。@$tid显示tid,!gle:显示LastError。

         LastErrorValue,最后一次错误码,是一个很小的数,LastStatusValue,最后一次系统状态码,是一个很大的数。一般的,调用系统服务失败,会把状态码传递给RtlNtStatusToError函数,在函数内部修改LastStatusValue,然后将LastStatusValue转化为LastErrorValue。

细看14d8线程

         在windbg,切换线程使用~ 线程序号 s。如果需要使用TID切换线程,可以使用~~ TID s

细看现场

         对于某些.NET托管代码,windbg由于没有私有符号,所以在栈回溯的时候没有办法显示名称,使用SOS扩展模块可以解析托管代码。

         使用.loadby sos mscorwks加载模块,使用!clrstack回溯栈,发现WinIoError函数,说明出现异常,产生异常的是该函数的下面一个函数。

         使用!thread命令查看线程信息,可以发现存在一次异常信息。异常名称的后面显示的是异常对象的地址。利用!do [异常对象地址]可以查看异常的详细信息。或者使用!Printexception打印所有异常。

追本溯源

         判断某个函数的父函数,可以利用函数的返回地址是否在父函数内部来判断。