avatar

空指针

gatesXgame

1 upx

直接百度得到脱壳机

2 花指令

研究了一下发现模式固定=.=,直接010editor替换即可

1
2
3
4
5
6
7
8
9
10
11
In [2]: asm('jmp $+5')
Out[2]: '\xeb\x03'

In [3]: asm('jmp $+6')
Out[3]: '\xeb\x04'

In [4]: asm('jmp $+8')
Out[4]: '\xeb\x06'

In [5]: asm('jmp $+7')
Out[5]: '\xeb\x05'

然后nop掉没用的东西

3 小插曲

不知道为啥动态调试总是出问题(输入的第一字节位空),猜测可能是壳子的问题?=.=不影响解题,判断逻辑直接暴力jmp即可

4 retfq

ida调试炸了,x64dbg调试炸了=.=,上网搜了搜发现是一种反调试

CTF中32位程序调用64位代码的逆向方法

根据解决办法找到了windbg/x64

调试即可

发现逻辑并不复杂,但是数量很多

5 dump&分析程序

通过上述操作,发现关键点在动态的那段代码,直接dump+修复花指令

得到稍微能看的汇编,理出程序逻辑(我一开始还单纯以为只是简单的几条,准备手动搞来着

发现数据极多

写出脚本提取数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
def searchip(ip,tstr):
ends = False
while not ends:
asm = GetDisasm(ip)
if 'mov' in asm and 'sp' in asm and 'h' in asm:

ends = True
return str(int('0'+asm.split(',')[-1][:-1].replace(' ','').split(';')[0].replace('h',''),16))

ip+=1

def search(ip,tstr):
ends = False
while not ends:
asm = GetDisasm(ip)
if 'cmp' in asm and 'al' in asm:
ttstr=tstr+'\t'+ asm.split(';')[-1].replace('\'','')+'\t'
ip+=2
asm = GetDisasm(ip)
if 'jz' in asm:
nextip = int(asm.split('_')[-1],16)
#print('next ip 0x%x'%(nextip))
ttstr+=searchip(nextip,tstr)
print(ttstr)
if 'xor' in asm and 'ax' in asm:
ends = True
break
ip+=1


count = 0
ip = 0
while ip < 0x30D0:
asm = GetDisasm(ip)
if 'cmp' in asm and "ecx" in asm:
print('+'*20)
tstr = str(ip)
ip = ip+2
search(ip,tstr)
count+=1

elif 'cmp' in asm and "rcx" in asm:
print('+'*20)
tstr = str(ip)
ip=ip+3
search(ip,tstr)
count+=1
else:
ip+=1

print('count %d'%count)

6 最短路求解=.=

得到flag

npointer{f4fce95b63f57187c9424ae06cf1a86f}

Author: L0x1c
Link: https://l0x1c.github.io/2020/04/26/%E7%A9%BA%E6%8C%87%E9%92%88gatesXgame/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
    微信
  • 支付寶
    支付寶