姚小宝 发表于 2019-8-14 13:29

2019xman个人晋级赛之little-unpack




逆向题有点坑,这道看到后边时间有点紧,看不下去,有点可惜。

题目

一打开数据混乱,应该是加壳了。



直接在seg022段下断点,动态调试。
运行如下代码段。
seg024:000000000060309D cmp   rax, rcx
seg024:00000000006030A0 jnz   short near ptr loc_6030A4+1
seg024:00000000006030A2 jz      short near ptr loc_6030A4+1

发现解密循环判断,判断是否解密完。rax是段的起始地址,也就是0x400850,rcx代表段尾。

解密完之后进入代码段之间还有一个反调试。
libc_2.24.so:00007FBF48D4E344 mov   , eax
libc_2.24.so:00007FBF48D4E346 jz      short loc_7FBF48D4E354
libc_2.24.so:00007FBF48D4E348 xor   edx, edx
libc_2.24.so:00007FBF48D4E34A xor   esi, esi
libc_2.24.so:00007FBF48D4E34C mov   rdi, r9
libc_2.24.so:00007FBF48D4E34F call    near ptr __cxa_atexit
手动修改寄存器的值跳过。

进入核心段之后发现


造成这种原因为因为代码段中插入了很多0xE8数据,手段修改,得到。




虽然还有很多花指令在其中,但已经不影响阅读。

其中还有一些反调试,可以手动去掉、

程序大概流程是输入明文,经过des加密对比、

这是key的赋值
.text:00000000004009FC mov   qword ptr , 0
.text:0000000000400A05 mov   byte ptr , 31h
.text:0000000000400A0A mov   byte ptr , 32h
.text:0000000000400A0F mov   byte ptr , 33h
.text:0000000000400A14 mov   byte ptr , 34h
.text:0000000000400A19 mov   byte ptr , 35h
.text:0000000000400A1E mov   byte ptr , 36h
.text:0000000000400A23 mov   byte ptr , 37h
.text:0000000000400A28 mov   byte ptr , 38h

即key=12345678

加密后,密文的对比方式
.text:0000000000400BE5 loc_400BE5:                           ; CODE XREF: .text:0000000000400BDF↑j
.text:0000000000400BE5 pop   rax
.text:0000000000400BE6 pop   rax
.text:0000000000400BE7 mov   edx,
.text:0000000000400BEE mov   eax,
.text:0000000000400BF5 mov   ecx, edx
.text:0000000000400BF7 sub   ecx, eax
.text:0000000000400BF9 cmp   ecx, 55F8FD5Bh
.text:0000000000400BFF jz      loc_400CA6


.text:0000000000400CA6 loc_400CA6:                           ; CODE XREF: .text:0000000000400BFF↑j
.text:0000000000400CA6 mov   ecx,
.text:0000000000400CAD mov   esi,
.text:0000000000400CB4 mov   edi, ecx
.text:0000000000400CB6 sub   edi, esi
.text:0000000000400CB8 cmp   edi, 3C763966h
.text:0000000000400CBE jnz   loc_400C05
.text:0000000000400CC4 imul    rax, rcx
.text:0000000000400CC8 mov   rcx, 13069E5EF81C51D0h
.text:0000000000400CD2 cmp   rax, rcx
.text:0000000000400CD5 jnz   loc_400C05
.text:0000000000400CDB imul    rdx, rsi
.text:0000000000400CDF mov   rax, 16DE11EA08E740B7h
.text:0000000000400CE9 cmp   rdx, rax
.text:0000000000400CEC jnz   loc_400C05
.text:0000000000400CF2 jnz   short near ptr loc_400CF6+1
.text:0000000000400CF4 jz      short near ptr loc_400CF6+1



one - tow = 0x55F8FD5B
three - four = 0x3C763966

tow * three = 0x13069E5EF81C51D0
one * four = 0x16DE11EA08E740B7

直接写脚本解
from z3 import *


x = Solver()

flag =

x.add(flag>0)

x.add(flag>0)

x.add(flag>0)

x.add(flag>0)


x.add(flag-flag==0x55F8FD5B)

x.add(flag-flag==0x3C763966)

x.add((flag*flag)==0x13069E5EF81C51D0)

x.add((flag*flag)==0x16DE11EA08E740B7)

print x.check()

print x.model()

得到
[flag1 = 780944752,
flag3 = 741130309,
flag0 = 2223325899,
flag2 = 1755511211]

根据大端小端,得到密文
cb42858470458c2eabf9a26845c02c2c

此时还是解不开。后面发现是字秘钥处理方式被改了。


就是生成16组字秘钥之后,再将每一组以64位操作下循环左移5位。

在标准的des代码中加入
        for (count = 0; count < 16; count++)
        {
                temps = sub_key;
                //sub_key = ((temps << 5) & 0xffffffff) | ((temps >> 59) & 0xffffffff);
                sub_key = (temps << 5);
        }

运行得flag

piaoransfx 发表于 2019-8-14 15:12

惭愧。到现在还是看不懂

jasidy 发表于 2019-8-14 16:36

谢谢楼主提供好工具。

o651560441 发表于 2019-8-14 22:22

这些楼主分享思路,新人总是需要去尝试,但是没人带只能自己下琢磨

lixiaoben52poji 发表于 2019-8-23 15:35

软件真的好用
页: [1]
查看完整版本: 2019xman个人晋级赛之little-unpack