flowering-shrubs
使用 IDA 可以看到程序完全无法分析。
再仔细看汇编可以发现,题目似乎在随机位置处添加了同一个花指令。
因此我们要使用 IDAPython 自动去除花指令。
python
# remove_flower.py
import idc
import idaapi
startaddr=0x1100
endaddr=0x15FF
lis=[0x50, 0x51, 0x52, 0x53, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x48, 0x81, 0xC3, 0x12, 0x00, 0x00, 0x00, 0x48, 0x89, 0x5C, 0x24, 0x18, 0x48, 0x83, 0xC4, 0x18,0xC3]
#这个for循环是关键点,检测以当前地址开始的27个字节是否符合lis列表的内容。
for i in range(startaddr,endaddr):
flag=True
for j in range(i,i+27):
if idc.get_wide_byte(j)!=lis[j-i]:
flag=False
if flag==True:
for addr in range(i,i+27):
idc.patch_byte(addr,0x90) # 将这部分内容全部nop掉
for i in range(startaddr,endaddr):# 取消函数定义
idc.del_items(i)
for i in range(startaddr,endaddr): # 添加函数定义
if idc.get_wide_dword(i)==0xFA1E0FF3: #endbr64
idaapi.add_func(i)
lis
列表中的内容就是花指令的全部内容。
在 IDA 中选择 File » Script file,选择该 Python 文件即可。
或者在 File » Script command 中将上面的代码粘贴进来。
之后再按下 F5 即可看到清晰的伪代码。
部分函数我进行了重命名。在函数名位置处按下 N 即可重命名。
关键内容就是 encrypt
函数。
这里是用了递归,一共 40 个字节,每四个字节为 1 组,一共 10 组,通过 get_next_rand
函数得到下一组加密字节。仔细分析一下即可写出脚本。
python
#solve.py
lis=[0x54,0xf4,0x20,0x47,0xfc,0xc4,0x93,0xe6,0x39,0xe0,
0x6e,0x00,0xa5,0x6e,0xaa,0x9f,0x7a,0xa1,0x66,0x39,
0x76,0xb7,0x67,0x57,0x3d,0x95,0x61,0x22,0x55,0xc9,
0x3b,0x4e,0x4f,0xe8,0x66,0x08,0x3d,0x50,0x43,0x3e]
str="uarefirst."
offset_buf=[0,4,32,12,8,24,16,20,28,36]
#offset_buf就是通过动态调试提取出每一轮get_next_rand函数的返回值得到的
truekey=[]
for i in str:
truekey.append(ord(i))
def decrypt(offset,key):
a=lis[offset]
b=lis[offset+1]
c=lis[offset+2]
d=lis[offset+3]
flagc=((c+key)&0xff)^b
flagd=c^d
flaga=a^d^key
flagb=((b-key)&0xff)^flaga^key
lis[offset]=flaga
lis[offset+1]=flagb
lis[offset+2]=flagc
lis[offset+3]=flagd
for i in range(10):
decrypt(offset_buf[i],truekey[i])
print(bytes(lis).decode('utf-8'))
# flag{y0u_C4n_3a51ly_Rem0v3_CoNfu510n-!!}