挖井

类库大魔王的挖井日记

挖一口属于自己的井


一次从栈中寻找被优化到寄存器中的局部变量指针的经历

  上周基本解决了一个dump文件分析的问题。
  一开始,问题没有弄复杂,只是从最后异常看到call stack,大体得出某个类的指针为NULL,却被继续使用,然后fix的话只要在被使用前判断一下是否不为NULL就行了。
  不过这个fix有一点没有考虑到,是该方法一开始就有一个分支对该指针进行了判断。所以如果该分支确实成立的话,我的fix就说明有问题了。于是新的问题就成了验证该分支的条件是否成立。
  分支的条件是判断另一个对象的每个成员是否为空。本来,这个对象一开始是new出来的,指针是某个方法的局部变量,一般说来是放在栈上的。不过通过call stack切换到那个方法的context后,发现查看局部变量并没有那个指针。通过查看反汇编的代码,才发现原来该指针被优化了,并不存储在栈上,而是存储在寄存器r13上了。于是我就开始想着如何可以查看某一级call stack时的寄存器,一开始我以为每次call指令时,会自动把所有寄存器的值都压栈的,后来发现不是,还特地去找了Intel的指令手册看了一下说明,反正没说有压栈寄存器,大概是我记错了。问了一下那个老外同事,他说没什么办法,只有想办法从栈里找。
  这样没头绪了几天,后来灵光一闪,偶尔发现在call stack中使用r13存储指针的方法的下一级被调用方法的反汇编代码中,把r13压栈了!于是只要在栈中就肯定能找到那个指针的值了。至于怎么找那个栈中的位置,从函数的返回地址找!从最后的esp值开始大地址(栈的生长方向是往小地址方向生长)开始搜索那一个方法的返回地址,找到后再往小地址找压入的栈的寄存器值,果然找到一个值,可以通过dt来查看,还可以通过dds该地址的vf-table来查看它的虚表包含的虚函数名称,这样就可以验证是否是要找的那个对象。果然没错!

本文地址:

https://minidump.info/blog/2012/04/e4-b8-80-e6-ac-a1-e4-bb-8e-e6-a0-88-e4-b8-ad-e5-af-bb-e6-89-be-e8-a2-ab-e4-bc-98-e5-8c-96-e5-88-b0-e5-af-84-e5-ad-98-e5-99-a8-e4-b8-ad-e7-9a-84-e5-b1-80-e9-83-a8-e5-8f-98-e9-87-8f-e6-8c-87-e9-92-88/

感觉本文不错,不妨小额鼓励我一下!
上一篇

最近过得很开心

  前天傍晚下班回来的路上被追尾了。因为车速比较快,前面的一辆的士突然停下载客,我就急刹车,差点点就要撞上前面的,我都感觉到我的车好像因为刹车踩得太猛而什么东西突然断裂了一样,但是后面另一辆的士就没刹住,撞上我了。看了一下,我只是后面有几条划痕,那的士是右大灯完全废了,都往里陷入了。我也懒得跟...…

KarenMeu 全文阅读
下一篇

好久没来写blog了

  这个月总的说来过得很开心,进展很大,当然前些天也一度出现很灭世的事,甚至为之放声大哭。  一个人的日子果然非常无趣,于是马上回到了用物质享受来麻痹精神的状态,买了一个BlackBerry的PlayBook,一个HP的TouchPad,总共花掉2600块钱,这个月就开销就这变大了。  之后一...…

Life mm 全文阅读