拿到程序,拖入IDA
进行反编译,我们可以获取到一些基本的信息
我们可以得到flag
的长度为24
,同时点击对应的encrypt
可以发现跳到的是一个地址,我们可以断定是一个SMC
程序,程序将我们的输入保存了两份,第一份用来判断是否是假的flag
,第二部分用于真正的加密,同时判断是否与flag
加密后相同
我们可以利用一个SMC
解密脚本进行手动解密来进行静态分析,而不是动态调试来进行解密
1 2 3 4 5 6 7 8 9 10 11 12 13
| import idc def aPatch(start,end,key): n=0 while(start+n!=end+1): addr=start+n idc.patch_byte(addr,idc.get_wide_byte(addr)^key) n+=1 print("%d Byte has been changed"%n)
codeStart=0x401500 codeLen=187 xorData=0x41 aPatch(codeStart,codeStart+codeLen-1,xorData)
|
我们观察wrong
函数,也就是一个简单的加密
十分简单的我们便可以写出逆过程
1 2 3 4 5 6 7 8 9 10 11 12 13
| enc = [0x000066, 0x00006B, 0x000063, 0x000064, 0x00007F, 0x000061, 0x000067, 0x000064, 0x00003B, 0x000056, 0x00006B, 0x000061, 0x00007B, 0x000026, 0x00003B, 0x000050, 0x000063, 0x00005F, 0x00004D, 0x00005A, 0x000071, 0x00000C, 0x000037, 0x000066] def de1(a): for i in range(24): if i&1 !=0 : a[i] += i else: a[i]^=i
de1(enc) for i in range(len(enc)): print(chr(enc[i]),end='')
|
明显的看出来这个就是一个Fake Flag
,我们观察下面的函数
同样的是一个异或,但是执行这个脚本我们会发现少了后面的5
位Flag
,此时我们有下面的一个函数:
可以发现这个函数比较的难看,我们已知flag
最后一位必定为}
,我们猜测最后一个加密与前面相同,同样是异或,经过简单的尝试后,发现没有问题…
于是我们便可以得到如下脚本对完整的flag
进行解密
1 2 3 4 5 6 7 8 9 10 11
| enc2 = [0x0000000E, 0x0000000D, 0x00000009, 0x00000006, 0x00000013, 0x00000005, 0x00000058, 0x00000056, 0x0000003E, 0x00000006, 0x0000000C, 0x0000003C, 0x0000001F, 0x00000057, 0x00000014, 0x0000006B, 0x00000057, 0x00000059, 0x0000000D] xor_data ="hahahaha_do_you_find_me?" for i in range(19): print(chr(enc2[i]^ord(xor_data[i])),end='')
enc3 ="%tp&:" xor_data2 = ord(enc3[-1])^ord('}') for i in range(len(enc3)): print(chr(ord(enc3[i])^xor_data2),end='')
|