首页
社区
课程
招聘
[原创]我第三题的分析过程
发表于: 2008-10-9 11:45 2875

[原创]我第三题的分析过程

2008-10-9 11:45
2875
看到这个题目,我以为我没有希望了! 我连MAP文件是什么都不知道`~~~~~~
Google了好久,让我找到了两篇文章,先分享给大家!

第一个是老罗的《仅通过崩溃地址找出源代码的出错行》
原文出处:http://www.luocong.com/articles/show_article.asp?Article_ID=29
第二个是在VC知识库找的名叫《对“仅通过崩溃地址找出源代码的出错行”一文的补充与改进》
地址我忘记了!


我不指望我能在本次比赛里得到什么奖项(就我这水平,想得估计也那个什么……),所以只是抱着能穴道东西的心态来参加的!到目前为止,我虽然没有得到什么分数,但是我学到了很多的东西!
第二题因为学校的事耽搁了,只分析了一半没能参加,这次第三题,不管对错,提交上来,对自己也算有个交代!

     盯着MAP文件瞅了半天,终于让我找到了下面这句!

 0001:0001fd20       ?OnBnClickedBtnCrash@CTestFloatDlg@@QAEXXZ 00420d20 f   TestFloatDlg.obj


     哈哈,是不是我运气太好了?我找到了OnBnClickedBtnCrash()这个函数,也就是我们看到的程序里面那个按钮的单击事件的响应程序啊~~~~
别的不说,先看一下代码先:

.text:00420D20         push    ebp
.text:00420D21         mov     ebp, esp
.text:00420D23         sub     esp, 94h
.text:00420D29         mov     eax, dword_429DA8
.text:00420D2E         xor     eax, ebp
.text:00420D30         mov     [ebp-0Ch], eax
.text:00420D33         mov     [ebp-94h], ecx
.text:00420D39         mov     ax, ds:word_425A30
.text:00420D3F         mov     [ebp-90h], ax
.text:00420D46         push    7Eh
.text:00420D48         push    0
.text:00420D4A         lea     ecx, [ebp-8Eh]
.text:00420D50         push    ecx
.text:00420D51         call    _memset			;清空缓冲区[ebp-90h]
.text:00420D56         add     esp, 0Ch
.text:00420D59         fld     ds:dbl_425DC0	;把ds:dbl_425DC0中的内容加载到ST0 valid 3.1415900000000000000
.text:00420D5F         fstp    qword ptr [ebp-8]      ;再保存到qword ptr [ebp-8] 里面去
.text:00420D62         fld     qword ptr [ebp-8]	;再加载到ST0里去
.text:00420D65         fadd    st, st	;将它们相加 ST0 valid 6.2831800000000000000
.text:00420D67         fstp    qword ptr [ebp-8]	;再保存到qword ptr [ebp-8] 里面去
.text:00420D6A         sub     esp, 8
.text:00420D6D         fld     qword ptr [ebp-8]
.text:00420D70         fstp    qword ptr [esp]  ;再保存到qword ptr [esp] 里面去
.text:00420D73         push    offset aPi2F    ; "PI * 2 = %f"
.text:00420D78         push    40h
.text:00420D7A         lea     edx, [ebp-90h]
.text:00420D80         push    edx
.text:00420D81         call    __snwprintf		;把aPi2F中的内容赋值到[ebp-90h]中去
.text:00420D86         add     esp, 14h
.text:00420D89         push    40h
.text:00420D8B         push    offset aTestfloag ; "TestFloag"
.text:00420D90         lea     eax, [ebp-90h]
.text:00420D96         push    eax
.text:00420D97         mov     ecx, [ebp-94h]
.text:00420D9D         call    sub_405C75		;查MAP文件得知,这个函数是:MessageBoxW@CWnd@@QAEHPB_W0I@Z
.text:00420DA2         mov     ecx, [ebp-0Ch]
.text:00420DA5         xor     ecx, ebp
.text:00420DA7         call    sub_40ECBD
.text:00420DAC         mov     esp, ebp
.text:00420DAE         pop     ebp
.text:00420DAF         retn

好了,我把注释也给加上了,到这里这个程序的功能我们就都清楚了:显示PI * 2 = 6.2831800000000000000!

虽然它的具体实现是有问题的,我不知道作者把结果放大ESP里是怎么个用法,但是我认为常规方法应该把算出来的浮点型的结果进行类型转换,弄成字符串型的,然后再进行赋值等操作等等!
但是不是我们要考虑的重点!

这次题目要求我们分析出异常的原因,我们分析一下它吧:
这个程序做了浮点运算,我们用OD跟一下,在走:
.text:00420D59         fld     ds:dbl_425DC0	;把ds:dbl_425DC0中的内容加载到ST0 valid 3.1415900000000000000
.text:00420D5F         fstp    qword ptr [ebp-8]      ;再保存到qword ptr [ebp-8] 里面去
.text:00420D62         fld     qword ptr [ebp-8]	;再加载到ST0里去
.text:00420D65         fadd    st, st	;将它们相加 ST0 valid 6.2831800000000000000
.text:00420D67         fstp    qword ptr [ebp-8]	;再保存到qword ptr [ebp-8] 里面去
.text:00420D6A         sub     esp, 8
.text:00420D6D         fld     qword ptr [ebp-8]
.text:00420D70         fstp    qword ptr [esp]  ;再保存到qword ptr [esp] 里面去

这些代码的时候都没有出过问题,而且,F8单步跟的结果都是正确的!
问题出在__snwprintf函数这里!而这个函数是字符串操作函数,不存在浮点类型运算!!!

那我们就可以得出结论了:问题就出在%f上了!
%f会被误认为是浮点型所以在执行 __snwprintf() 函数的时候要出问题,提示不支持家在浮点数库!

我给出的解决方法是:把小写的 %f 改写成大写的%F 即远地址调用字符串!

要去吃饭了,我就不写测试程序了(关键是不知道怎么写~)!我把给定的程序修改一下,再贴个图,发出来吧~~~~


希望我的分析是正确的!如果不对还望各位大大批评指正!

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

上传的附件:
收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 264
活跃值: (30)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
2
错误请抓紧时间重新考虑
2008-10-9 11:50
0
雪    币: 65
活跃值: (811)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
3
遵命!!!!!!!
2008-10-9 11:57
0
游客
登录 | 注册 方可回帖
返回
//