首页
社区
课程
招聘
[原创]第一阶段第三题答案
发表于: 2008-10-8 20:21 3011

[原创]第一阶段第三题答案

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的只读属性

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 377
活跃值: (432)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
我一时手快打错字了,修复方法应该是去掉.rdata的可写属性
这样应该不算第二次提交吧?
2008-10-8 20:25
0
雪    币: 264
活跃值: (30)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
3
不算,原因找到就是正确 !!
2008-10-9 13:02
0
雪    币: 264
活跃值: (30)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
4
结果提交时间 8 小时 21 分钟
结果提交时间长度 = 501 分钟
结果提交次数 = 1
结果提交为根本原因
得分 = [(2880 - 501)/2880]^1/5 x 1.0 x 100 - (1 -1 ) x 5 = 96.25
2008-10-9 13:03
0
游客
登录 | 注册 方可回帖
返回
//