首页
社区
课程
招聘
[原创]第一阶段第三题
2008-10-9 01:52 2538

[原创]第一阶段第三题

2008-10-9 01:52
2538
1.在出错的对话框弹出的时候暂时,看堆栈可以看到0013F348   0013F828  UNICODE "PI * 2 = ",于是找到:
00420D20 >/.  55            push    ebp
00420D21  |.  8BEC          mov     ebp, esp
00420D23  |.  81EC 94000000 sub     esp, 94
....

2.这些代码继续跟:
00413E00  |.  56            |push    esi
00413E01  |.  50            |push    eax
00413E02  |.  FF35 C8A04200 |push    dword ptr [42A0C8]
00413E08  |.  E8 3FEFFFFF   |call    <__decode_pointer           004>
00413E0D  |.  59            |pop     ecx
00413E0E  |.  FFD0          |call    eax

发现是这些代码导致的错误,把[42A0C8]里的东西解密(__decode_pointer调用了DecodePointer)一下然后调用
call eax通过动态方式调用了0041AE1F <Test.__fptrap>函数,而经过再三考虑这个是必经之路,说明[42A0C8]里的东西应该是关键。肯定有操作[42A0C8]这个地址的代码

3.写OD脚本把代码段找了一下(因为OPCODE里一定有42A0C8),一共3处:
temp: 00411DFF   --------->写入值
00411DFD                         |.  C705 C8A04200>mov     dword ptr [42A0C8], <__cfltcvt_l     >
temp: 00413E04         --------->读取值(在格式化字符串的时候被调用了)
temp: 0041678A         --------->读取值(根本没人调用它)
基本调用关系OD可以分析出来

4.再次运行程序试着在执行call eax的时候把将__cfltcvt_l的地址给eax,竟然成功了!!!
那00411DFF这个地址是一定要执行的。可能还有其它的问题,因为这里有一些解密操作。

但是在00411DFF附近下断点并没有断下,看函数名是_fmath调过来的,而看调用最终到了:
0040F618 <Test.__cinit          >/$  833D 5C404200>cmp     dword ptr [42405C], 0
0040F61F                         |.  74 1A         je      short 0040F63B
0040F621                         |.  68 5C404200   push    0042405C
0040F626                         |.  E8 65670000   call    <__IsNonwritableInCurrentIma>
0040F62B                         |.  85C0          test    eax, eax
0040F62D                         |.  59            pop     ecx
0040F62E                         |.  74 0B         je      short 0040F63B
0040F630                         |.  FF7424 04     push    dword ptr [esp+4]
0040F634                         |.  FF15 5C404200 call    dword ptr [42405C]           ;  <Test.__fpmath                   00411e26 f   libcmt:fpinit.obj>
0040F63A                         |.  59            pop     ecx
0040F63B                         |>  E8 AC660000   call    <__initp_misc_cfltcvt_tab   >
而__cinit这个函数是程序初始化时调用的,最后发现关键跳在
0040F62E                         |.  74 0B         je      short 0040F63B只要把它nop掉一切OK。
发现call    <__IsNonwritableInCurrentImage>会访问PE头的节表第二个节的描述符判断是否是可写的。如果是可写的返回0,只读的返回1。

查了一下PE头原来.rdata节不是只读的。用LordPE修改一下。
OK!

5.回过头来再看一下加解密部分:
在[42A0C8]下内存读写断点可以跟到在:00415CEC <Test.__initp_misc_cfltcvt_tab   >/$  56            push    esi
00415CED                                   |.  57            push    edi
00415CEE                                   |.  33FF          xor     edi, edi
00415CF0                                   |>  8DB7 B0A04200 /lea     esi, dword ptr [edi+42A0B0]
00415CF6                                   |.  FF36          |push    dword ptr [esi]
00415CF8                                   |.  E8 D8CFFFFF   |call    <__encode_pointer           00412cd5>
00415CFD                                   |.  83C7 04       |add     edi, 4
00415D00                                   |.  83FF 28       |cmp     edi, 28
00415D03                                   |.  59            |pop     ecx
00415D04                                   |.  8906          |mov     dword ptr [esi], eax
00415D06                                   |.^ 72 E8         \jb      short 00415CF0
00415D08                                   |.  5F            pop     edi
00415D09                                   |.  5E            pop     esi
00415D0A                                   \.  C3            retn

__encode_pointer这个函数里调用的EncodePointer加密

这个函数里对一张地址表做了加密(包括42A0C8)其实这个函数就是在紧接着初始化之后就调用了。
后面就是每用一次里面的函数指针就解密一次。

根本原因在于.rdata的PE头属性为只读,初始化的时候并没有初始化地址表。

附OD脚本:

var temp
mov temp, 00401000

start:
find temp, #C8A042#
cmp $RESULT, 0
je Exit0
mov temp, $RESULT
log temp
inc temp
cmp $RESULT, 00422000
jb start

Exit0:
ret

[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (1)
雪    币: 264
活跃值: (30)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
kangaroo 6 2008-10-9 12:51
2
0
结果提交时间 13 小时 52 分钟
结果提交时间长度 = 832 分钟
结果提交次数 = 1
结果提交为根本原因
得分 = [(2880 - 832)/2880]^1/5 x 1.0 x 100 - (1 -1 ) x 5 = 93.41
游客
登录 | 注册 方可回帖
返回