首页
社区
课程
招聘
[原创]第一阶段第三题
发表于: 2008-10-8 14:15 2753

[原创]第一阶段第三题

2008-10-8 14:15
2753
首先说怎么找那个出错的地方

出错函数在_snwprintf()里面,用IDA看一下button的代码,然后下断点,跟一下就知道了

不多说了

下面是为什么会出错:

首先,自己写一个一摸一样的程序,见附件,然后编译,发现没有任何问题,OK,调自己的程序,和题目对比,发现在
_decode_pointer这个地方出错
正确的解出是下面函数
00413F51     |.  E8 A5EEFFFF   |call    _decode_pointer
00413F56     |.  59            |pop     ecx                                          ;  testfloa._cfltcvt_l
00413F57     |.  FFD0          |call    eax



而题目解不出,说明没有调用过_encode_pointer这个过程!

OK,重新载入自己的程序,对_encode_pointer下断点,发现testfloa._cfltcvt_l的时候返回看地方
00415E3C testfloa._initp_misc_cfltcvt_tab   /$  56            push    esi
00415E3D                                    |.  57            push    edi
00415E3E                                    |.  33FF          xor     edi, edi
00415E40                                    |>  8DB7 B0B04200 /lea     esi, dword ptr [edi+_cfltcvt_tab]
00415E46                                    |.  FF36          |push    dword ptr [esi]
00415E48                                    |.  E8 37CFFFFF   |call    _encode_pointer
00415E4D                                    |.  83C7 04       |add     edi, 4                                       ;  返回这里
00415E50                                    |.  83FF 28       |cmp     edi, 28
00415E53                                    |.  59            |pop     ecx
00415E54                                    |.  8906          |mov     dword ptr [esi], eax
00415E56                                    |.^ 72 E8         \jb      short 00415E40
00415E58                                    |.  5F            pop     edi
00415E59                                    |.  5E            pop     esi
00415E5A                                    \.  C3            retn



再返回
0040F6D8 testfloa._cinit                    /$  833D 44404200>cmp     dword ptr [_FPinit], 0
0040F6DF                                    |.  74 1A         je      short 0040F6FB
0040F6E1                                    |.  68 44404200   push    offset _FPinit
0040F6E6                                    |.  E8 F5670000   call    _IsNonwritableInCurrentImage
0040F6EB                                    |.  85C0          test    eax, eax
0040F6ED                                    |.  59            pop     ecx
0040F6EE                                    |.  74 0B         je      short 0040F6FB
0040F6F0                                    |.  FF7424 04     push    dword ptr [esp+4]
0040F6F4                                    |.  FF15 44404200 call    dword ptr [_FPinit]            ;  testfloa._fpmath
0040F6FA                                    |.  59            pop     ecx
0040F6FB                                    |>  E8 3C670000   call    _initp_misc_cfltcvt_tab
0040F700                                    |.  68 90244200   push    offset __xi_z                  ;  返回这里



然后开OD,载入题目有问题的程序,到相同位置比较一下,发现是一个地方验证没通过跳走了,没初始化

0040F6D8 testfloa._cinit                    /$  833D 44404200>cmp     dword ptr [_FPinit], 0
0040F6DF                                    |.  74 1A         je      short 0040F6FB
0040F6E1                                    |.  68 44404200   push    offset _FPinit
0040F6E6                                    |.  E8 F5670000   call    _IsNonwritableInCurrentImage
0040F6EB                                    |.  85C0          test    eax, eax
0040F6ED                                    |.  59            pop     ecx
0040F6EE                                    |.  74 0B         je      short 0040F6FB                 ;  这里跳走了
0040F6F0                                    |.  FF7424 04     push    dword ptr [esp+4]
0040F6F4                                    |.  FF15 44404200 call    dword ptr [_FPinit]            ;  testfloa._fpmath
0040F6FA                                    |.  59            pop     ecx
0040F6FB                                    |>  E8 3C670000   call    _initp_misc_cfltcvt_tab




问题就在上面一个call里面

OK,重新来,进call,发现在找到.rdata区段后验证这个区段是否可写

00415F33    .  50            push    eax
00415F34    .  68 00004000   push    00400000
00415F39    .  E8 52FFFFFF   call    _FindPESection
00415F3E    .  83C4 08       add     esp, 8                         ;  返回.rdata区段
00415F41    .  85C0          test    eax, eax
00415F43    .  74 3B         je      short 00415F80
00415F45    .  8B40 24       mov     eax, dword ptr [eax+24]        ;  区段属性
00415F48    .  C1E8 1F       shr     eax, 1F
00415F4B    .  F7D0          not     eax                            ;  这里判断区段是否可写:含有0x80000000属性
00415F4D    .  83E0 01       and     eax, 1                         ;  不含有就是1,即不可写



OK,那么看一下有问题的exe,发现.rdata属性是 0xC0000040,可写,改成0x40000040,保存,运行正常

最后,我列举几个原因,我理解中,评委要的根本原因应该是

.rdata区段属性可写

不知道对不对,如果不对,我再加几个

_snwprintf函数出错
浮点支持库未加载

解决方案:
.rdata改成不可写即可

好了,详细文档,根本原因,修复方法都有了

不知道评委还有什么问题

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

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 264
活跃值: (30)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
2
结果提交时间 2 小时 15 分钟
结果提交时间长度 = 135 分钟
结果提交次数 = 1
结果提交为根本原因
得分 = [(2880 - 135)/2880]^1/5 x 1.0 x 100 - (1 -1 ) x 5 = 99.04
2008-10-14 16:04
0
游客
登录 | 注册 方可回帖
返回
//