首页
社区
课程
招聘
[原创]第一轮第三题答案
2008-10-8 14:00 2593

[原创]第一轮第三题答案

2008-10-8 14:00
2593
收藏
点赞0
打赏
分享
最新回复 (2)
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
shoooo 16 2008-10-8 14:12
2
0
1. 结果
00413DFD     8D45 88           lea eax,dword ptr ss:[ebp-78]
00413E00     56                push esi
00413E01     50                push eax
00413E02     FF35 C8A04200     push dword ptr ds:[42A0C8]
00413E08     E8 3FEFFFFF       call <TestFloa.__decode_pointer           0>
00413E0D     59                pop ecx
00413E0E     FFD0              call eax

_decode_pointer对42A0C8解码后,call eax, 进入_amsg_exit 后crash了
问题出在42A0C8, 看它的上下文
0042A0A8  6E 40 73 74 64 40 40 00 04 43 17 9B 04 43 17 9B
0042A0B8  04 43 17 9B 04 43 17 9B 04 43 17 9B 04 43 17 9B
0042A0C8  04 43 17 9B 04 43 17 9B 04 43 17 9B 04 43 17 9B


发现都是9B174304(每次是不同的固定值), 直觉告诉我, 这个加码的表有问题

2. 自己写程序
我自己写了一个浮点的程序, 在相同的位置,也找到了同样的表,但是我的程序表中的每个dword值是不同的, 为什么不同呢, 我对它们下写断点的, 在初始化的时候,看到了
类似
00431DC0 test._cfltcvt_init     55                push ebp
00431DC1                        8BEC              mov ebp,esp
00431DC3                        C705 E8F14900 0BF>mov dword ptr ds:[_cfltcvt_tab],test.0042F90B
00431DCD                        C705 ECF14900 E0F>mov dword ptr ds:[49F1EC],test.0042F6E0
00431DD7                        C705 F0F14900 BA0>mov dword ptr ds:[49F1F0],test.004303BA
00431DE1                        C705 F4F14900 51F>mov dword ptr ds:[49F1F4],test.0042FE51
00431DEB                        C705 F8F14900 99F>mov dword ptr ds:[49F1F8],test.0042FC99
00431DF5                        C705 FCF14900 0BF>mov dword ptr ds:[49F1FC],test.0042F90B
00431DFF                        C705 00F24900 9AF>mov dword ptr ds:[49F200],test.0042F19A
00431E09                        C705 04F24900 830>mov dword ptr ds:[49F204],test.00430383
00431E13                        C705 08F24900 B9F>mov dword ptr ds:[49F208],test.0042F5B9
00431E1D                        C705 0CF24900 DF0>mov dword ptr ds:[49F20C],test.004301DF
00431E27                        5D                pop ebp                                                 ; 0012FF4C
00431E28                        C3                retn

这样的函数, 很明显,题目中的程序没有调这样的函数

3.比较分析
经过一层层对照的分析, 发现了这个关键点
0040F621     68 5C404200       push TestFloa.0042405C
0040F626     E8 65670000       call <TestFloa.__IsNonwritableInCurrentImage >
0040F62B     85C0              test eax,eax
0040F62D     59                pop ecx                                       ; TestFloa.0040EBD8
0040F62E     74 0B             je short TestFloa.0040F63B
0040F630     FF7424 04         push dword ptr ss:[esp+4]
0040F634     FF15 5C404200     call dword ptr ds:[42405C]                    ; <TestFloa.__fpmath                   00411e26 f   libcmt:fpinit.obj>


题目中的程序_IsNonwritableInCurrentImage返回后,je跳转满足了,因此没有进入fpmath函数, 而我自己写的程序je没有满足,执行了fpmath函数

4.起因
知道为什么了,于是就看_IsNonwritableInCurrentImage函数了
关键就是这里了
00415DE9     E8 52FFFFFF       call <TestFloa.__FindPESection            004>
00415DEE     83C4 08           add esp,8
00415DF1     85C0              test eax,eax
00415DF3     74 3B             je short TestFloa.00415E30
00415DF5     8B40 24           mov eax,dword ptr ds:[eax+24]
00415DF8     C1E8 1F           shr eax,1F
00415DFB     F7D0              not eax
00415DFD     83E0 01           and eax,1

这里是取出.rdata段的属性,然后检查0xC0000000位,于是发现题目中这个位是1, 我自己写的程序,这个位是0

5. 结论
从这个题目中, 大概的结论是
程序初始化的时候,会通过_FPinit的对象来找到它所在的段,一般是.rdata段,然后去查这个段的属性, 如果标记为不可写,那么去执行fpmath函数来进行一些浮点运算的初始化,如果可写,那么不执行那个函数。而那个函数所做的初始化,正好是我们_snwprintf中所用到的
雪    币: 264
活跃值: (30)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
kangaroo 6 2008-10-9 12:58
3
0
结果提交时间 2 小时 0 分钟
结果提交时间长度 = 120 分钟
结果提交次数 = 1
结果提交为根本原因
得分 = [(2880 - 120)/2880]^1/5 x 1.0 x 100 - (1 -1 ) x 5 = 99.15
游客
登录 | 注册 方可回帖
返回