181202 逆向-2018鹏城杯

本次比赛的各个Re题目都对各种公开密码算法的运用考察比较多,还是挺有意思的~

Reverse

badblock

main函数打开发现是C++写的,充斥大量无用代码
于是转头执行,发现接收输入后回弹err...
搜索字符串发现有三处引用
分别是两个anti_debug和一个puts_wrong
anti_debug分别通过ptrace和getpid()的方法,不必多说,调试的时候直接绕过即可

puts_wrong则是在一个vtable中,很明显是一个类的成员函数
于是根据vt指针找到sub_5607AA5F4DD0
做了一些初始化以后、包括对input和data的赋值
调用了这个函数

return (*((unsigned int (__fastcall **)(Class *))obj->this + 13))(obj) == 1;

this+13即vt[12],点进去看一下即可发现是main_loop

循环处理code,显然是个VM
此处一共有2个类,根据代码逐步复原结构即可

然后处理VM的各个handler

.data.rel.ro:00005607AA7F7A10 vt              dq offset plus          ; DATA XREF: Imp+16↑o
.data.rel.ro:00005607AA7F7A18                 dq offset sub
.data.rel.ro:00005607AA7F7A20                 dq offset cmp
.data.rel.ro:00005607AA7F7A28                 dq offset jmp_2
.data.rel.ro:00005607AA7F7A30                 dq offset mov
.data.rel.ro:00005607AA7F7A38                 dq offset save_ip
.data.rel.ro:00005607AA7F7A40                 dq offset load_ip
.data.rel.ro:00005607AA7F7A48                 dq offset load_short
.data.rel.ro:00005607AA7F7A50                 dq offset wrong
.data.rel.ro:00005607AA7F7A58                 dq offset load_input
.data.rel.ro:00005607AA7F7A60                 dq offset load_data
.data.rel.ro:00005607AA7F7A68                 dq offset xor
.data.rel.ro:00005607AA7F7A70                 dq offset get_final_flag
.data.rel.ro:00005607AA7F7A78                 dq offset main_loop

跑一下log可以发现是将输入和一个数异或后与另一个数比较的算法,dump出来发现不可见,于是回头调试发现在接受输入后的几行指令后的sub_5607AA5F4D50中对输入进行了一个前后字符异或的处理

我对模拟器进行了Patch功能-即输入不对时也会继续向后执行,和Dump功能的添加–计算并保存flag

code = [8, 0, 20, 8, 1, 0, 8, 2, 1, 8, 7, 9, 8, 8, 0, 8, 9, 0, 1, 9, 8, 1, 8, 2, 3, 7, 8, 516, 65532, 0, 5, 3, 9, 3, 1, 0, 260, 10, 0, 5, 4, 1, 1, 4, 3, 1, 4, 4, 10, 5, 1, 12, 5, 4, 11, 6, 1, 1, 1, 2, 3, 6, 5, 260, 65525, 0, 516, 1, 0, 255, 0, 0, 9, 0, 0, 255, 0, 0, 0, 0, ]
# data = [46, 0, 38, 0, 45, 0, 41, 0, 77,0,103, 0, 5, 0, 68, 0, 26, 0, 14,0,127, 0, 127, 0, 125, 0, 101, 0, 119,0,36, 0, 26, 0, 93, 0, 51, 0, 81, 0]
mem = [0 for i in range(50)]
input = [0 for i in range(50)]
dump = ""
n = 0
flag = 0
while (n < 100):
    # patch check
    if (n == 21):
        flag = 1
        # print("Patched:%d"%flag)
    c = code[3 * n] & 0xff
    f = code[3 * n] >> 8
    h1 = code[3 * n + 1]
    h2 = code[3 * n + 2]
    if (f != 0 and f != flag):
        n += 1
        print("pass")
        continue
    if (False):
        pass
    elif (c == 1):
        mem[h1] += mem[h2]
    elif (c == 2):
        mem[h1] -= mem[h2]
    elif (c == 3):
        # dump flag
        if (n == 20):
            dump += chr(mem[4] 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值