本文作者:rookiedrag*(二进制逆向星球学员)
最近学习用了一下ghidra !
Mips工具反汇编工具有ghidra,jeb,ida,插件retdec(我觉得不好用),听说现在ida7.5也可以反mips了, 可我还是个盗版怪。
Mips用ghidra转, 虽然也是只能看个大概
还是要读汇编的
注意是大端 mips64
Mips传参前四个是a0-a3
Mips 返回值 v0 v1
这里要说明一点
我觉得传参和返回值这种东西十分重要,所以我逆向汇编一开始就是上网查mips传参和返回值是啥
第一次用ghrida,这翻译的一点不准确连一个参数都忘记传了!!!!!我记住了下次一定有记性 (同时显示了记住mips汇编传参和返回值的重要)
乍一看我还以为没法逆, 丧了一会儿!
首先我是有两点没有看好,一个是传参数ghrida弄丢一个,一个是加减运算是优于异或的,下面从头到尾静态分析解释一下
主函数逻辑是这样:先打开一个flag文件,当然这个flag文件内容是需要逆的,因为题目给了一个ciphertext
很显然这是flag加密后的结果。
然后进入cipher函数
Cipher函数的第一个参数是flag值,第二个是临时生成的变量
Cipher函数如下:
分析cipher函数:
最后的尾巴那里是putchar(10) 就刚好是刚才ciphertext最后一个字节0x0a
然后进入encrypt函数进行分析
上图为两个参数
我们看一下汇编
a0, a1,a2 其实传了三个参数!!!!!
A2那个变量其实是cipher函数param2的地址
就是这里面a2是一个随机数
仔细看的话其实a2传进去两个字节的随机数
因为都是sb指令
Encrypt函数如下:
我这里出了一个小问题
我以为异或优先运算,其实不是(这导致我脚本写了半天)
事实是这样的:
Stack32 = key1
Stack24 = key2由于stackxx都是ulonglong类型的(8个字节),所以key2永远是0
这里也是重点,为什么不是key1 为0, 偏偏是key2 为0
Stack 40 = xxx
Stack48 = xxx
循环里面:
Stack24 = ((stack24 >>8) + (stack24<<0x38) + ustack32) ^index
Stack32 = ((stack32>>0x3d) + (stack32<<3))^stack24
Stack40 = ((stack40>>8 + stack40<<0x38)+stack48) ^ stack32
Stack48 = (stack48>>0x3d + stack48 <<3)^stack40
附一个别人的脚本:
https://bbs.pediy.com/thread-259892.htm
这道题看雪大佬总结了,十分详细值得一看,也写了如何进行动态调试mips。
我就不再这里丢人了!
import struct
def solve():
# withopen('ciphertext', 'rb')as f:
# enc = f.read()
enc = b'*\x00\xf8+\xe1\x1dw\xc1\xc3\xb1q\xfc#\xd5\x91\xf40\xf1\x1e\x8b\xc2\x88YW\xd5\x94\xabwB/\xebu\xe1]v\xf0Fn\x98\xb9\xb6Q\xfd\xb5]w6\xf2\n'
for i in range(0x10000):
v32, v24 =get_final_r1_r2(0x7413 * 0x1000000000000, 0)
flag = b''
for k in range(len(enc) // 16):
f1, f2 =decrypt(enc[k * 16:k * 16 + 16], v32, v24)
flag += struct_example.pack('>Q', f1) +struct_example.pack('>Q', f2)
if b'RCTF' in flag:
print(hex(i), flag)
print(i)
break
def decrypt(byte16, fc, fd):
v48 = struct_example.unpack('>Q', byte16[:8])[0]
v40 = struct_example.unpack('>Q', byte16[8:])[0]
v32, v24 = fc, fd
for i in range(0x1e, -1, -1):
#print((v40 ^ v32) -v48)
v48 = rol64(v48 ^v40, 0x3d)
v40 = rol64(ull((v40 ^ v32) -v48), 8)
v32 = rol64(v32 ^ v24, 0x3d)
v24 = rol64(ull((v24 ^ i) - v32), 8)
v48 = rol64(v48 ^ v40, 0x3d)
v40 = rol64(ull((v40 ^ v32) - v48), 8)
return v48, v40
def get_final_r1_r2(c, d):
v32, v24 = c, d
for i in range(0x1f):
v24 = ull(ror64(v24, 8) + v32) ^ i
v32 = ror64(v32, 0x3d) ^ v24
return v32, v24
def rol64(value, k):
return ull(value<< k) | ull(value >> (64 - k))
def ror64(value, k):
return ull(value<< (64 - k)) | ull(value >> k)
def ull(n):
return n & 0xffffffffffffffff
solve()
扫描下方二维码加入星球学习
加入后会邀请你进入内部微信群,内部微信群永久有效!
目前28000+人已关注加入我们