-
-
[原创]第一阶段第三题答案
-
发表于:
2008-10-8 20:21
3011
-
不知道我的答案符不符合题目要求,如果有不符合的地方我会改的,谢谢
跟踪过程:
OD加载,运行程序,Crash弹框,F12中断进程,查看调用堆栈,发现有“OnBnClicked”字样,应该就是单击按钮这个事件的处理函数。还有“__snwprintf”这个函数,一般这个函数都比较喜欢出错误。
偶是小白,不懂特别的技巧,只F8、F7地一遍一遍地跟,最终发现41AE1F那个地方有一个__amsg_exit,应该是错误信息对话框的开始,按我的理解是错误已经发生了。而会去到这个地址是因为412DAE那个CALL产生的,这个CALL调用了RtDecodePointer。
DecodePointer只是负责解码出一个指针,在413E02可以看到传给它的函数放在42A0C8。给42A0C8下硬件写断点。发现415D04在向它写数据。然后在415CF0发现这个地址是保存在42A0B0。又对42A0B0下写断点,发现它未被写入就已经EncodePointer了,即是说程序开始默认的值就是会弹错误框的。
42A0B0应该在程序的某个地方被修改,而又为什么没有被修改呢?我在这里被卡了很久,什么地方会修改42A0B0嘛?真不知道。
后来去了吃饭,吃完饭回来打开OD,发现42A0B0与42A0D7都被赋了同一个初始值,应该是一个数组,数组一般都是在首地址来定位的,于是在代码段中搜索“42A0B0”这个常量,哈哈,果然在411DCB这个地方找到了修改它的内容的指令。在这里下断点,重新运行程序,果然没被断下来。接下来应该解决为什么程序没有运行到这里的问题。
出错函数:
从411DCB开始,根据跳转不断向前找,发现40F626那里有一个
__IsNonwritableInCurrentImage这样的函数,很可疑,而如果它返回0,则40F62E会跳走,42A0B0就不能被修改了。传给它的参数42405C,此时它所在段的属性是可写的。所以这个函数返回了0。
出错原因分析:
简单分析一下__IsNonwritableInCurrentImage就可以发现,
是因为42405C所在的.rdata数据段具有可写属性,致使__IsNonwritableInCurrentImage返回了0,40F62F处发生了跳转,最终使411DCB没有被执行,而发生了错误。
修复方法:
综上所述,有两种修复方法,一是把40F62E那里的je指令NOP掉;二是去掉.rdata的只读属性。我觉得第二种方法好一点,因为.rdata本来就是只读数据段,所以我的答案是
去掉.rdata的只读属性。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!