博 文
今天回复访客的留言变成了修改访客的留言,52rd的出来管管呀!同时,我也对不慎修改了留言的那位客人说声对不起,下次我一定注意看看是回复还是修改。
今天不小心又找到一个Bug。Bug的现象是当某项操作的进度执行到100%以后就会出现非法操作。通过反汇编非操报告的模块和地址,定位到一个消息处理函数中。分析这个函数源代码,判断是由于消息处理函数的第二个参数为空或者野指针造成。于是,在追查所有发送这个消息的函数后,定位到一个线程主函数return前的PostMessage()调用中。这里调用的PostMessage()在第二个参数中传递了一个结构给出现非操的那个消息处理函数,这个结构是一个局部变量,而没有想到就在紧接着的return以后,整个线程就将结束,线程中使用的局部变量将自动被释放,因此,造成消息处理函数获得了一个野指针,故而非法操作。
总结:在使用PostMessage()发送消息,并向消息处理函数传递指针或者引用结构的时候,请一定考虑结构或者指针指向的实例是否在消息处理函数执行时还有效,使用局部的结构作为消息参数传递,不小心就会出现这种野指针错误,而且不容易查明原因。因此,PostMessage()的参数尽可能避免使用局部的结构变量作为参数。
如果你的函数是一个递归函数,请一定注意节约使用局部变量。因为一个线程的堆栈是有限的,局部变量总是保存在线程堆栈里面,要等到函数返回时才会释放。在递归调用中,因为递归函数没有返回,局部变量也就不会释放,直到所有递归完成。因此,每递归一次,递归函数中的局部变量就会吞噬线程堆栈中的一段空间,当线程堆栈被吞噬完后,就会出现寄存器ebp的值归零或者异常,从而导致局部变量混乱而出现非法操作。因此,在递归函数中,如果需要声明一个上百字节的数组或者结构,最好采用new方式,这样局部变量就由数组或者结构变成了指针,从而也能增加递归的次数(深度),呵呵。
最近这段时间,因为AOL的案子Debug的事情比较多。今天又遇到一例局部变量混乱的问题。问题时这样的,某个AP级程序在执行几秒钟后就会非操,RD估计是发生在某个函数中。调试这个函数,发现局部变量File的值无故发生了变化,分析File变量的地址,该变量的地址发生了偏移(增大了1),因此,初步判断是由于堆栈(也就是寄存器ebp)的值发生了变化造成。下面就是需要找到ebp在什么时候变化的,特别要留意函数调用后ebp的值。果然在调用了R()函数后,ebp的值发生了变化。追踪进去,由于R()内部是一个大循环,因此不知道是循环了多少次以后造成了内存泄漏。于是在R函数中加入了如下代码:
//定义如下全局变量LPDWORD pEbp;DWORD dwEbp;int s;
//在函数的开始位置加入如下代码pEbp = (LPDWORD)&Param1; //获取函数第一个参数的地址pEbp -= 2; //函数第一个参数地址减去8个字节的位置通常用于保存调用者(函数)寄存器ebp值,具体位置可切换到汇编模式下查看便知dwEbp = *pEbp; //记录下这个ebp的值
//在怀疑内存泄露的地方加入以下代码if(dwEbp != *pEbp) s = 0;//检查函数保存的ebp值是否发生了变化,在这里设下调试断点,若发生了变化则在这里停下
通过上述方法检查函数保存寄存器ebp值的变化,测量出出现这个bug时的循环次数为0次,找到出现Bug的代码位置是在调用完一次DeviceIoControl()以后。原来函数中有这样定义和直接使用一个结构:struct{ LONGLONG V1; LONGLONG V2; char pBuf[32768];}Data;DeviceIoControl()中的参数就使用了Data这个结...
今天下班正准备回家,被一位同事叫住帮忙解决一个Driver蓝屏的Bug。初看起来蓝屏是出现在自己的Driver里面,并且Softice没有拦截到这个错误。用Windbg打开蓝屏的Dump文件,Windbg告知蓝屏出现在Driver的xxxx位置。然后在Softice中设置好Driver的源码文件,使用Softice的mod指令找到该Driver的基地址,蓝屏代码的位置应该就在基地址+xxxx的附近。使用u指令反汇编这个位置的代码,正好在一个名为BT_xxx()的函数中。在该函数的入口设下断点,然后试图重现这个蓝屏Bug。当Softice在断点位置停了下的时候开始单步跟踪。靠!原来是个除零错误。
总结一下:1、首先获得蓝屏的Dump文件。2、然后用Windbg查到蓝屏代码在Driver中的偏移地址。3、在Softice中设置好调试Driver的源码文件。4、然后使用Softice的mod指令找到调试Driver的基地址。造成蓝屏的代码位置应该就在 基地址+偏移地址附近。5、再使用Softice的u指令反汇编这个地址的代码,在怀疑的代码位置设下断点。6、下面开始重现蓝屏Bug,当Softice在断点位置停下来后,就开始单步调试。祝你好运!
常常听到和看到一些关于Blog的事情,一直都不以为然。前几天,公司让我分析如何解决Vista权限的UAP问题,苦于资料短缺,把我折腾了半天,最后没想到在一位微软RD的Blog上找到了答案,一下子激起了我Blog的热情。