pwn.college: Reverse Engineering

不,你不会讨厌”yan85”的,因为后面的还有”yan85_64”。*_*

Reverse Engineering

level1.0

这题很简单哇,就是把输入的字符串转成了ascii。对应输入即可获得flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Ready to receive your license key!

quit
Initial input:

71 75 69 74 0a

The mangling is done! The resulting bytes will be used for the final comparison.

Final result of mangling input:

71 75 69 74 0a

Expected result:

63 6c 6a 79 62

Checking the received license key!

level1.1

这下没有回显了,只能通过工具逆向一下子了。

也很简单啊,直接看到了匹配的字符串。

level2.0

依然,使用IDA 看看:

但是输入会把最后两个字节翻转。最后输入xzujs即可。

level2.1

依然是,没有回显。简单查看一下逆向出来的源码。

1
2
3
4
5
6
7
8
movzx   eax, byte ptr [rbp+buf+2]
mov byte ptr [rbp+var_10], al
movzx eax, byte ptr [rbp+buf+3]
mov byte ptr [rbp+var_10+1], al
movzx eax, byte ptr [rbp+var_10+1]
mov byte ptr [rbp+buf+2], al
movzx eax, byte ptr [rbp+var_10]
mov byte ptr [rbp+buf+3], al

其中,rbp+buf是用户输入的地址。按照逻辑分析:该代码将用户输入的第3个字节给了rbp+var_10位置。第4个字节给了rbp+var_10+1位置,随后第4个字节给了第3个字节位置。第3个字节给了第4个字节位置。综合起来即,将用户输入的第三、四个字节位置交换。

那么输入loodc即可。

level3.0

1
2
3
4
5
6
7
8
9
10
quit
Initial input:

71 75 69 74 0a

This challenge is now mangling your input using the `reverse` mangler.

This mangled your input, resulting in:

0a 74 69 75 71

显然,这是将输入进行逆序了。image-20241107210124444

其实也不用IDA,通过回显的ASCII码可以推出要的结果。

最后输入sikky即可。

level3.1

查看源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
loc_153E:
mov eax, [rbp+var_14]
cdqe
movzx eax, byte ptr [rbp+rax+buf]
mov [rbp+var_16], al
mov eax, 4
sub eax, [rbp+var_14]
cdqe
movzx eax, byte ptr [rbp+rax+buf]
mov [rbp+var_15], al
mov eax, [rbp+var_14]
cdqe
movzx edx, [rbp+var_15]
mov byte ptr [rbp+rax+buf], dl
mov eax, 4
sub eax, [rbp+var_14]
cdqe
movzx edx, [rbp+var_16]
mov byte ptr [rbp+rax+buf], dl
add [rbp+var_14], 1

cdqe指令:EAX符号位拓展到RAX

有点抽象的是,无法知道[rbp+var_14]的值,因此手动分析不出来哇。通过IDA查看源码,发现循环了两次,第一次是交换第一个字节和第5个字节。第二次是交换第二个字节和第4个字节。因此就是一个逆序。

然后,

最后输入ruhsi即可。

level4.0

1
2
3
4
5
6
7
8
9
10
quit
Initial input:

71 75 69 74 0a

This challenge is now mangling your input using the `sort` mangler.

This mangled your input, resulting in:

0a 69 71 74 75

最后一个字节,去了第一个位置。第三个字节去了第二个位置,第一个字节去了第三个位置,第四个位置没动,第二个字节去了第五个位置。

66 71 72 77 78,这是期待的字符串,也就是fqrwx

最后输入xrfwq即可。

qfxwr

level4.1

这道题也是一样的,按照上面的逻辑进行翻转。

1
2
3
4
5
6
7
8
9
10
11
12
for ( i = 0; i <= 3; ++i )
{
for ( j = 0; j < 4 - i; ++j )
{
if ( *((_BYTE *)&buf + j) > *((_BYTE *)&buf + j + 1) )
{
v3 = *((_BYTE *)&buf + j);
*((_BYTE *)&buf + j) = *((_BYTE *)&buf + j + 1);
*((_BYTE *)&buf + j + 1) = v3;
}
}
}

分析一下,i = 0 的情况下,j由0到3,前五个字节。那么这里会有一个判断,即将ascii值最大的字节放至第5个位置;i = 1的情况下,j由0到2,前4个字节。将ascii值最大的字节放至第4个位置。以此类推。这是冒泡排序,对前5个字节进行冒泡排序。将ascii码值由小到大排序。

最后输入almrv的任意排序即可。因此,我在level4.0发现的规律是错误的。

level5.0

This challenge is now mangling your input using the xor mangler with key 0xb7

与0xb7异或。异或的操作是可逆的,那么再异或回去就好了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Type "help", "copyright", "credits" or "license" for more information.
>>> 0xc3 ^ 0xb7
116
>>> hex(0xc3 ^ 0xb7)
'0x74'
>>> hex(0xc2 ^ 0xb7)
'0x75'
>>> hex(0xdf ^ 0xb7)
'0x68'
>>> hex(0xc7 ^ 0xb7)
'0x70'
>>> hex(0xc4 ^ 0xb7)
'0x73'
>>>

用python终端,即可。最终输入tuhps即可。

level5.1

1
2
for ( i = 0; i <= 4; ++i )
*((_BYTE *)&buf + i) ^= 0x41u;

异或的字节为0x41,目标字符串是.data:0000000000004010 a056 db '0',27h,27h,'56',0

异或一下。最终输入qfftw即可。

level6.0

This challenge is now mangling your input using the xor mangler with key 0xbf46

This challenge is now mangling your input using the sort mangler.

This challenge is now mangling your input using the swap mangler for indexes 0 and 9.

强度一下就上来啦,xor,sort和swap三种方法。

目标

字符串为:cd 20 25 27 27 28 31 35 c8 20 ce cf d1 d5 d9 dc,写个脚本跑就好了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from pwn import *

io = process("/challenge/babyrev_level6.0")

# 20 20 25 27 27 28 31 35 c8 cd ce cf d1 d5 d9 dc
hex_string=[0x20,0x20,0x25,0x27,0x27,0x28,0x31,0x35,0xc8,0xcd,0xce,0xcf,0xd1,0xd5,0xd9,0xdc]
payload=""
# xor

for i in range(0,len(hex_string) - 1, 2):
print(i)
payload += chr(hex_string[i] ^ 0xbf)
payload += chr(hex_string[i+1] ^ 0x46)


print(payload)
io.sendafter('Ready to receive your license key!\n',payload)

data = io.recvall()
print(data.decode())

因为有sort的关系,并且最终的结果也确实sort后swap就能达到。因此只需要将目标字符串从小到大排序后,异或0xbf46即可。

level6.1

目标字符串为0x80, 0xD8, 0x4E, 0xC7, 0X99, 0x0B, 0x8B, 0xC8, 0x45, 0xC0, 0x86, 0x06, 0x84, 0xC2, 0x5F, 0xD6, 0x82, 0x03, 0x83

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
for ( i = 0; i <= 18; ++i )
{
v3 = i % 3;
if ( i % 3 == 2 )
{
*((_BYTE *)buf + i) ^= 0xEBu;
}
else if ( v3 <= 2 )
{
if ( v3 )
{
if ( v3 == 1 )
*((_BYTE *)buf + i) ^= 0x37u;
}
else
{
*((_BYTE *)buf + i) ^= 0xF1u;
}
}
}
for ( j = 0; j <= 8; ++j )
{
v4 = *((_BYTE *)buf + j);
*((_BYTE *)buf + j) = *((_BYTE *)buf + 18 - j);
*((_BYTE *)buf + 18 - j) = v4;
}
for ( k = 0; k <= 18; ++k )
{
if ( k % 2 )
{
if ( k % 2 == 1 )
*((_BYTE *)buf + k) ^= 0x46u;
}
else
{
*((_BYTE *)buf + k) ^= 0x1Du;
}
}

最终脚本为:

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
from pwn import *

io = process("/challenge/babyrev_level6.1")

# 20 20 25 27 27 28 31 35 c8 cd ce cf d1 d5 d9 dc
hex_string=[0x80, 0xD8, 0x4E, 0xC7, 0X99, 0x0B, 0x8B, 0xC8, 0x45, 0xC0, 0x86, 0x06, 0x84, 0xC2, 0x5F, 0xD6, 0x82, 0x03, 0x83]
# 0x80, 0xD8, 0x4E, 0xC7, 0X99, 0x0B, 0x8B, 0xC8, 0x45, 0xC0, 0x86, 0x06, 0x84, 0xC2, 0x5F, 0xD6, 0x82, 0x03, 0x83
payload=""
# xor


for i in range(19):
if i % 2 == 1:
hex_string[i] ^= 0x46
else:
hex_string[i] ^= 0x1d

for i in range(9):
temp = hex_string[i]
hex_string[i] = hex_string[18 - i]
hex_string[18 - i] = temp

for i in range(len(hex_string)):
if i % 3 == 2:
hex_string[i] ^= 0xeb
elif i % 3 == 1:
hex_string[i] ^= 0x37
else:
hex_string[i] ^= 0xf1
for i in range(len(hex_string)):
payload += chr(hex_string[i])

print(payload)
io.sendafter('Ready to receive your license key!\n',payload)

data = io.recvall()
print(data.decode())

逆序进行即可。还是比较简单的。

level7.0

1
2
3
4
5
6
7
8
This challenge is now mangling your input using the `sort` mangler.
This challenge is now mangling your input using the `swap` mangler for indexes `16` and `21`.
This challenge is now mangling your input using the `swap` mangler for indexes `9` and `22`.
This challenge is now mangling your input using the `swap` mangler for indexes `3` and `6`.
This challenge is now mangling your input using the `reverse` mangler.
Expected result:

79 78 78 68 72 73 72 72 72 74 70 6f 6f 6d 6c 6a 77 67 65 62 64 62 64 61 61 61
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from pwn import *

io = process("/challenge/babyrev_level7.0")

# 20 20 25 27 27 28 31 35 c8 cd ce cf d1 d5 d9 dc
hex_string=[0x79, 0x78, 0x78, 0x68, 0x72, 0x73, 0x72, 0x72, 0x72, 0x74, 0x70, 0x6f, 0x6f, 0x6d, 0x6c, 0x6a, 0x77, 0x67, 0x65 ,0x62, 0x64, 0x62, 0x64, 0x61, 0x61, 0x61]
payload=""

for i in range(len(hex_string)):
payload += chr(hex_string[i])

print(payload)
io.sendafter('Ready to receive your license key!\n',payload)

data = io.recvall()
print(data.decode())

因为sort在第一个的关系,因此实际上我们需要的是找到expected result即可。

level7.1

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
// swap  
for ( i = 0; i <= 13; ++i )
{
v6 = *((_BYTE *)&buf + i);
*((_BYTE *)&buf + i) = *((_BYTE *)&buf + 28 - i);
*((_BYTE *)&buf + 28 - i) = v6;
}
//sort
for ( j = 0; j <= 27; ++j )
{
for ( k = 0; k < 28 - j; ++k )
{
if ( *((_BYTE *)&buf + k) > *((_BYTE *)&buf + k + 1) )
{
v5 = *((_BYTE *)&buf + k);
*((_BYTE *)&buf + k) = *((_BYTE *)&buf + k + 1);
*((_BYTE *)&buf + k + 1) = v5;
}
}
}
// swap
for ( m = 0; m <= 13; ++m )
{
v4 = *((_BYTE *)&buf + m);
*((_BYTE *)&buf + m) = *((_BYTE *)&buf + 28 - m);
*((_BYTE *)&buf + 28 - m) = v4;
}
// switch
for ( n = 0; n <= 28; ++n )
{
switch ( n % 5 )
{
case 0:
*((_BYTE *)&buf + n) ^= 0x75u;
break;
case 1:
*((_BYTE *)&buf + n) ^= 0x7Eu;
break;
case 2:
*((_BYTE *)&buf + n) ^= 1u;
break;
case 3:
*((_BYTE *)&buf + n) ^= 0x3Du;
break;
case 4:
*((_BYTE *)&buf + n) ^= 0xC5u;
break;
default:
continue;
}
}
image-20241110102042920
1
0x0f, 0x04, 0x7b, 0x47, 0xbf, 0x0c, 0x06, 0x79, 0x4a, 0xb0, 0x01, 0x0d, 0x70, 0x52, 0xaa, 0x18, 0x12, 0x6a, 0x56, 0xae, 0x1f, 0x16, 0x67, 0x59, 0xa6, 0x16, 0x1c, 0x63, 0x5c
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
from pwn import *

io = process("/challenge/babyrev_level7.1")

# 20 20 25 27 27 28 31 35 c8 cd ce cf d1 d5 d9 dc
hex_string=[0x0f, 0x04, 0x7b, 0x47, 0xbf, 0x0c, 0x06, 0x79, 0x4a, 0xb0, 0x01, 0x0d, 0x70, 0x52, 0xaa, 0x18, 0x12, 0x6a, 0x56, 0xae, 0x1f, 0x16, 0x67, 0x59, 0xa6, 0x16, 0x1c, 0x63, 0x5c]
payload=""

# xor

for i in range(29):
d = i % 5
if d == 0:
hex_string[i] ^= 0x75
elif d == 1:
hex_string[i] ^= 0x7e
elif d == 2:
hex_string[i] ^= 0x01
elif d == 3:
hex_string[i] ^= 0x3d
else:
hex_string[i] ^= 0xc5

for i in range(len(hex_string)):
payload += chr(hex_string[i])

print(payload)
io.sendafter('Ready to receive your license key!\n',payload)

data = io.recvall()
print(data.decode())

level8.0

1
2
3
4
5
6
7
8
This challenge is now mangling your input using the `swap` mangler for indexes `5` and `22`.
This challenge is now mangling your input using the `reverse` mangler.
This challenge is now mangling your input using the `xor` mangler with key `0x3c7c`
This challenge is now mangling your input using the `sort` mangler.
This challenge is now mangling your input using the `swap` mangler for indexes `18` and `33`.
This challenge is now mangling your input using the `reverse` mangler.
This challenge is now mangling your input using the `swap` mangler for indexes `3` and `10`.
5f 5e 46 53 58 57 57 57 56 56 5a 52 52 4e 4e 4c 4a 5b 1f 1f 1f 1b 19 16 16 14 14 14 12 11 0d 0c 0b 08 06 05

虽然有这么多层修改,但是只需要关心sort前的修改即可。

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
from pwn import *

io = process("/challenge/babyrev_level8.0")

# 20 20 25 27 27 28 31 35 c8 cd ce cf d1 d5 d9 dc
hex_string=[0x5f, 0x5e, 0x46, 0x53, 0x58, 0x57, 0x57, 0x57, 0x56, 0x56, 0x5a, 0x52, 0x52, 0x4e, 0x4e, 0x4c, 0x4a, 0x5b, 0x1f, 0x1f, 0x1f, 0x1b, 0x19, 0x16, 0x16, 0x14, 0x14, 0x14, 0x12, 0x11, 0x0d, 0x0c, 0x0b, 0x08, 0x06, 0x05]
payload=""

# xor
for i in range(len(hex_string)):
if i % 2 == 0:
hex_string[i] ^= 0x3c
else:
hex_string[i] ^= 0x7c

# reverse
reversed_hex_string = hex_string[::-1]

# swap
temp = reversed_hex_string[5]
reversed_hex_string[5] = reversed_hex_string[22]
reversed_hex_string[22] = temp


for i in range(len(reversed_hex_string)):
payload += chr(reversed_hex_string[i])

print(payload)
io.sendafter('Ready to receive your license key!\n',payload)

data = io.recvall()
print(data.decode())

level8.1

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// swap  		0x5e97a08d5571
v3 = BYTE6(v15);
BYTE6(v15) = v17;
LOBYTE(v17) = v3;
// reverse
for ( i = 0; i <= 17; ++i )
{
v7 = *((_BYTE *)&buf + i);
*((_BYTE *)&buf + i) = *((_BYTE *)&buf + 36 - i);
*((_BYTE *)&buf + 36 - i) = v7;
}
// swap 0x5e97a08d55de
v4 = BYTE3(buf);
BYTE3(buf) = BYTE4(v14);
BYTE4(v14) = v4;
// xor
for ( j = 0; j <= 36; ++j )
{
if ( j % 2 )
{
if ( j % 2 == 1 )
*((_BYTE *)&buf + j) ^= 0xA4u;
}
else
{
*((_BYTE *)&buf + j) ^= 0x48u;
}
}
// reverse
for ( k = 0; k <= 17; ++k )
{
v6 = *((_BYTE *)&buf + k);
*((_BYTE *)&buf + k) = *((_BYTE *)&buf + 36 - k);
*((_BYTE *)&buf + 36 - k) = v6;
}
// reverse
for ( m = 0; m <= 17; ++m )
{
v5 = *((_BYTE *)&buf + m);
*((_BYTE *)&buf + m) = *((_BYTE *)&buf + 36 - m);
*((_BYTE *)&buf + 36 - m) = v5;
}
// xor
for ( n = 0; n <= 36; ++n )
{
switch ( n % 5 )
{
case 0:
*((_BYTE *)&buf + n) ^= 0x5Cu;
break;
case 1:
*((_BYTE *)&buf + n) ^= 0xA3u;
break;
case 2:
*((_BYTE *)&buf + n) ^= 0xBDu;
break;
case 3:
*((_BYTE *)&buf + n) ^= 0x29u;
break;
case 4:
*((_BYTE *)&buf + n) ^= 0x6Cu;
break;
default:
continue;
}
}
1
0x79, 0x76, 0x8c, 0xe8, 0x55, 0x8e, 0x93, 0x75, 0x0b, 0xbc, 0x64, 0x69, 0x9b, 0xe8, 0x5d, 0x97, 0x9d, 0x77, 0x10, 0xb2, 0x7b, 0x6e, 0x9b, 0xe9, 0x4b, 0x93, 0x87, 0x6b, 0x13, 0xbd, 0x75, 0x60, 0x9b, 0xf9, 0x53, 0x8f, 0x93
1
2
3
4
5
6
7
8
9
movzx   eax, byte ptr [rbp+buf+3]		# byte ptr [rbp + buf + 3]
mov [rbp+var_4C], al
movzx eax, byte ptr [rbp+var_28+4] # byte ptr [rbp + buf + 6]
mov [rbp+var_4B], al
movzx eax, [rbp+var_4B]
mov byte ptr [rbp+buf+3], al
movzx eax, [rbp+var_4C]
mov byte ptr [rbp+var_28+4], al # 交换36
mov [rbp+var_40], 0
1
2
3
4
5
6
7
8
movzx   eax, byte ptr [rbp+var_20+6]		# 等价为 byte ptr [rbp + buf + 16]
mov [rbp+var_4E], al
movzx eax, byte ptr [rbp+var_10] # 等价为 byte ptr [rbp + buf + 20]
mov [rbp+var_4D], al
movzx eax, [rbp+var_4D]
mov byte ptr [rbp+var_20+6], al # 交换1620
movzx eax, [rbp+var_4E]
mov byte ptr [rbp+var_10], al

动态调试:

1
2
3
4
5
6
7
8
原始输入:
xwwtngaurrlkodniozqnvoyennptjlxvqeyqm 22 ---- 32
第一个: 0x5ee6a471a571 (断点地址)
xwwtngaurrlkodniozqnvoqennptjlxvyeyqm
第二个: 0x5ee6a471a5de
xwwtngaurrlkodniozqnvoqennptjlxvyeyqm

xwwtngaurrlkodniozqnvoyennptjlevqxyqm
1
2
3
4
xwwtngaurrlkodniozqnvoyennptjlevqxyqm		3 ---- 12
xwwtngaurrlkodniozqnvoqennptjlevyxyqm
mqyxyveljtpnneqovnqzoindoklrruagntwwx
mqynyveljtpnxeqovnqzoindoklrruagntwwx

调试过程中,发现两个swap的具体交换位置。然后写exp:

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
52
53
54
from pwn import *

io = process("/challenge/babyrev_level8.1")

hex_string=[0x79, 0x76, 0x8c, 0xe8, 0x55, 0x8e, 0x93, 0x75, 0x0b, 0xbc, 0x64, 0x69, 0x9b, 0xe8, 0x5d, 0x97, 0x9d, 0x77, 0x10, 0xb2, 0x7b, 0x6e, 0x9b, 0xe9, 0x4b, 0x93, 0x87, 0x6b, 0x13, 0xbd, 0x75, 0x60, 0x9b, 0xf9, 0x53, 0x8f, 0x93]
payload=""

print(len(hex_string))
# xor
for i in range(37):
if i % 5 == 0:
hex_string[i] ^= 0x5c
elif i % 5 == 1:
hex_string[i] ^= 0xa3
elif i % 5 == 2:
hex_string[i] ^= 0xbd
elif i % 5 == 3:
hex_string[i] ^= 0x29
else:
hex_string[i] ^= 0x6c

# xor
for i in range(37):
if i % 2 == 1:
hex_string[i] ^= 0xa4
else:
hex_string[i] ^= 0x48

# swap
temp = hex_string[3]
hex_string[3] = hex_string[12]
hex_string[12] = temp


# reverse
for i in range(18):
temp = hex_string[i]
hex_string[i] = hex_string[36 - i]
hex_string[36 - i] = temp

# swap
temp = hex_string[22]
hex_string[22] = hex_string[32]
hex_string[32] = temp

for i in range(len(hex_string)):
payload += chr(hex_string[i])

print(payload)
io.sendafter('Ready to receive your license key!\n',payload)

data = io.recvall()
print(data.decode())

level9.0

看源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
v12 = ((unsigned __int64)bin_padding & 0xFFFFFFFFFFFFF000LL) - 4096;
do
v3 = v6++;
while ( !mprotect((void *)((v3 << 12) + v12), 0x1000uLL, 7) );
for ( i = 0; i <= 4; ++i )
{
printf("Changing byte %d/5.\n", (unsigned int)(i + 1));
printf("Offset (hex) to change: ");
__isoc99_scanf("%hx", &v5);
printf("New value (hex): ");
__isoc99_scanf("%hhx", &v4);
*(_BYTE *)(v5 + v12) = v4;
printf("The byte has been changed: *%p = %hhx.\n", (const void *)(v12 + v5), v4);
}

关于可执行文件的装载——页映射(理解上述源码的v12是什么)

静态装载——程序执行时所需要的指令和数据必须在内存中才能够正常运行,最简单的办法就是将程序运行所需要的指令和数据全都装入内存中,这样程序就可以顺利运行,这就是最简单的静态装入的办法。

**问题:**很多情况下程序所需要的内存数量大于物理内存的数量。

根本的解决办法是添加物理内存。相对于磁盘来说,内存是昂贵的,因此人们想尽各种办法,希望能够不添加内存的情况下,让更多的程序运行起来,尽可能有效地利用内存。

那么为了良好地解决这个问题,研究人员发现,程序运行时是有局部性原理的,所以,将程序最常用的部分驻留在内存中,而将一些不太常用的数据存放在磁盘里面,这就是动态装载的基本原理。动态装载的思想是程序用到哪个模块,就将哪个模块装入内存,如果不用就暂时不装入,存放在磁盘中。

页映射——页映射不是一下子就把程序所有的数据和指令都装入内存,而是将内存和所有磁盘中的数据和指令按照“页(Page)”为单位划分成若干个页,以后所有的装载和操作的单位就是页。硬件规定的页的大小由4096字节、8192字节、2MB、4MB等,最常见的Intel IA32处理器一般都是用4096字节。这题所使用到的分页也是4096字节为一页。

假设程序所有的指令和数据的总和为32KB,机器为32位有16KB的内存,每个页大小为4096字节。那么程序总共被分为8个页。可人为将它们编号P0~P7。很明显,16KB的内存无法同时将32KB的程序装入,那么将按照动态装入的原理来进行整个装入过程。如果程序刚开始执行时的入口地址在P0,这时装载管理器发现程序的P0不在内存中,于是将内存F0分配给P0,并且将P0的内容装入F0;运行一段时间以后,程序需要用到P5,于是装载管理器将P5装入F1;就这样,映射关系如下所示:

【来源:《程序员的自我修养》P156】

可以知道,v12计算得出上一页的起始地址。一页为4096字节。

解题思路:看到了if memcmp分支的条件。在ida中查看。其是jne,并且根据查表:Intel x86 JUMP quick reference,可知jne的opcode是75,我们将其改成74即可控制分支。

根据思路,我们需要修改jne的opcode,通过gdb调试一下能够知道偏移量为0x27c1。最后我们只需要修改该位置的opcode为74,即可拿到flag。

level9.1

思路同上,偏移为0x1789,不过这题用gdb调试的时候,没有main这个符号。可以设置断点在_start处,然后一步步调试。到main处的时候,就能拿到main的地址。然后使用disassemble 起始地址,终止地址来查看这个地址区间的反汇编结果。然后就能查看jne指令的地址。最后算出偏移为0x1789,再修改opcode就行了。

level10.0

只能修改一个字节,但是够了。思路还是以上的思路。算出偏移地址为:0x1F17

level10.1

gdbfinish命令能够帮助快速执行完当前函数,断点可以打在memcmp函数这儿。偏移量为0x201e

level11.0

思路一致,只不过这时需要修改的是两个jne指令为jn指令,所以需要找到两个偏移量。还是按照前面题目的思路,找到的两个偏移量为:0x28570x2ae9

level11.1

还是老套路,这次没有符号了。依然可以gdb调试拿到偏移量:0x197b+10x1a5a

为什么要+1?是因为通过ida pro打开源程序后,发现它是带符号的opcode,因此查阅后需要将OF 85改成OF 84,所以,需要+1修改后面那个字节的值。而后面那个偏移不需要+1因为它时不带符号的opcode。因此后面的偏移值改成74即可。

level12.0

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
void __fastcall __noreturn execute_program(_BYTE *a1)		// al指向一个全为0的char数组,长度为256字节。
{
int v1; // eax
int v2; // eax
size_t v3; // rax
_BOOL4 v4; // [rsp+1Ch] [rbp-94h]
char buf[136]; // [rsp+20h] [rbp-90h] BYREF
unsigned __int64 v6; // [rsp+A8h] [rbp-8h]

v6 = __readfsqword(0x28u);
read(0, a1 + 67, 6uLL); // 接收用户输入的6个字节,从char[67]开始
a1[99] = 18;
a1[100] = -84;
a1[101] = -73;
a1[102] = -78;
a1[103] = -91;
a1[104] = 26;
v1 = memcmp(a1 + 99, a1 + 67, 6uLL);
v4 = v1 == 0;
if ( v1 )
{
printf("INCORRECT!");
}
else
{
printf("CORRECT! Your flag: ");
v2 = open("/flag", 0);
v3 = read(v2, buf, 0x64uLL);
write(1, buf, v3);
}
exit(!v4);
}

将al数组=[18, -84, -73, -78, -91, -26]使用python中的struct.pack打包成字节序,然后发送给目标程序就行了。

1
2
3
4
5
6
7
8
9
from pwn import *

p = process('/challenge/babyrev-level-12-0')
al = [18, -84, -73, -78, -91, 26]

payload = struct.pack('6b', *al)
print(payload)
p.send(payload)
print(p.readall())

struct.pack说明:

1
struct.pack(fmt, v1, v2, ...)
  • fmt:格式字符串,指定如何将数据打包成二进制。格式字符串由字符组成,每个字符表示一种数据类型。
  • v1,v2,...:要打包的数据,可以是整数、浮点数、字符串等。

格式字符串fmt由字节顺序(@,=,<,>,!)和数据类型(c,b,B,?,h,H,i,I,l,L,q,Q,f,d,s,p,x)组成。其中字节顺序可选,@默认,使用本地字节顺序、大小和对齐方式。=使用本地字节序,标准大小,无对其。<小端模式,>大端模式,!网络字节序(大端模式)。后续的数据类型常见的有:

c:字符;b:有符号字节;B:无符号字节;h:有符号短整型;H:无符号短整型;i:有符号整型;I:无符号整型;s:字符串,需要指定长度,例如10s表示10字节的字符串

level12.1

同理

1
2
3
4
5
6
7
8
9
from pwn import *

p = process('/challenge/babyrev-level-12-1')
al = [61,118,-61,-110]

payload = struct.pack('4b', *al)
print(payload)
p.send(payload)
print(p.readall())

level13.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[s] IMM b = 0x71
[s] IMM c = 0x1
[s] IMM a = 0xbd
[s] STM *b = a # a1[0x71] = 0xbd
[s] ADD b c
[s] IMM a = 0xb5
[s] STM *b = a # a1[0x72] = 0xb5
[s] ADD b c
[s] IMM a = 0xd8
[s] STM *b = a # a1[0x73] = 0xd8
[s] ADD b c
[s] IMM a = 0xdc
[s] STM *b = a # a1[0x74] = 0xdc
[s] ADD b c
[s] IMM a = 0xbd
[s] STM *b = a # a1[0x75] = 0xbd
[s] ADD b c
[s] IMM a = 0x98
[s] STM *b = a # a1[0x76] = 0x98
[s] ADD b c

可以看到是一系列寄存器/立即数的操作。题目要求输入6个字节。 而上述正好是从a1[113]开始,写入了6个字节。因此,我们把这6个字节转换成字节序丢给它即可。

1
2
3
4
5
6
7
8
9
from pwn import *

p = process('/challenge/babyrev-level-13-0')
al = [0xbd,0xb5,0xd8,0xdc,0xbd,0x98]

payload = struct.pack('6B', *al)
print(payload)
p.send(payload)
print(p.readall())

level13.1

现在,题目不会打印出汇编伪代码了。就得自己通过ida 看出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sub_1533(a1, 1LL, 91LL);			
sub_1533(a1, 8LL, 1LL);
sub_1533(a1, 2LL, 70LL);
sub_1687(a1, 1LL, 2LL);
sub_1568(a1, 1LL, 8LL);
sub_1533(a1, 2LL, 236LL);
sub_1687(a1, 1LL, 2LL);
sub_1568(a1, 1LL, 8LL);
sub_1533(a1, 2LL, 45LL);
sub_1687(a1, 1LL, 2LL);
sub_1568(a1, 1LL, 8LL);
sub_1533(a1, 2LL, 101LL);
sub_1687(a1, 1LL, 2LL);
sub_1568(a1, 1LL, 8LL);

看了看,要手工调出来得好久,还容易出错。还是写代码快:

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
from pwn import *
import numpy as np

a1 = np.zeros((512,1), dtype=int)

def sub_1533(a2,a3):
return sub_1415(a2,a3)

def sub_1415(a2, a3):
result = []
match a2:
case 2:
result = a1
a1[256] = a3
case 1:
result = a1
a1[257] = a3
case 8:
result = a1
a1[258] = a3
case 32:
result = a1
a1[259] = a3
case 4:
result = a1
a1[260] = a3
case 16:
result = a1
a1[261] = a3
case 64:
result = a1
a1[262] = a3
case _:
print("unknown register")
exit()
return result
def sub_1687(a2, a3):
v3 = sub_1363(a3)
v4 = sub_1363(a2)
return sub_1507(v4, v3)

def sub_1363(a2):
res = 0
match a2:
case 2:
return a1[256]
case 1:
return a1[257]
case 8:
return a1[258]
case 32:
return a1[259]
case 4:
return a1[260]
case 16:
return a1[261]
case 64:
return a1[262]
def sub_1507(a2, a3):
res = a2
a1[a2] = a3
return res

def sub_1568(a2, a3):
v3 = sub_1363(a2)
v4 = sub_1363(a3)
return sub_1415(a2, v3+v4)


sub_1533(1, 91)
sub_1533(8, 1)
sub_1533(2, 70)
sub_1687(1, 2)
sub_1568(1, 8)
sub_1533(2, 236)
sub_1687(1, 2)
sub_1568(1, 8)
sub_1533(2, 45)
sub_1687(1, 2)
sub_1568(1, 8)
sub_1533(2, 101)
sub_1687(1, 2)
sub_1568(1, 8)
for i in range(4):
print(a1[91+i])

最后exp就是之前的模板:

1
2
3
4
5
6
7
8
9
from pwn import *

p = process('/challenge/babyrev-level-13-1')
al = [70,236,45,101]

payload = struct.pack('4B', *al)
print(payload)
p.send(payload)
print(p.readall())

level14.0

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
[s] IMM b = 0x36
[s] IMM c = 0x6
[s] IMM a = 0
[s] SYS 0x2 a
[s] ... read_memory
[s] ... return value (in register a): 0x2
[s] IMM b = 0x56
[s] IMM c = 0x1
[s] IMM a = 0x14
[s] STM *b = a # a1[0x56] = 0x14
[s] ADD b c
[s] IMM a = 0xd2
[s] STM *b = a # a1[0x57] = 0xd2
[s] ADD b c
[s] IMM a = 0xcf
[s] STM *b = a # a1[0x58] = 0xcf
[s] ADD b c
[s] IMM a = 0x31
[s] STM *b = a # a1[0x59] = 0x31
[s] ADD b c
[s] IMM a = 0x54
[s] STM *b = a # a1[0x5a] = 0x54
[s] ADD b c
[s] IMM a = 0xb8
[s] STM *b = a # a1[0x5b] = 0xb8
[s] ADD b c

老规矩,第一关还是会打印出来。那么我们直接简单推导一下就行了。exp:

1
2
3
4
5
6
7
8
9
10
from pwn import *

p = process('/challenge/babyrev-level-14-0')
al = [0x14,0xd2,0xcf,0x31,0x54,0xb8]

payload = struct.pack('6B', *al)
print(payload)
p.send(payload)
print(p.readall())

level14.1

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
from pwn import *
import numpy as np

a1 = np.zeros((512,1), dtype=int)

def sub_1533(a2,a3):
return sub_1415(a2,a3)

def sub_1415(a2, a3):
result = []
match a2:
case 2:
result = a1
a1[256] = a3
case 1:
result = a1
a1[257] = a3
case 8:
result = a1
a1[258] = a3
case 32:
result = a1
a1[259] = a3
case 4:
result = a1
a1[260] = a3
case 16:
result = a1
a1[261] = a3
case 64:
result = a1
a1[262] = a3
case _:
print("unknown register")
exit()
return result
def sub_1687(a2, a3):
v3 = sub_1363(a3)
v4 = sub_1363(a2)
return sub_1507(v4, v3)

def sub_1363(a2):
res = 0
match a2:
case 2:
return a1[256]
case 1:
return a1[257]
case 8:
return a1[258]
case 32:
return a1[259]
case 4:
return a1[260]
case 16:
return a1[261]
case 64:
return a1[262]
def sub_1507(a2, a3):
res = a2
a1[a2] = a3
return res

def sub_1568(a2, a3):
v3 = sub_1363(a2)
v4 = sub_1363(a3)
return sub_1415(a2, v3+v4)


# sub_1533(16, 82)
# sub_1533(2, 8)
# sub_1533(8, 0)
# sub_1896(8, 8)
sub_1533(16, 114)
sub_1533(2, 1)
sub_1533(8, 97)
sub_1687(16, 8)
sub_1568(16, 2)
sub_1533(8, 170)
sub_1687(16, 8)
sub_1568(16, 2)
sub_1533(8, 239)
sub_1687(16, 8)
sub_1568(16, 2)
sub_1533(8, 133)
sub_1687(16, 8)
sub_1568(16, 2)
sub_1533(8, 167)
sub_1687(16, 8)
sub_1568(16, 2)
sub_1533(8, 205)
sub_1687(16, 8)
sub_1568(16, 2)
sub_1533(8, 70)
sub_1687(16, 8)
sub_1568(16, 2)
sub_1533(8, 226)
sub_1687(16, 8)
sub_1568(16, 2)

for i in range(8):
print(a1[114+i])

这里能够注释掉前面几个混淆,因为没起作用。后面的sub_18969()是获取用户输入的。所以不需要写。

最后exp就不贴了,模板还是之前的,然后改一改数字就行了。

level15.0

道理是一样的,不过这一关的open flag啥的也被做成了函数,也就是后面的if()语句内的。我们只需要关注memcmp()函数以前的vmcode即可。

level15.1

还是之前的脚本,跑一下,打印出来的整数转成字节序,发给目标程序即可拿到flag。

level16.0

1
0x5c, 0x99, 0xc6, 0x21, 0xce, 0xf2, 0x7e, 0xb8

依然不用管后续的cmp就行了。其实就是刚开始的cmp换了种形式。依然可以直接按照先前的方法。记住ida pro这种形式,其实也是一种字符串的匹配问题。

level16.1

这一关就记住,找到输入的位置。根据之前的规律,很简单就知道用户从a1的哪个索引处开始写入数据的:

image-20250306162439521

因此,我们只需要用之前的脚本执行一下就行。(可能有名字的差异,但是大差不差。简单找一找就能知道对应的函数了)

level17.0

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
[s] IMM b = 0x51
[s] IMM c = 0x1
[s] IMM a = 0x87
[s] STM *b = a # a1[81] = 0x87
[s] ADD b c
[s] IMM a = 0xf
[s] STM *b = a # a1[82] = 0xf
[s] ADD b c
[s] IMM a = 0xca
[s] STM *b = a # 83
[s] ADD b c
[s] IMM a = 0xc1
[s] STM *b = a # 84
[s] ADD b c
[s] IMM a = 0xde
[s] STM *b = a # 85
[s] ADD b c
[s] IMM a = 0x29
[s] STM *b = a # 86
[s] ADD b c
[s] IMM b = 0x31
[s] IMM c = 0x1
[s] LDM a = *b # a = a1[0x31]
[s] IMM d = 0xc0 # d = 0xc0
[s] ADD a d # a = a1[0x31] + 0xc0
[s] STM *b = a # a1[0x31] = 0xc0
[s] ADD b c # b = 0x31 + 0x32
[s] LDM a = *b # a = a1[0x32]
[s] IMM d = 0
[s] ADD a d # a = a1[0x32] + 0

可以发现,多了LDM指令。经过分析之后,发现它是会对我们的输入进行了一个加法的操作。所以,我们把它打印出来,然后做减法就行了。注意转换成字节序的时候,有符号和范围溢出的问题。我们可以分开处理正数和负数就行了。exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from pwn import *

p = process('/challenge/babyrev-level-17-0')
al = [-57, 15, 178, 162,180,-100]
payload = b''
for i in range(len(al)):
if al[i] > 0:
payload += struct.pack('B', al[i])
else:
payload += struct.pack('b', al[i])
# payload = struct.pack('6b', *al)
print(payload)
p.send(payload)
print(p.readall())

level17.1

这里记录一下题目中的api,方便我们拿到匹配的字符串。

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
from pwn import *
import numpy as np

a1 = np.zeros((512,1), dtype=int)


def imm(a2,a3):
return sub_1415(a2,a3)

def stm(a2, a3):
v3 = read_register(a3)
v4 = read_register(a2)
return write_memory(v4, v3)


def write_memory(a2, a3):
res = a2
a1[a2] = a3
return res

def add(a2, a3):
v3 = sub_1363(a2)
v4 = sub_1363(a3)
return sub_1415(a2, v3+v4)

def read_register(a2):
match a2:
case 4:
return a1[257]
case 16:
return a1[256]
case 64:
return a1[261]
case 1:
return a1[259]
case 32:
return a1[260]
case 2:
return a1[258]
return a1[262]

def write_register(a2, a3): # sub_13F5
match a2:
case 4:
a1[257] = a3
case 16:
a1[256] = a3
case 8:
a1[262] = a3
case 64:
a1[261] = a3
case 1:
a1[259] = a3
case 32:
a1[260] = a3
case 2:
a1[258] = a3


def ldm(a2, a3):
v5 = read_register(a3)
memory = read_memory(v5)
return write_register(a2, memory)

def read_memory(a2):
return a1[a2]


def imm(a2, a3):
return write_register(a2, a3)


def write_memory(a2, a3):
a1[a2] = a3


def stm(a2, a3): # stm
v3 = read_register(a3) #
v5 = read_register(a2) #
return write_memory(v5, v3) #

def add(a2, a3):
v3 = read_register(a2)
v5 = read_register(a3)
return write_register(a2, v3+v5)

ida打开,同样的有LDM指令,不过符号没有标识出来而已。然后发现它是在它原先的字符串上进行了加法,而不是上一题那样在我们输入的字符串上进行加法。那就很简单了。只需要把最后的值打印出来,然后大于256的减一下就行了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *

p = process('/challenge/babyrev-level-17-1')
al = [188, 371, 259, 201,273,381, 204, 259,313, 219, 235,411]
payload = b''
for i in range(len(al)):
if al[i] > 256:
payload += struct.pack('B', al[i] - 256)
else:
payload += struct.pack('B', al[i])
# payload = struct.pack('6b', *al)
print(payload)
p.send(payload)
print(p.readall())

level18.0

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
[s] IMM b = 0x6d
[s] IMM c = 0x1
[s] IMM a = 0x81
[s] STM *b = a
[s] ADD b c
[s] IMM a = 0xea
[s] STM *b = a
[s] ADD b c
[s] IMM a = 0x34
[s] STM *b = a
[s] ADD b c
[s] IMM a = 0xde
[s] STM *b = a
[s] ADD b c
[s] IMM a = 0xf2
[s] STM *b = a
[s] ADD b c
[s] IMM a = 0x1d
[s] STM *b = a
[s] ADD b c
[s] IMM a = 0xe
[s] STM *b = a
[s] ADD b c
[s] IMM a = 0x49
[s] STM *b = a
[s] ADD b c
[s] IMM a = 0xe1
[s] STM *b = a
[s] ADD b c
[s] IMM b = 0x6d
[s] LDM b = *b # b = a1[0x6d] = 0x81
[s] IMM a = 0x4d
[s] LDM a = *a # a = a1[0x4d] users input from 0x4d
[s] IMM c = 0x2e
[s] ADD a c # a = 0x2e
[s] CMP a b # cmp a1[0x6d], a1[0x4d] + 0x2e
[s] IMM b = 0x6e
[s] LDM b = *b
[s] IMM a = 0x4e
[s] LDM a = *a
[s] IMM c = 0xa7
[s] ADD a c
[s] CMP a b
[s] IMM b = 0x6f
[s] LDM b = *b
[s] IMM a = 0x4f
[s] LDM a = *a
[s] IMM c = 0x9e
[s] ADD a c
[s] CMP a b
[s] IMM b = 0x70
[s] LDM b = *b
[s] IMM a = 0x50
[s] LDM a = *a
[s] IMM c = 0x82
[s] ADD a c
[s] CMP a b
[s] IMM b = 0x71
[s] LDM b = *b
[s] IMM a = 0x51
[s] LDM a = *a
[s] IMM c = 0x9d
[s] ADD a c
[s] CMP a b
[s] IMM b = 0x72
[s] LDM b = *b
[s] IMM a = 0x52
[s] LDM a = *a
[s] IMM c = 0x89
[s] ADD a c
[s] CMP a b
[s] IMM b = 0x73
[s] LDM b = *b
[s] IMM a = 0x53
[s] LDM a = *a
[s] IMM c = 0xdc
[s] ADD a c
[s] CMP a b
[s] IMM b = 0x74
[s] LDM b = *b
[s] IMM a = 0x54
[s] LDM a = *a
[s] IMM c = 0x7
[s] ADD a c
[s] CMP a b
[s] IMM b = 0x75
[s] LDM b = *b
[s] IMM a = 0x55
[s] LDM a = *a
[s] IMM c = 0xa9
[s] ADD a c
[s] CMP a b

其他的不怎么用改,只不过在这里需要自己加变量,然后打印出来中间的输入。

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
imm(0x20, 0x4D)
imm(0x40, 9)
imm(2, 0)
# sys(2, 2)
imm(0x20, 0x6D) # 0x20 b
imm(0x40, 1) # 0x40 c
imm(2, 0x81) # 0x02 a 0x10 d 0x01 s 0x04 i 0x08 f
stm(0x20, 2) # [s] STM *b = a
add(0x20, 0x40) # [s] ADD b c
imm(2, 0xEA)
stm(0x20, 2)
add(0x20, 0x40)
imm(2, 0x34)
stm(0x20, 2)
add(0x20, 0x40)
imm(2, 0xDE)
stm(0x20, 2)
add(0x20, 0x40)
imm(2, 0xF2)
stm(0x20, 2)
add(0x20, 0x40)
imm(2, 0x1D)
stm(0x20, 2)
add(0x20, 0x40)
imm(2, 0xE)
stm(0x20, 2)
add(0x20, 0x40)
imm(2, 0x49)
stm(0x20, 2)
add(0x20, 0x40)
imm(2, 0xE1)
stm(0x20, 2)
add(0x20, 0x40) # [s] ADD b c
imm(0x20, 0x6D) # [s] IMM b = 0x6d
ldm(32, 32) # [s] LDM b = *b
imm(2, 0x4D) # [s] IMM a = 0x4d
ldm(2, 2) # [s] IMM a = *a
imm(0x40, 0x2E) # [s] IMM c = 0x2e
add(2, 0x40) # [s] add a c
imm(0x10, 1) # [s] IMM d = 0x01
imm(1, 0x4D) # [s] IMM s = 0x4d
stm(1, 2) # [s] STM *s = a
add(1, 0x10) # [s] add s d

imm(0x20, 0x6E)
ldm(32, 32)
imm(2, 0x4E)
ldm(2, 2)
imm(0x40, 0xA7)
add(2, 0x40)
stm(1, 2) # [s] STM *s = a
add(1, 0x10) # [s] add s d

imm(0x20, 0x6F)
ldm(32, 32)
imm(2, 0x4F)
ldm(2, 2)
imm(0x40, 0x9E)
add(2, 0x40)
stm(1, 2) # [s] STM *s = a
add(1, 0x10) # [s] add s d

imm(0x20, 0x70)
ldm(32, 32)
imm(2, 0x50)
ldm(2, 2)
imm(0x40, 0x82)
add(2, 0x40)
stm(1, 2) # [s] STM *s = a
add(1, 0x10) # [s] add s d

# cmp(2, 32)
imm(0x20, 0x71)
ldm(32, 32)
imm(2, 0x51)
ldm(2, 2)
imm(0x40, 0x9D)
add(2, 0x40)
stm(1, 2) # [s] STM *s = a
add(1, 0x10) # [s] add s d

# cmp(2, 32)
imm(0x20, 0x72)
ldm(32, 32)
imm(2, 0x52)
ldm(2, 2)
imm(0x40, 0x89)
add(2, 0x40)
stm(1, 2) # [s] STM *s = a
add(1, 0x10) # [s] add s d

# cmp(2, 32)
imm(0x20, 0x73)
ldm(32, 32)
imm(2, 0x53)
ldm(2, 2)
imm(0x40, 0xDC)
add(2, 0x40)
stm(1, 2) # [s] STM *s = a
add(1, 0x10) # [s] add s d

# cmp(2, 32)
imm(0x20, 0x74)
ldm(32, 32)
imm(2, 0x54)
ldm(2, 2)
imm(0x40, 7)
add(2, 0x40)
stm(1, 2) # [s] STM *s = a
add(1, 0x10) # [s] add s d

# cmp(2, 32)
imm(0x20, 0x75)
ldm(32, 32)
imm(2, 0x55)
ldm(2, 2)
imm(0x40, 0xA9)
add(2, 0x40)
stm(1, 2) # [s] STM *s = a
add(1, 0x10) # [s] add s d

# cmp(2, 32)
print(a1[0x6d: 0x6d + 9])
print(a1[0x4d: 0x4d + 9])
for i in range(9):
a1[i] = a1[0x6d + i] - a1[0x4d + i]
print(a1[:9])

根据描述可以知道寄存器a,b,c,d,s,i,f分别是哪些16进制数代表的。所以就可以用上去,把中间值存起来,最后做一个减法就行了。

最后记得一点,就是有一个小于-128的负数,我们加上256,而不是加128。因为原本的数是因为大于256才溢出成为负数的。那么同理,减法也是减去256而不是128。

level18.1

a1[121]接收用户输入,目标字符串在a1[153];从逻辑上很容易看出来,这道题是在目标字符串上加了一个数。所以,这里我们需要修改上题的逻辑,把加之后的数据依然保存在原来的a1[153]开始的连续地址处就行了。最后再打印出来,转成字节序发送即可。

level19.0

原来,这里才开始是vmcode啊。

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x20 arg1:0x1 arg2:0x52 // opcode:0x20 IMM
[s] IMM d = 0x52
[V] a:0 b:0 c:0 d:0x52 s:0 i:0x2 f:0
[I] op:0x4 arg1:0x20 arg2:0x1 // opcode:0x4 STK
[s] STK i d
[s] ... pushing d
[s] ... popping i
[V] a:0 b:0 c:0 d:0x52 s:0 i:0x53 f:0
[I] op:0x20 arg1:0x1 arg2:0x6a
[s] IMM d = 0x6a
[V] a:0 b:0 c:0 d:0x6a s:0 i:0x54 f:0
[I] op:0x20 arg1:0x8 arg2:0x9c
[s] IMM c = 0x9c
[V] a:0 b:0 c:0x9c d:0x6a s:0 i:0x55 f:0
[I] op:0x8 arg1:0x8 arg2:0x1
[s] STM *c = d // a1[0x9c] = 0x6a
[V] a:0 b:0 c:0x9c d:0x6a s:0 i:0x56 f:0
[I] op:0x20 arg1:0x1 arg2:0x39
[s] IMM d = 0x39
[V] a:0 b:0 c:0x9c d:0x39 s:0 i:0x57 f:0
[I] op:0x20 arg1:0x8 arg2:0x9d
[s] IMM c = 0x9d
[V] a:0 b:0 c:0x9d d:0x39 s:0 i:0x58 f:0
[I] op:0x8 arg1:0x8 arg2:0x1
[s] STM *c = d // a1[0x9d] = 0x39
[V] a:0 b:0 c:0x9d d:0x39 s:0 i:0x59 f:0
[I] op:0x20 arg1:0x1 arg2:0xf2
[s] IMM d = 0xf2
[V] a:0 b:0 c:0x9d d:0xf2 s:0 i:0x5a f:0
[I] op:0x20 arg1:0x8 arg2:0x9e
[s] IMM c = 0x9e
[V] a:0 b:0 c:0x9e d:0xf2 s:0 i:0x5b f:0
[I] op:0x8 arg1:0x8 arg2:0x1
[s] STM *c = d
[V] a:0 b:0 c:0x9e d:0xf2 s:0 i:0x5c f:0
[I] op:0x20 arg1:0x1 arg2:0x34
[s] IMM d = 0x34
[V] a:0 b:0 c:0x9e d:0x34 s:0 i:0x5d f:0
[I] op:0x20 arg1:0x8 arg2:0x9f
[s] IMM c = 0x9f
[V] a:0 b:0 c:0x9f d:0x34 s:0 i:0x5e f:0
[I] op:0x8 arg1:0x8 arg2:0x1
[s] STM *c = d
[V] a:0 b:0 c:0x9f d:0x34 s:0 i:0x5f f:0
[I] op:0x20 arg1:0x1 arg2:0x50
[s] IMM d = 0x50
[V] a:0 b:0 c:0x9f d:0x50 s:0 i:0x60 f:0
[I] op:0x20 arg1:0x8 arg2:0xa0
[s] IMM c = 0xa0
[V] a:0 b:0 c:0xa0 d:0x50 s:0 i:0x61 f:0
[I] op:0x8 arg1:0x8 arg2:0x1
[s] STM *c = d
[V] a:0 b:0 c:0xa0 d:0x50 s:0 i:0x62 f:0
[I] op:0x20 arg1:0x1 arg2:0x39
[s] IMM d = 0x39
[V] a:0 b:0 c:0xa0 d:0x39 s:0 i:0x63 f:0
[I] op:0x20 arg1:0x8 arg2:0xa1
[s] IMM c = 0xa1
[V] a:0 b:0 c:0xa1 d:0x39 s:0 i:0x64 f:0
[I] op:0x8 arg1:0x8 arg2:0x1
[s] STM *c = d
[V] a:0 b:0 c:0xa1 d:0x39 s:0 i:0x65 f:0
[I] op:0x20 arg1:0x1 arg2:0x38
[s] IMM d = 0x38
[V] a:0 b:0 c:0xa1 d:0x38 s:0 i:0x66 f:0
[I] op:0x20 arg1:0x8 arg2:0xa2
[s] IMM c = 0xa2
[V] a:0 b:0 c:0xa2 d:0x38 s:0 i:0x67 f:0
[I] op:0x8 arg1:0x8 arg2:0x1
[s] STM *c = d
[V] a:0 b:0 c:0xa2 d:0x38 s:0 i:0x68 f:0
[I] op:0x20 arg1:0x1 arg2:0xbf
[s] IMM d = 0xbf
[V] a:0 b:0 c:0xa2 d:0xbf s:0 i:0x69 f:0
[I] op:0x20 arg1:0x8 arg2:0xa3
[s] IMM c = 0xa3
[V] a:0 b:0 c:0xa3 d:0xbf s:0 i:0x6a f:0
[I] op:0x8 arg1:0x8 arg2:0x1
[s] STM *c = d
[V] a:0 b:0 c:0xa3 d:0xbf s:0 i:0x6b f:0
[I] op:0x20 arg1:0x1 arg2:0xee
[s] IMM d = 0xee
[V] a:0 b:0 c:0xa3 d:0xee s:0 i:0x6c f:0
[I] op:0x20 arg1:0x8 arg2:0xa4
[s] IMM c = 0xa4
[V] a:0 b:0 c:0xa4 d:0xee s:0 i:0x6d f:0
[I] op:0x8 arg1:0x8 arg2:0x1
[s] STM *c = d
[V] a:0 b:0 c:0xa4 d:0xee s:0 i:0x6e f:0
[I] op:0x20 arg1:0x1 arg2:0xd8
[s] IMM d = 0xd8
[V] a:0 b:0 c:0xa4 d:0xd8 s:0 i:0x6f f:0
[I] op:0x20 arg1:0x8 arg2:0xa5
[s] IMM c = 0xa5
[V] a:0 b:0 c:0xa5 d:0xd8 s:0 i:0x70 f:0
[I] op:0x8 arg1:0x8 arg2:0x1
[s] STM *c = d
[V] a:0 b:0 c:0xa5 d:0xd8 s:0 i:0x71 f:0
[I] op:0x20 arg1:0x1 arg2:0x65
[s] IMM d = 0x65
[V] a:0 b:0 c:0xa5 d:0x65 s:0 i:0x72 f:0
[I] op:0x20 arg1:0x8 arg2:0xa6
[s] IMM c = 0xa6
[V] a:0 b:0 c:0xa6 d:0x65 s:0 i:0x73 f:0
[I] op:0x8 arg1:0x8 arg2:0x1
[s] STM *c = d
[V] a:0 b:0 c:0xa6 d:0x65 s:0 i:0x74 f:0
[I] op:0x20 arg1:0x1 arg2:0xe0
[s] IMM d = 0xe0
[V] a:0 b:0 c:0xa6 d:0xe0 s:0 i:0x75 f:0
[I] op:0x20 arg1:0x8 arg2:0xa7
[s] IMM c = 0xa7
[V] a:0 b:0 c:0xa7 d:0xe0 s:0 i:0x76 f:0
[I] op:0x8 arg1:0x8 arg2:0x1
[s] STM *c = d
[V] a:0 b:0 c:0xa7 d:0xe0 s:0 i:0x77 f:0
[I] op:0x20 arg1:0x1 arg2:0x15
[s] IMM d = 0x15
[V] a:0 b:0 c:0xa7 d:0x15 s:0 i:0x78 f:0
[I] op:0x20 arg1:0x8 arg2:0xa8
[s] IMM c = 0xa8
[V] a:0 b:0 c:0xa8 d:0x15 s:0 i:0x79 f:0
[I] op:0x8 arg1:0x8 arg2:0x1
[s] STM *c = d
[V] a:0 b:0 c:0xa8 d:0x15 s:0 i:0x7a f:0
[I] op:0x20 arg1:0x1 arg2:0x6b
[s] IMM d = 0x6b
[V] a:0 b:0 c:0xa8 d:0x6b s:0 i:0x7b f:0
[I] op:0x20 arg1:0x8 arg2:0xa9
[s] IMM c = 0xa9
[V] a:0 b:0 c:0xa9 d:0x6b s:0 i:0x7c f:0
[I] op:0x8 arg1:0x8 arg2:0x1
[s] STM *c = d // a1[0xa9] = 0x6b
[V] a:0 b:0 c:0xa9 d:0x6b s:0 i:0x7d f:0
[I] op:0x20 arg1:0x20 arg2:0x8a
[s] IMM i = 0x8a
[V] a:0 b:0 c:0xa9 d:0x6b s:0 i:0x8b f:0
[I] op:0x4 arg1:0 arg2:0x4
[s] STK NONE a
[s] ... pushing a // [0]
[V] a:0 b:0 c:0xa9 d:0x6b s:0x1 i:0x8c f:0
[I] op:0x4 arg1:0 arg2:0x2
[s] STK NONE b
[s] ... pushing b // [0,0]
[V] a:0 b:0 c:0xa9 d:0x6b s:0x2 i:0x8d f:0
[I] op:0x4 arg1:0 arg2:0x8
[s] STK NONE c
[s] ... pushing c // [0xa9,0,0]
[V] a:0 b:0 c:0xa9 d:0x6b s:0x3 i:0x8e f:0
[I] op:0x20 arg1:0x2 arg2:0x1
[s] IMM b = 0x1
[V] a:0 b:0x1 c:0xa9 d:0x6b s:0x3 i:0x8f f:0
[I] op:0x10 arg1:0x2 arg2:0x40
[s] ADD b s
[V] a:0 b:0x4 c:0xa9 d:0x6b s:0x3 i:0x90 f:0
[I] op:0x20 arg1:0x1 arg2:0x4b
[s] IMM d = 0x4b
[V] a:0 b:0x4 c:0xa9 d:0x4b s:0x3 i:0x91 f:0
[I] op:0x4 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d // [0x4b, 0xa9,0,0]
[V] a:0 b:0x4 c:0xa9 d:0x4b s:0x4 i:0x92 f:0
[I] op:0x20 arg1:0x1 arg2:0x45
[s] IMM d = 0x45
[V] a:0 b:0x4 c:0xa9 d:0x45 s:0x4 i:0x93 f:0
[I] op:0x4 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d // [0x45,0x4b, 0xa9,0,0]
[V] a:0 b:0x4 c:0xa9 d:0x45 s:0x5 i:0x94 f:0
[I] op:0x20 arg1:0x1 arg2:0x59
[s] IMM d = 0x59
[V] a:0 b:0x4 c:0xa9 d:0x59 s:0x5 i:0x95 f:0
[I] op:0x4 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d // [0x59,0x45,0x4b, 0xa9,0,0]
[V] a:0 b:0x4 c:0xa9 d:0x59 s:0x6 i:0x96 f:0
[I] op:0x20 arg1:0x1 arg2:0x3a
[s] IMM d = 0x3a
[V] a:0 b:0x4 c:0xa9 d:0x3a s:0x6 i:0x97 f:0
[I] op:0x4 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d // [0x3a,0x59,0x45,0x4b, 0xa9,0,0]
[V] a:0 b:0x4 c:0xa9 d:0x3a s:0x7 i:0x98 f:0
[I] op:0x20 arg1:0x1 arg2:0x20
[s] IMM d = 0x20
[V] a:0 b:0x4 c:0xa9 d:0x20 s:0x7 i:0x99 f:0
[I] op:0x4 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d // [0x20,0x3a,0x59,0x45,0x4b, 0xa9,0,0]
[V] a:0 b:0x4 c:0xa9 d:0x20 s:0x8 i:0x9a f:0
[I] op:0x20 arg1:0x8 arg2:0x5
[s] IMM c = 0x5
[V] a:0 b:0x4 c:0x5 d:0x20 s:0x8 i:0x9b f:0
[I] op:0x20 arg1:0x4 arg2:0x1
[s] IMM a = 0x1
[V] a:0x1 b:0x4 c:0x5 d:0x20 s:0x8 i:0x9c f:0
[I] op:0x1 arg1:0x8 arg2:0x1
[s] SYS 0x8 d
[s] ... write
KEY: [s] ... return value (in register d): 0x5
[V] a:0x1 b:0x4 c:0x5 d:0x5 s:0x8 i:0x9d f:0
[I] op:0x4 arg1:0x8 arg2:0
[s] STK c NONE
[s] ... popping c // c = 0x20
[V] a:0x1 b:0x4 c:0x20 d:0x5 s:0x7 i:0x9e f:0
[I] op:0x4 arg1:0x2 arg2:0
[s] STK b NONE
[s] ... popping b // b = 0x3a
[V] a:0x1 b:0x3a c:0x20 d:0x5 s:0x6 i:0x9f f:0
[I] op:0x4 arg1:0x4 arg2:0
[s] STK a NONE
[s] ... popping a // a = 0x59
[V] a:0x59 b:0x3a c:0x20 d:0x5 s:0x5 i:0xa0 f:0
[I] op:0x4 arg1:0 arg2:0x4
[s] STK NONE a
[s] ... pushing a // [0x59,0x45,0x4b, 0xa9,0,0]
[V] a:0x59 b:0x3a c:0x20 d:0x5 s:0x6 i:0xa1 f:0
[I] op:0x4 arg1:0 arg2:0x2
[s] STK NONE b
[s] ... pushing b // [0x3a,0x59,0x45,0x4b, 0xa9,0,0]
[V] a:0x59 b:0x3a c:0x20 d:0x5 s:0x7 i:0xa2 f:0
[I] op:0x4 arg1:0 arg2:0x8
[s] STK NONE c
[s] ... pushing c // [0x20,0x3a,0x59,0x45,0x4b, 0xa9,0,0]
[V] a:0x59 b:0x3a c:0x20 d:0x5 s:0x8 i:0xa3 f:0
[I] op:0x20 arg1:0x2 arg2:0x30
[s] IMM b = 0x30
[V] a:0x59 b:0x30 c:0x20 d:0x5 s:0x8 i:0xa4 f:0
[I] op:0x20 arg1:0x8 arg2:0xe
[s] IMM c = 0xe
[V] a:0x59 b:0x30 c:0xe d:0x5 s:0x8 i:0xa5 f:0
[I] op:0x20 arg1:0x4 arg2:0
[s] IMM a = 0
[V] a:0 b:0x30 c:0xe d:0x5 s:0x8 i:0xa6 f:0
[I] op:0x1 arg1:0x4 arg2:0x1
[s] SYS 0x4 d
[s] ... read_memory
1

上面的是接受用户输入前的代码,下面的是接收用户输入后的处理逻辑。

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
[s] ... return value (in register d): 0x2
[V] a:0 b:0x30 c:0xe d:0x2 s:0x8 i:0xa7 f:0
[I] op:0x4 arg1:0x8 arg2:0
[s] STK c NONE
[s] ... popping c // c = 0x20 [0x3a,0x59,0x45,0x4b, 0xa9,0,0]
[V] a:0 b:0x30 c:0x20 d:0x2 s:0x7 i:0xa8 f:0
[I] op:0x4 arg1:0x2 arg2:0
[s] STK b NONE
[s] ... popping b // b = 0x3a [0x59,0x45,0x4b, 0xa9,0,0]
[V] a:0 b:0x3a c:0x20 d:0x2 s:0x6 i:0xa9 f:0
[I] op:0x4 arg1:0x4 arg2:0
[s] STK a NONE
[s] ... popping a // a = 0x59 [0x45,0x4b, 0xa9,0,0]
[V] a:0x59 b:0x3a c:0x20 d:0x2 s:0x5 i:0xaa f:0
[I] op:0x20 arg1:0x20 arg2:0xaa
[s] IMM i = 0xaa
[V] a:0x59 b:0x3a c:0x20 d:0x2 s:0x5 i:0xab f:0
[I] op:0x4 arg1:0 arg2:0x4
[s] STK NONE a
[s] ... pushing a // [0x59,0x45,0x4b, 0xa9,0,0]
[V] a:0x59 b:0x3a c:0x20 d:0x2 s:0x6 i:0xac f:0
[I] op:0x4 arg1:0 arg2:0x2
[s] STK NONE b
[s] ... pushing b // [0x3a,0x59,0x45,0x4b, 0xa9,0,0]
[V] a:0x59 b:0x3a c:0x20 d:0x2 s:0x7 i:0xad f:0
[I] op:0x4 arg1:0 arg2:0x8
[s] STK NONE c
[s] ... pushing c // [0x20,0x3a,0x59,0x45,0x4b, 0xa9,0,0]
[V] a:0x59 b:0x3a c:0x20 d:0x2 s:0x8 i:0xae f:0
[I] op:0x4 arg1:0x8 arg2:0
[s] STK c NONE
[s] ... popping c
[V] a:0x59 b:0x3a c:0x20 d:0x2 s:0x7 i:0xaf f:0
[I] op:0x4 arg1:0x2 arg2:0
[s] STK b NONE
[s] ... popping b
[V] a:0x59 b:0x3a c:0x20 d:0x2 s:0x6 i:0xb0 f:0
[I] op:0x4 arg1:0x4 arg2:0
[s] STK a NONE
[s] ... popping a // [0x45,0x4b, 0xa9,0,0]
[V] a:0x59 b:0x3a c:0x20 d:0x2 s:0x5 i:0xb1 f:0
[I] op:0x20 arg1:0x20 arg2:0x7d
[s] IMM i = 0x7d
[V] a:0x59 b:0x3a c:0x20 d:0x2 s:0x5 i:0x7e f:0
[I] op:0x20 arg1:0x4 arg2:0x30
[s] IMM a = 0x30
[V] a:0x30 b:0x3a c:0x20 d:0x2 s:0x5 i:0x7f f:0
[I] op:0x20 arg1:0x2 arg2:0x9e
[s] IMM b = 0x9e
[V] a:0x30 b:0x9e c:0x20 d:0x2 s:0x5 i:0x80 f:0
[I] op:0x20 arg1:0x8 arg2:0xc
[s] IMM c = 0xc
[V] a:0x30 b:0x9e c:0xc d:0x2 s:0x5 i:0x81 f:0
[I] op:0x20 arg1:0x1 arg2:0x2
[s] IMM d = 0x2
[V] a:0x30 b:0x9e c:0xc d:0x2 s:0x5 i:0x82 f:0
[I] op:0x10 arg1:0x1 arg2:0x20
[s] ADD d i
[V] a:0x30 b:0x9e c:0xc d:0x84 s:0x5 i:0x83 f:0
[I] op:0x4 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d // [0x84,0x45,0x4b, 0xa9,0,0]
[V] a:0x30 b:0x9e c:0xc d:0x84 s:0x6 i:0x84 f:0
[I] op:0x20 arg1:0x20 arg2:0xce
[s] IMM i = 0xce
[V] a:0x30 b:0x9e c:0xc d:0x84 s:0x6 i:0xcf f:0
[I] op:0x10 arg1:0x4 arg2:0x8
[s] ADD a c
[V] a:0x3c b:0x9e c:0xc d:0x84 s:0x6 i:0xd0 f:0
[I] op:0x10 arg1:0x2 arg2:0x8
[s] ADD b c
[V] a:0x3c b:0xaa c:0xc d:0x84 s:0x6 i:0xd1 f:0
[I] op:0x20 arg1:0x1 arg2:0xff
[s] IMM d = 0xff
[V] a:0x3c b:0xaa c:0xc d:0xff s:0x6 i:0xd2 f:0
[I] op:0x10 arg1:0x4 arg2:0x1
[s] ADD a d
[V] a:0x3b b:0xaa c:0xc d:0xff s:0x6 i:0xd3 f:0
[I] op:0x10 arg1:0x2 arg2:0x1
[s] ADD b d
[V] a:0x3b b:0xa9 c:0xc d:0xff s:0x6 i:0xd4 f:0
[I] op:0x4 arg1:0 arg2:0x4
[s] STK NONE a
[s] ... pushing a // [0x3b,0x84,0x45,0x4b, 0xa9,0,0]
[V] a:0x3b b:0xa9 c:0xc d:0xff s:0x7 i:0xd5 f:0
[I] op:0x4 arg1:0 arg2:0x2
[s] STK NONE b
[s] ... pushing b // [0xa9,0x3b,0x84,0x45,0x4b, 0xa9,0,0]
[V] a:0x3b b:0xa9 c:0xc d:0xff s:0x8 i:0xd6 f:0
[I] op:0x2 arg1:0x4 arg2:0x4
[s] LDM a = *a // a = a1[0x3b] = 0
[V] a:0 b:0xa9 c:0xc d:0xff s:0x8 i:0xd7 f:0
[I] op:0x2 arg1:0x2 arg2:0x2
[s] LDM b = *b // b = a1[0xa9] = 0x6b
[V] a:0 b:0x6b c:0xc d:0xff s:0x8 i:0xd8 f:0
[I] op:0x80 arg1:0x4 arg2:0x2
[s] CMP a b
[V] a:0 b:0x6b c:0xc d:0xff s:0x8 i:0xd9 f:0xc
[I] op:0x4 arg1:0x2 arg2:0
[s] STK b NONE
[s] ... popping b
[V] a:0 b:0xa9 c:0xc d:0xff s:0x7 i:0xda f:0xc
[I] op:0x4 arg1:0x4 arg2:0
[s] STK a NONE
[s] ... popping a
[V] a:0x3b b:0xa9 c:0xc d:0xff s:0x6 i:0xdb f:0xc
[I] op:0x20 arg1:0x1 arg2:0xe2
[s] IMM d = 0xe2
[V] a:0x3b b:0xa9 c:0xc d:0xe2 s:0x6 i:0xdc f:0xc
[I] op:0x40 arg1:0x4 arg2:0x1
[j] JMP N d
[j] ... TAKEN
[V] a:0x3b b:0xa9 c:0xc d:0xe2 s:0x6 i:0xe3 f:0xc
[I] op:0x4 arg1:0x1 arg2:0x8
[s] STK d c
[s] ... pushing c
[s] ... popping d
[V] a:0x3b b:0xa9 c:0xc d:0xc s:0x6 i:0xe4 f:0xc
[I] op:0x4 arg1:0x20 arg2:0
[s] STK i NONE
[s] ... popping i
[V] a:0x3b b:0xa9 c:0xc d:0xc s:0x5 i:0x85 f:0xc
[I] op:0x20 arg1:0x8 arg2:0
[s] IMM c = 0
[V] a:0x3b b:0xa9 c:0 d:0xc s:0x5 i:0x86 f:0xc
[I] op:0x80 arg1:0x1 arg2:0x8
[s] CMP d c
[V] a:0x3b b:0xa9 c:0 d:0xc s:0x5 i:0x87 f:0x6
[I] op:0x20 arg1:0x1 arg2:0x2
[s] IMM d = 0x2
[V] a:0x3b b:0xa9 c:0 d:0x2 s:0x5 i:0x88 f:0x6
[I] op:0x40 arg1:0x10 arg2:0x1
[j] JMP E d
[j] ... NOT TAKEN
[V] a:0x3b b:0xa9 c:0 d:0x2 s:0x5 i:0x89 f:0x6
[I] op:0x20 arg1:0x1 arg2:0xb1
[s] IMM d = 0xb1
[V] a:0x3b b:0xa9 c:0 d:0xb1 s:0x5 i:0x8a f:0x6
[I] op:0x40 arg1:0xa arg2:0x1
[j] JMP LG d
[j] ... TAKEN
[V] a:0x3b b:0xa9 c:0 d:0xb1 s:0x5 i:0xb2 f:0x6
[I] op:0x20 arg1:0x2 arg2:0x1
[s] IMM b = 0x1
[V] a:0x3b b:0x1 c:0 d:0xb1 s:0x5 i:0xb3 f:0x6
[I] op:0x10 arg1:0x2 arg2:0x40
[s] ADD b s
[V] a:0x3b b:0x6 c:0 d:0xb1 s:0x5 i:0xb4 f:0x6
[I] op:0x20 arg1:0x1 arg2:0x49
[s] IMM d = 0x49
[V] a:0x3b b:0x6 c:0 d:0x49 s:0x5 i:0xb5 f:0x6
[I] op:0x4 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d
[V] a:0x3b b:0x6 c:0 d:0x49 s:0x6 i:0xb6 f:0x6
[I] op:0x20 arg1:0x1 arg2:0x4e
[s] IMM d = 0x4e
[V] a:0x3b b:0x6 c:0 d:0x4e s:0x6 i:0xb7 f:0x6
[I] op:0x4 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d
[V] a:0x3b b:0x6 c:0 d:0x4e s:0x7 i:0xb8 f:0x6
[I] op:0x20 arg1:0x1 arg2:0x43
[s] IMM d = 0x43
[V] a:0x3b b:0x6 c:0 d:0x43 s:0x7 i:0xb9 f:0x6
[I] op:0x4 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d
[V] a:0x3b b:0x6 c:0 d:0x43 s:0x8 i:0xba f:0x6
[I] op:0x20 arg1:0x1 arg2:0x4f
[s] IMM d = 0x4f
[V] a:0x3b b:0x6 c:0 d:0x4f s:0x8 i:0xbb f:0x6
[I] op:0x4 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d
[V] a:0x3b b:0x6 c:0 d:0x4f s:0x9 i:0xbc f:0x6
[I] op:0x20 arg1:0x1 arg2:0x52
[s] IMM d = 0x52
[V] a:0x3b b:0x6 c:0 d:0x52 s:0x9 i:0xbd f:0x6
[I] op:0x4 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d
[V] a:0x3b b:0x6 c:0 d:0x52 s:0xa i:0xbe f:0x6
[I] op:0x20 arg1:0x1 arg2:0x52
[s] IMM d = 0x52
[V] a:0x3b b:0x6 c:0 d:0x52 s:0xa i:0xbf f:0x6
[I] op:0x4 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d
[V] a:0x3b b:0x6 c:0 d:0x52 s:0xb i:0xc0 f:0x6
[I] op:0x20 arg1:0x1 arg2:0x45
[s] IMM d = 0x45
[V] a:0x3b b:0x6 c:0 d:0x45 s:0xb i:0xc1 f:0x6
[I] op:0x4 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d
[V] a:0x3b b:0x6 c:0 d:0x45 s:0xc i:0xc2 f:0x6
[I] op:0x20 arg1:0x1 arg2:0x43
[s] IMM d = 0x43
[V] a:0x3b b:0x6 c:0 d:0x43 s:0xc i:0xc3 f:0x6
[I] op:0x4 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d
[V] a:0x3b b:0x6 c:0 d:0x43 s:0xd i:0xc4 f:0x6
[I] op:0x20 arg1:0x1 arg2:0x54
[s] IMM d = 0x54
[V] a:0x3b b:0x6 c:0 d:0x54 s:0xd i:0xc5 f:0x6
[I] op:0x4 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d
[V] a:0x3b b:0x6 c:0 d:0x54 s:0xe i:0xc6 f:0x6
[I] op:0x20 arg1:0x1 arg2:0x21
[s] IMM d = 0x21
[V] a:0x3b b:0x6 c:0 d:0x21 s:0xe i:0xc7 f:0x6
[I] op:0x4 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d
[V] a:0x3b b:0x6 c:0 d:0x21 s:0xf i:0xc8 f:0x6
[I] op:0x20 arg1:0x1 arg2:0xa
[s] IMM d = 0xa
[V] a:0x3b b:0x6 c:0 d:0xa s:0xf i:0xc9 f:0x6
[I] op:0x4 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d
[V] a:0x3b b:0x6 c:0 d:0xa s:0x10 i:0xca f:0x6
[I] op:0x20 arg1:0x8 arg2:0xb
[s] IMM c = 0xb
[V] a:0x3b b:0x6 c:0xb d:0xa s:0x10 i:0xcb f:0x6
[I] op:0x20 arg1:0x4 arg2:0x1
[s] IMM a = 0x1
[V] a:0x1 b:0x6 c:0xb d:0xa s:0x10 i:0xcc f:0x6
[I] op:0x1 arg1:0x8 arg2:0x1
[s] SYS 0x8 d
[s] ... write
INCORRECT!
[s] ... return value (in register d): 0xb
[V] a:0x1 b:0x6 c:0xb d:0xb s:0x10 i:0xcd f:0x6
[I] op:0x20 arg1:0x4 arg2:0x1
[s] IMM a = 0x1
[V] a:0x1 b:0x6 c:0xb d:0xb s:0x10 i:0xce f:0x6
[I] op:0x1 arg1:0x20 arg2:0
[s] SYS 0x20 NONE
[s] ... exit

还挺复杂的…下面的是idapro的逆向源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
void __fastcall __noreturn interpreter_loop(__int64 a1)
{
unsigned __int8 v1; // al

while ( 1 )
{
v1 = *(_BYTE *)(a1 + 1029);
*(_BYTE *)(a1 + 1029) = v1 + 1;
interpret_instruction(
a1,
*(unsigned __int16 *)(a1 + 3LL * v1) | ((unsigned __int64)*(unsigned __int8 *)(a1 + 3LL * v1 + 2) << 16));
}
}
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
__int64 __fastcall interpret_instruction(unsigned __int8 *a1, __int64 a2)
{
__int64 result; // rax

printf(
"[V] a:%#hhx b:%#hhx c:%#hhx d:%#hhx s:%#hhx i:%#hhx f:%#hhx\n",
a1[1024],
a1[1025],
a1[1026],
a1[1027],
a1[1028],
a1[1029],
a1[1030]);
printf("[I] op:%#hhx arg1:%#hhx arg2:%#hhx\n", BYTE2(a2), (unsigned __int8)a2, BYTE1(a2));
if ( (a2 & 0x200000) != 0 )
interpret_imm(a1, a2);
if ( (a2 & 0x100000) != 0 )
interpret_add(a1, a2);
if ( (a2 & 0x40000) != 0 )
interpret_stk(a1, a2);
if ( (a2 & 0x80000) != 0 )
interpret_stm(a1, a2);
if ( (a2 & 0x20000) != 0 )
interpret_ldm(a1, a2);
if ( (a2 & 0x800000) != 0 )
interpret_cmp(a1, a2);
if ( (a2 & 0x400000) != 0 )
interpret_jmp(a1, a2);
result = BYTE2(a2) & 1;
if ( (a2 & 0x10000) != 0 )
return interpret_sys(a1, a2);
return result;
}

看一下新操作STK所做的操作:

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
__int64 __fastcall interpret_stk(__int64 a1, __int16 a2)
{
const char *v2; // rbx
const char *v3; // rax
const char *v4; // rax
unsigned __int8 v5; // al
__int64 result; // rax
const char *v7; // rax
unsigned __int8 memory; // al

v2 = (const char *)describe_register(HIBYTE(a2));
v3 = (const char *)describe_register((unsigned __int8)a2);
printf("[s] STK %s %s\n", v3, v2);
if ( HIBYTE(a2) )
{
v4 = (const char *)describe_register(HIBYTE(a2));
printf("[s] ... pushing %s\n", v4);
++*(_BYTE *)(a1 + 1028);
v5 = read_register(a1, HIBYTE(a2));
write_memory(a1, *(unsigned __int8 *)(a1 + 1028), v5);
}
result = (unsigned __int8)a2;
if ( (_BYTE)a2 )
{
v7 = (const char *)describe_register((unsigned __int8)a2);
printf("[s] ... popping %s\n", v7);
memory = read_memory(a1, *(unsigned __int8 *)(a1 + 1028));
write_register(a1, (unsigned __int8)a2, memory);
result = a1;
--*(_BYTE *)(a1 + 1028);
}
return result;
}

可以看出,这是模拟栈,并且把栈地址设置为a1[1028]

最后做出来,感觉不太需要关心这个栈,其实只需要看CMP指令,然后发现它第一个比较的数是a1[0x3b]a1[0xa9],第二个比较的数是a1[3a]a1[a8]。一个逆序比较,那么不用管,只需要调整一下顺序就可以了。把前俩放到最后就行了。

level19.1

我们通过gdb脚本,然后拿到对应的opcode以及arg1和arg2。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
b *0x589192137cd1
set $fd = fopen("/home/hacker/Desktop/rsi.txt","w")

while 1
set $rsi_value = $rsi
set $a = *(unsigned char*)($rax + 0x400)
set $b = *(unsigned char*)($rax + 0x401)
set $c = *(unsigned char*)($rax + 0x402)
set $d = *(unsigned char*)($rax + 0x403)
set $s = *(unsigned char*)($rax + 0x404)
set $i = *(unsigned char*)($rax + 0x405)
set $f = *(unsigned char*)($rax + 0x406)
call fprintf($fd,"a:%x b:%x c:%x d:%x s:%x i:%x f:%x\n", $a,$b,$c,$d,$s,$i,$f)
call fprintf($fd, "0x%lx\n", $rsi_value)

continue
end

call fclose($fd)
quit

这个break的地址是通过gdb调试过程中拿到的,其实就是死循环中调用的那个函数的call指令的地址。然后,$rax在这时存储的是a1的首地址,然后我们发现偏移地址就是+0x403,这可以通过调试或者19.0这个level拿到。然后,就打印出来a,b,c,d,s,i,f变量的值。以此来判断,我们要发送的字符串,以及其做的代码混淆处理。

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
a:0 b:0 c:0 d:0 s:0 i:1 f:0
0x20402
a:0 b:0 c:0 d:2 s:0 i:2 f:0
0x801004
a:0 b:0 c:0 d:2 s:0 i:3 f:0
0x204c2
a:0 b:0 c:0 d:c2 s:0 i:4 f:0
0x2206c
a:0 b:0 c:6c d:c2 s:0 i:5 f:0
0x402004
a:0 b:0 c:6c d:c2 s:0 i:6 f:0
0x2044d
a:0 b:0 c:6c d:4d s:0 i:7 f:0
0x2206d
a:0 b:0 c:6d d:4d s:0 i:8 f:0
0x402004
a:0 b:0 c:6d d:4d s:0 i:9 f:0
0x20442
a:0 b:0 c:6d d:42 s:0 i:a f:0
0x2206e
a:0 b:0 c:6e d:42 s:0 i:b f:0
0x402004
a:0 b:0 c:6e d:42 s:0 i:c f:0
0x20482
a:0 b:0 c:6e d:82 s:0 i:d f:0
0x2206f
a:0 b:0 c:6f d:82 s:0 i:e f:0
0x402004
a:0 b:0 c:6f d:82 s:0 i:f f:0
0x2042d
a:0 b:0 c:6f d:2d s:0 i:10 f:0
0x22070
a:0 b:0 c:70 d:2d s:0 i:11 f:0
0x402004
a:0 b:0 c:70 d:2d s:0 i:12 f:0
0x204e5
a:0 b:0 c:70 d:e5 s:0 i:13 f:0
0x22071
a:0 b:0 c:71 d:e5 s:0 i:14 f:0
0x402004
a:0 b:0 c:71 d:e5 s:0 i:15 f:0
0x20464
a:0 b:0 c:71 d:64 s:0 i:16 f:0
0x22072
a:0 b:0 c:72 d:64 s:0 i:17 f:0
0x402004
a:0 b:0 c:72 d:64 s:0 i:18 f:0
0x20498
a:0 b:0 c:72 d:98 s:0 i:19 f:0
0x22073
a:0 b:0 c:73 d:98 s:0 i:1a f:0
0x402004
a:0 b:0 c:73 d:98 s:0 i:1b f:0
0x204f7
a:0 b:0 c:73 d:f7 s:0 i:1c f:0
0x22074
a:0 b:0 c:74 d:f7 s:0 i:1d f:0
0x402004
a:0 b:0 c:74 d:f7 s:0 i:1e f:0
0x204ac
a:0 b:0 c:74 d:ac s:0 i:1f f:0
0x22075
a:0 b:0 c:75 d:ac s:0 i:20 f:0
0x402004
a:0 b:0 c:75 d:ac s:0 i:21 f:0
0x20465
a:0 b:0 c:75 d:65 s:0 i:22 f:0
0x22076
a:0 b:0 c:76 d:65 s:0 i:23 f:0
0x402004
a:0 b:0 c:76 d:65 s:0 i:24 f:0
0x21024
a:0 b:0 c:76 d:65 s:0 i:25 f:0
0x800002
a:0 b:0 c:76 d:65 s:1 i:26 f:0
0x800040
a:0 b:0 c:76 d:65 s:2 i:27 f:0
0x800020
a:0 b:0 c:76 d:65 s:3 i:28 f:0
0x24001
a:0 b:1 c:76 d:65 s:3 i:29 f:0
0x14008
a:0 b:4 c:76 d:65 s:3 i:2a f:0
0x2044b
a:0 b:4 c:76 d:4b s:3 i:2b f:0
0x800004
a:0 b:4 c:76 d:4b s:4 i:2c f:0
0x20445
a:0 b:4 c:76 d:45 s:4 i:2d f:0
0x800004
a:0 b:4 c:76 d:45 s:5 i:2e f:0
0x20459
a:0 b:4 c:76 d:59 s:5 i:2f f:0
0x800004
a:0 b:4 c:76 d:59 s:6 i:30 f:0
0x2043a
a:0 b:4 c:76 d:3a s:6 i:31 f:0
0x800004
a:0 b:4 c:76 d:3a s:7 i:32 f:0
0x20420
a:0 b:4 c:76 d:20 s:7 i:33 f:0
0x800004
a:0 b:4 c:76 d:20 s:8 i:34 f:0
0x22005
a:0 b:4 c:5 d:20 s:8 i:35 f:0
0x20201
a:1 b:4 c:5 d:20 s:8 i:36 f:0
0x100104
a:1 b:4 c:5 d:5 s:8 i:37 f:0
0x802000
a:1 b:4 c:20 d:5 s:7 i:38 f:0
0x804000
a:1 b:3a c:20 d:5 s:6 i:39 f:0
0x800200
a:59 b:3a c:20 d:5 s:5 i:3a f:0
0x800002
a:59 b:3a c:20 d:5 s:6 i:3b f:0
0x800040
a:59 b:3a c:20 d:5 s:7 i:3c f:0
0x800020
a:59 b:3a c:20 d:5 s:8 i:3d f:0
0x24030
a:59 b:30 c:20 d:5 s:8 i:3e f:0
0x2200b
a:59 b:30 c:b d:5 s:8 i:3f f:0
0x20200
a:0 b:30 c:b d:5 s:8 i:40 f:0
0x100404
a:0 b:30 c:b d:b s:8 i:41 f:0
0x802000
a:0 b:30 c:20 d:b s:7 i:42 f:0
0x804000
a:0 b:3a c:20 d:b s:6 i:43 f:0
0x800200
a:59 b:3a c:20 d:b s:5 i:44 f:0
0x21044
a:59 b:3a c:20 d:b s:5 i:45 f:0
0x800002
a:59 b:3a c:20 d:b s:6 i:46 f:0
0x800040
a:59 b:3a c:20 d:b s:7 i:47 f:0
0x800020
a:59 b:3a c:20 d:b s:8 i:48 f:0
0x802000
a:59 b:3a c:20 d:b s:7 i:49 f:0
0x804000
a:59 b:3a c:20 d:b s:6 i:4a f:0
0x800200
a:59 b:3a c:20 d:b s:5 i:4b f:0
0x210ce
a:59 b:3a c:20 d:b s:5 i:cf f:0
0x20230
a:30 b:3a c:20 d:b s:5 i:d0 f:0
0x2406e
a:30 b:6e c:20 d:b s:5 i:d1 f:0
0x22009
a:30 b:6e c:9 d:b s:5 i:d2 f:0
0x20402
a:30 b:6e c:9 d:2 s:5 i:d3 f:0
0x10410
a:30 b:6e c:9 d:d5 s:5 i:d4 f:0
0x800004
a:30 b:6e c:9 d:d5 s:6 i:d5 f:0
0x2109b
a:30 b:6e c:9 d:d5 s:6 i:9c f:0
0x10220
a:39 b:6e c:9 d:d5 s:6 i:9d f:0
0x14020
a:39 b:77 c:9 d:d5 s:6 i:9e f:0
0x204ff
a:39 b:77 c:9 d:ff s:6 i:9f f:0
0x10204
a:38 b:77 c:9 d:ff s:6 i:a0 f:0
0x14004
a:38 b:76 c:9 d:ff s:6 i:a1 f:0
0x800002
a:38 b:76 c:9 d:ff s:7 i:a2 f:0
0x800040
a:38 b:76 c:9 d:ff s:8 i:a3 f:0
0x80202
a:64 b:76 c:9 d:ff s:8 i:a4 f:0
0x84040
a:64 b:65 c:9 d:ff s:8 i:a5 f:0
0x200240 # cmp
a:64 b:65 c:9 d:ff s:8 i:a6 f:9
0x804000
a:64 b:76 c:9 d:ff s:7 i:a7 f:9
0x800200
a:38 b:76 c:9 d:ff s:6 i:a8 f:9
0x204af
a:38 b:76 c:9 d:af s:6 i:a9 f:9
0x40804
a:38 b:76 c:9 d:af s:6 i:b0 f:9
0x800420
a:38 b:76 c:9 d:9 s:6 i:b1 f:9
0x801000
a:38 b:76 c:9 d:9 s:5 i:d6 f:9
0x22000
a:38 b:76 c:0 d:9 s:5 i:d7 f:9
0x200420 # cmp
a:38 b:76 c:0 d:9 s:5 i:d8 f:18
0x2044b
a:38 b:76 c:0 d:4b s:5 i:d9 f:18
0x40404
a:38 b:76 c:0 d:4b s:5 i:da f:18
0x204b1
a:38 b:76 c:0 d:b1 s:5 i:db f:18
0x41104
a:38 b:76 c:0 d:b1 s:5 i:b2 f:18
0x24001
a:38 b:1 c:0 d:b1 s:5 i:b3 f:18
0x14008
a:38 b:6 c:0 d:b1 s:5 i:b4 f:18
0x20449
a:38 b:6 c:0 d:49 s:5 i:b5 f:18
0x800004
a:38 b:6 c:0 d:49 s:6 i:b6 f:18
0x2044e
a:38 b:6 c:0 d:4e s:6 i:b7 f:18
0x800004
a:38 b:6 c:0 d:4e s:7 i:b8 f:18
0x20443
a:38 b:6 c:0 d:43 s:7 i:b9 f:18
0x800004
a:38 b:6 c:0 d:43 s:8 i:ba f:18
0x2044f
a:38 b:6 c:0 d:4f s:8 i:bb f:18
0x800004
a:38 b:6 c:0 d:4f s:9 i:bc f:18
0x20452
a:38 b:6 c:0 d:52 s:9 i:bd f:18
0x800004
a:38 b:6 c:0 d:52 s:a i:be f:18
0x20452
a:38 b:6 c:0 d:52 s:a i:bf f:18
0x800004
a:38 b:6 c:0 d:52 s:b i:c0 f:18
0x20445
a:38 b:6 c:0 d:45 s:b i:c1 f:18
0x800004
a:38 b:6 c:0 d:45 s:c i:c2 f:18
0x20443
a:38 b:6 c:0 d:43 s:c i:c3 f:18
0x800004
a:38 b:6 c:0 d:43 s:d i:c4 f:18
0x20454
a:38 b:6 c:0 d:54 s:d i:c5 f:18
0x800004
a:38 b:6 c:0 d:54 s:e i:c6 f:18
0x20421
a:38 b:6 c:0 d:21 s:e i:c7 f:18
0x800004
a:38 b:6 c:0 d:21 s:f i:c8 f:18
0x2040a
a:38 b:6 c:0 d:a s:f i:c9 f:18
0x800004
a:38 b:6 c:0 d:a s:10 i:ca f:18
0x2200b
a:38 b:6 c:b d:a s:10 i:cb f:18
0x20201
a:1 b:6 c:b d:a s:10 i:cc f:18
0x100104
a:1 b:6 c:b d:b s:10 i:cd f:18
0x20201
a:1 b:6 c:b d:b s:10 i:ce f:18
0x100200

具体的opcode对应的操作指令,可以通过19.0对应出来。那么最后,分析发现用户输入偏移为0x30,目标字符串的偏移为0x6c。然后cmp指令比较时,从0x38偏移处开始比较的,然后目标字符串从0x76开始比较的。最后做相应处理即可。exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from pwn import *
# context(arch="amd64",os="linux",log_level="debug",terminal=['tmux','splitw','-h'])
# p = gdb.debug('/tmp/babyrev-level-19-1','b *$rebase(0x1d1c)')
p = process("/challenge/babyrev-level-19-1")
al = [0x42, 0x82, 0x2d, 0xe5, 0x64, 0x98, 0xf7, 0xac, 0x65,0xc2, 0x4d]
payload = b''
# for i in range(len(al)):
# if al[i] >= 256:
# payload += struct.pack('B', al[i] - 256)
# else:
# payload += struct.pack('B', al[i])
payload = struct.pack('11B', *al)
# gdb.attach(p)
# pause()
p.send(payload)

z = p.readline()
while(z):
print(z)
z = p.readline()

level20.0

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
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x20 arg1:0x40 arg2:0x1e
[s] IMM b = 0x1e
[V] a:0 b:0x1e c:0 d:0 s:0 i:0x2 f:0
[I] op:0x80 arg1:0x4 arg2:0x40
[s] STK i b
[s] ... pushing b
[s] ... popping i
[V] a:0 b:0x1e c:0 d:0 s:0 i:0x1f f:0
[I] op:0x20 arg1:0x40 arg2:0xde
[s] IMM b = 0xde
[V] a:0 b:0xde c:0 d:0 s:0 i:0x20 f:0
[I] op:0x20 arg1:0x20 arg2:0x5
[s] IMM c = 0x5
[V] a:0 b:0xde c:0x5 d:0 s:0 i:0x21 f:0
[I] op:0x20 arg1:0x2 arg2:0x1
[s] IMM a = 0x1
[V] a:0x1 b:0xde c:0x5 d:0 s:0 i:0x22 f:0
[I] op:0x2 arg1:0x2 arg2:0x1
[s] SYS 0x2 d
[s] ... write
KEY: [s] ... return value (in register d): 0x5
[V] a:0x1 b:0xde c:0x5 d:0x5 s:0 i:0x23 f:0
[I] op:0x80 arg1:0 arg2:0x2
[s] STK NONE a
[s] ... pushing a
[V] a:0x1 b:0xde c:0x5 d:0x5 s:0x1 i:0x24 f:0
[I] op:0x80 arg1:0 arg2:0x40
[s] STK NONE b
[s] ... pushing b
[V] a:0x1 b:0xde c:0x5 d:0x5 s:0x2 i:0x25 f:0
[I] op:0x80 arg1:0 arg2:0x20
[s] STK NONE c
[s] ... pushing c
[V] a:0x1 b:0xde c:0x5 d:0x5 s:0x3 i:0x26 f:0
[I] op:0x20 arg1:0x40 arg2:0x30
[s] IMM b = 0x30
[V] a:0x1 b:0x30 c:0x5 d:0x5 s:0x3 i:0x27 f:0
[I] op:0x20 arg1:0x20 arg2:0x1b
[s] IMM c = 0x1b
[V] a:0x1 b:0x30 c:0x1b d:0x5 s:0x3 i:0x28 f:0
[I] op:0x20 arg1:0x2 arg2:0
[s] IMM a = 0
[V] a:0 b:0x30 c:0x1b d:0x5 s:0x3 i:0x29 f:0
[I] op:0x2 arg1:0x1 arg2:0x1
[s] SYS 0x1 d
[s] ... read_memory
123

输入后

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
[s] ... return value (in register d): 0x4
[V] a:0 b:0x30 c:0x1b d:0x4 s:0x3 i:0x2a f:0
[I] op:0x80 arg1:0x20 arg2:0
[s] STK c NONE
[s] ... popping c
[V] a:0 b:0x30 c:0x5 d:0x4 s:0x2 i:0x2b f:0
[I] op:0x80 arg1:0x40 arg2:0
[s] STK b NONE
[s] ... popping b
[V] a:0 b:0xde c:0x5 d:0x4 s:0x1 i:0x2c f:0
[I] op:0x80 arg1:0x2 arg2:0
[s] STK a NONE
[s] ... popping a
[V] a:0x1 b:0xde c:0x5 d:0x4 s:0 i:0x2d f:0
[I] op:0x20 arg1:0x4 arg2:0x2d
[s] IMM i = 0x2d
[V] a:0x1 b:0xde c:0x5 d:0x4 s:0 i:0x2e f:0
[I] op:0x80 arg1:0 arg2:0x2
[s] STK NONE a
[s] ... pushing a
[V] a:0x1 b:0xde c:0x5 d:0x4 s:0x1 i:0x2f f:0
[I] op:0x80 arg1:0 arg2:0x40
[s] STK NONE b
[s] ... pushing b
[V] a:0x1 b:0xde c:0x5 d:0x4 s:0x2 i:0x30 f:0
[I] op:0x80 arg1:0 arg2:0x20
[s] STK NONE c
[s] ... pushing c
[V] a:0x1 b:0xde c:0x5 d:0x4 s:0x3 i:0x31 f:0
[I] op:0x20 arg1:0x2 arg2:0x30
[s] IMM a = 0x30
[V] a:0x30 b:0xde c:0x5 d:0x4 s:0x3 i:0x32 f:0
[I] op:0x20 arg1:0x20 arg2:0xa5
[s] IMM c = 0xa5
[V] a:0x30 b:0xde c:0xa5 d:0x4 s:0x3 i:0x33 f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a # a1[0x30] = 0x31
[V] a:0x30 b:0x31 c:0xa5 d:0x4 s:0x3 i:0x34 f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x30 b:0xd6 c:0xa5 d:0x4 s:0x3 i:0x35 f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b # a1[0x30] = 0x31 + 0xa5
[V] a:0x30 b:0xd6 c:0xa5 d:0x4 s:0x3 i:0x36 f:0
[I] op:0x20 arg1:0x2 arg2:0x31
[s] IMM a = 0x31
[V] a:0x31 b:0xd6 c:0xa5 d:0x4 s:0x3 i:0x37 f:0
[I] op:0x20 arg1:0x20 arg2:0xce
[s] IMM c = 0xce
[V] a:0x31 b:0xd6 c:0xce d:0x4 s:0x3 i:0x38 f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a # a1[0x31] = 0x32
[V] a:0x31 b:0x32 c:0xce d:0x4 s:0x3 i:0x39 f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x31 b:0 c:0xce d:0x4 s:0x3 i:0x3a f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b # a1[0x31] = 0x32 + 0xce
[V] a:0x31 b:0 c:0xce d:0x4 s:0x3 i:0x3b f:0
[I] op:0x20 arg1:0x2 arg2:0x32
[s] IMM a = 0x32
[V] a:0x32 b:0 c:0xce d:0x4 s:0x3 i:0x3c f:0
[I] op:0x20 arg1:0x20 arg2:0x67
[s] IMM c = 0x67
[V] a:0x32 b:0 c:0x67 d:0x4 s:0x3 i:0x3d f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x32 b:0x33 c:0x67 d:0x4 s:0x3 i:0x3e f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c # a1[0x32] = 0x33 + 0x67
[V] a:0x32 b:0x9a c:0x67 d:0x4 s:0x3 i:0x3f f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x32 b:0x9a c:0x67 d:0x4 s:0x3 i:0x40 f:0
[I] op:0x20 arg1:0x2 arg2:0x33
[s] IMM a = 0x33
[V] a:0x33 b:0x9a c:0x67 d:0x4 s:0x3 i:0x41 f:0
[I] op:0x20 arg1:0x20 arg2:0xab
[s] IMM c = 0xab
[V] a:0x33 b:0x9a c:0xab d:0x4 s:0x3 i:0x42 f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x33 b:0xa c:0xab d:0x4 s:0x3 i:0x43 f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x33 b:0xb5 c:0xab d:0x4 s:0x3 i:0x44 f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b # a1[0x33] = 0xa + 0xab
[V] a:0x33 b:0xb5 c:0xab d:0x4 s:0x3 i:0x45 f:0
[I] op:0x20 arg1:0x2 arg2:0x34
[s] IMM a = 0x34
[V] a:0x34 b:0xb5 c:0xab d:0x4 s:0x3 i:0x46 f:0
[I] op:0x20 arg1:0x20 arg2:0x98
[s] IMM c = 0x98
[V] a:0x34 b:0xb5 c:0x98 d:0x4 s:0x3 i:0x47 f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x34 b:0 c:0x98 d:0x4 s:0x3 i:0x48 f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x34 b:0x98 c:0x98 d:0x4 s:0x3 i:0x49 f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x34 b:0x98 c:0x98 d:0x4 s:0x3 i:0x4a f:0
[I] op:0x20 arg1:0x2 arg2:0x35
[s] IMM a = 0x35
[V] a:0x35 b:0x98 c:0x98 d:0x4 s:0x3 i:0x4b f:0
[I] op:0x20 arg1:0x20 arg2:0x46
[s] IMM c = 0x46
[V] a:0x35 b:0x98 c:0x46 d:0x4 s:0x3 i:0x4c f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x35 b:0 c:0x46 d:0x4 s:0x3 i:0x4d f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x35 b:0x46 c:0x46 d:0x4 s:0x3 i:0x4e f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x35 b:0x46 c:0x46 d:0x4 s:0x3 i:0x4f f:0
[I] op:0x20 arg1:0x2 arg2:0x36
[s] IMM a = 0x36
[V] a:0x36 b:0x46 c:0x46 d:0x4 s:0x3 i:0x50 f:0
[I] op:0x20 arg1:0x20 arg2:0x63
[s] IMM c = 0x63
[V] a:0x36 b:0x46 c:0x63 d:0x4 s:0x3 i:0x51 f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x36 b:0 c:0x63 d:0x4 s:0x3 i:0x52 f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x36 b:0x63 c:0x63 d:0x4 s:0x3 i:0x53 f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x36 b:0x63 c:0x63 d:0x4 s:0x3 i:0x54 f:0
[I] op:0x20 arg1:0x2 arg2:0x37
[s] IMM a = 0x37
[V] a:0x37 b:0x63 c:0x63 d:0x4 s:0x3 i:0x55 f:0
[I] op:0x20 arg1:0x20 arg2:0xe1
[s] IMM c = 0xe1
[V] a:0x37 b:0x63 c:0xe1 d:0x4 s:0x3 i:0x56 f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x37 b:0 c:0xe1 d:0x4 s:0x3 i:0x57 f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x37 b:0xe1 c:0xe1 d:0x4 s:0x3 i:0x58 f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x37 b:0xe1 c:0xe1 d:0x4 s:0x3 i:0x59 f:0
[I] op:0x20 arg1:0x2 arg2:0x38
[s] IMM a = 0x38
[V] a:0x38 b:0xe1 c:0xe1 d:0x4 s:0x3 i:0x5a f:0
[I] op:0x20 arg1:0x20 arg2:0x48
[s] IMM c = 0x48
[V] a:0x38 b:0xe1 c:0x48 d:0x4 s:0x3 i:0x5b f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x38 b:0 c:0x48 d:0x4 s:0x3 i:0x5c f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x38 b:0x48 c:0x48 d:0x4 s:0x3 i:0x5d f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x38 b:0x48 c:0x48 d:0x4 s:0x3 i:0x5e f:0
[I] op:0x20 arg1:0x2 arg2:0x39
[s] IMM a = 0x39
[V] a:0x39 b:0x48 c:0x48 d:0x4 s:0x3 i:0x5f f:0
[I] op:0x20 arg1:0x20 arg2:0x37
[s] IMM c = 0x37
[V] a:0x39 b:0x48 c:0x37 d:0x4 s:0x3 i:0x60 f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x39 b:0 c:0x37 d:0x4 s:0x3 i:0x61 f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x39 b:0x37 c:0x37 d:0x4 s:0x3 i:0x62 f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x39 b:0x37 c:0x37 d:0x4 s:0x3 i:0x63 f:0
[I] op:0x20 arg1:0x2 arg2:0x3a
[s] IMM a = 0x3a
[V] a:0x3a b:0x37 c:0x37 d:0x4 s:0x3 i:0x64 f:0
[I] op:0x20 arg1:0x20 arg2:0x3e
[s] IMM c = 0x3e
[V] a:0x3a b:0x37 c:0x3e d:0x4 s:0x3 i:0x65 f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x3a b:0 c:0x3e d:0x4 s:0x3 i:0x66 f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x3a b:0x3e c:0x3e d:0x4 s:0x3 i:0x67 f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x3a b:0x3e c:0x3e d:0x4 s:0x3 i:0x68 f:0
[I] op:0x20 arg1:0x2 arg2:0x3b
[s] IMM a = 0x3b
[V] a:0x3b b:0x3e c:0x3e d:0x4 s:0x3 i:0x69 f:0
[I] op:0x20 arg1:0x20 arg2:0x7f
[s] IMM c = 0x7f
[V] a:0x3b b:0x3e c:0x7f d:0x4 s:0x3 i:0x6a f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x3b b:0 c:0x7f d:0x4 s:0x3 i:0x6b f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x3b b:0x7f c:0x7f d:0x4 s:0x3 i:0x6c f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x3b b:0x7f c:0x7f d:0x4 s:0x3 i:0x6d f:0
[I] op:0x20 arg1:0x2 arg2:0x3c
[s] IMM a = 0x3c
[V] a:0x3c b:0x7f c:0x7f d:0x4 s:0x3 i:0x6e f:0
[I] op:0x20 arg1:0x20 arg2:0xc1
[s] IMM c = 0xc1
[V] a:0x3c b:0x7f c:0xc1 d:0x4 s:0x3 i:0x6f f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x3c b:0 c:0xc1 d:0x4 s:0x3 i:0x70 f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x3c b:0xc1 c:0xc1 d:0x4 s:0x3 i:0x71 f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x3c b:0xc1 c:0xc1 d:0x4 s:0x3 i:0x72 f:0
[I] op:0x20 arg1:0x2 arg2:0x3d
[s] IMM a = 0x3d
[V] a:0x3d b:0xc1 c:0xc1 d:0x4 s:0x3 i:0x73 f:0
[I] op:0x20 arg1:0x20 arg2:0xfa
[s] IMM c = 0xfa
[V] a:0x3d b:0xc1 c:0xfa d:0x4 s:0x3 i:0x74 f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x3d b:0 c:0xfa d:0x4 s:0x3 i:0x75 f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x3d b:0xfa c:0xfa d:0x4 s:0x3 i:0x76 f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x3d b:0xfa c:0xfa d:0x4 s:0x3 i:0x77 f:0
[I] op:0x20 arg1:0x2 arg2:0x3e
[s] IMM a = 0x3e
[V] a:0x3e b:0xfa c:0xfa d:0x4 s:0x3 i:0x78 f:0
[I] op:0x20 arg1:0x20 arg2:0x53
[s] IMM c = 0x53
[V] a:0x3e b:0xfa c:0x53 d:0x4 s:0x3 i:0x79 f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x3e b:0 c:0x53 d:0x4 s:0x3 i:0x7a f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x3e b:0x53 c:0x53 d:0x4 s:0x3 i:0x7b f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x3e b:0x53 c:0x53 d:0x4 s:0x3 i:0x7c f:0
[I] op:0x20 arg1:0x2 arg2:0x3f
[s] IMM a = 0x3f
[V] a:0x3f b:0x53 c:0x53 d:0x4 s:0x3 i:0x7d f:0
[I] op:0x20 arg1:0x20 arg2:0x5f
[s] IMM c = 0x5f
[V] a:0x3f b:0x53 c:0x5f d:0x4 s:0x3 i:0x7e f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x3f b:0 c:0x5f d:0x4 s:0x3 i:0x7f f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x3f b:0x5f c:0x5f d:0x4 s:0x3 i:0x80 f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x3f b:0x5f c:0x5f d:0x4 s:0x3 i:0x81 f:0
[I] op:0x20 arg1:0x2 arg2:0x40
[s] IMM a = 0x40
[V] a:0x40 b:0x5f c:0x5f d:0x4 s:0x3 i:0x82 f:0
[I] op:0x20 arg1:0x20 arg2:0x99
[s] IMM c = 0x99
[V] a:0x40 b:0x5f c:0x99 d:0x4 s:0x3 i:0x83 f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x40 b:0 c:0x99 d:0x4 s:0x3 i:0x84 f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x40 b:0x99 c:0x99 d:0x4 s:0x3 i:0x85 f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x40 b:0x99 c:0x99 d:0x4 s:0x3 i:0x86 f:0
[I] op:0x20 arg1:0x2 arg2:0x41
[s] IMM a = 0x41
[V] a:0x41 b:0x99 c:0x99 d:0x4 s:0x3 i:0x87 f:0
[I] op:0x20 arg1:0x20 arg2:0x31
[s] IMM c = 0x31
[V] a:0x41 b:0x99 c:0x31 d:0x4 s:0x3 i:0x88 f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x41 b:0 c:0x31 d:0x4 s:0x3 i:0x89 f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x41 b:0x31 c:0x31 d:0x4 s:0x3 i:0x8a f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x41 b:0x31 c:0x31 d:0x4 s:0x3 i:0x8b f:0
[I] op:0x20 arg1:0x2 arg2:0x42
[s] IMM a = 0x42
[V] a:0x42 b:0x31 c:0x31 d:0x4 s:0x3 i:0x8c f:0
[I] op:0x20 arg1:0x20 arg2:0x38
[s] IMM c = 0x38
[V] a:0x42 b:0x31 c:0x38 d:0x4 s:0x3 i:0x8d f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x42 b:0 c:0x38 d:0x4 s:0x3 i:0x8e f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x42 b:0x38 c:0x38 d:0x4 s:0x3 i:0x8f f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x42 b:0x38 c:0x38 d:0x4 s:0x3 i:0x90 f:0
[I] op:0x20 arg1:0x2 arg2:0x43
[s] IMM a = 0x43
[V] a:0x43 b:0x38 c:0x38 d:0x4 s:0x3 i:0x91 f:0
[I] op:0x20 arg1:0x20 arg2:0x8f
[s] IMM c = 0x8f
[V] a:0x43 b:0x38 c:0x8f d:0x4 s:0x3 i:0x92 f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x43 b:0 c:0x8f d:0x4 s:0x3 i:0x93 f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x43 b:0x8f c:0x8f d:0x4 s:0x3 i:0x94 f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x43 b:0x8f c:0x8f d:0x4 s:0x3 i:0x95 f:0
[I] op:0x20 arg1:0x2 arg2:0x44
[s] IMM a = 0x44
[V] a:0x44 b:0x8f c:0x8f d:0x4 s:0x3 i:0x96 f:0
[I] op:0x20 arg1:0x20 arg2:0x89
[s] IMM c = 0x89
[V] a:0x44 b:0x8f c:0x89 d:0x4 s:0x3 i:0x97 f:0
[I] op:0x40 arg1:0x40 arg2:0x2
[s] LDM b = *a
[V] a:0x44 b:0 c:0x89 d:0x4 s:0x3 i:0x98 f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x44 b:0x89 c:0x89 d:0x4 s:0x3 i:0x99 f:0
[I] op:0x1 arg1:0x2 arg2:0x40
[s] STM *a = b
[V] a:0x44 b:0x89 c:0x89 d:0x4 s:0x3 i:0x9a f:0
[I] op:0x80 arg1:0x20 arg2:0
[s] STK c NONE
[s] ... popping c
[V] a:0x44 b:0x89 c:0x5 d:0x4 s:0x2 i:0x9b f:0
[I] op:0x80 arg1:0x40 arg2:0
[s] STK b NONE
[s] ... popping b
[V] a:0x44 b:0xde c:0x5 d:0x4 s:0x1 i:0x9c f:0
[I] op:0x80 arg1:0x2 arg2:0
[s] STK a NONE
[s] ... popping a
[V] a:0x1 b:0xde c:0x5 d:0x4 s:0 i:0x9d f:0
[I] op:0x20 arg1:0x4 arg2:0x9d
[s] IMM i = 0x9d
[V] a:0x1 b:0xde c:0x5 d:0x4 s:0 i:0x9e f:0
[I] op:0x20 arg1:0x2 arg2:0x30
[s] IMM a = 0x30
[V] a:0x30 b:0xde c:0x5 d:0x4 s:0 i:0x9f f:0
[I] op:0x20 arg1:0x40 arg2:0xa3
[s] IMM b = 0xa3
[V] a:0x30 b:0xa3 c:0x5 d:0x4 s:0 i:0xa0 f:0
[I] op:0x20 arg1:0x20 arg2:0x15
[s] IMM c = 0x15
[V] a:0x30 b:0xa3 c:0x15 d:0x4 s:0 i:0xa1 f:0
[I] op:0x20 arg1:0x1 arg2:0x2
[s] IMM d = 0x2
[V] a:0x30 b:0xa3 c:0x15 d:0x2 s:0 i:0xa2 f:0
[I] op:0x4 arg1:0x1 arg2:0x4
[s] ADD d i
[V] a:0x30 b:0xa3 c:0x15 d:0xa4 s:0 i:0xa3 f:0
[I] op:0x80 arg1:0 arg2:0x1
[s] STK NONE d
[s] ... pushing d
[V] a:0x30 b:0xa3 c:0x15 d:0xa4 s:0x1 i:0xa4 f:0
[I] op:0x20 arg1:0x4 arg2:0x2
[s] IMM i = 0x2
[V] a:0x30 b:0xa3 c:0x15 d:0xa4 s:0x1 i:0x3 f:0
[I] op:0x4 arg1:0x2 arg2:0x20
[s] ADD a c
[V] a:0x45 b:0xa3 c:0x15 d:0xa4 s:0x1 i:0x4 f:0
[I] op:0x4 arg1:0x40 arg2:0x20
[s] ADD b c
[V] a:0x45 b:0xb8 c:0x15 d:0xa4 s:0x1 i:0x5 f:0
[I] op:0x20 arg1:0x1 arg2:0xff
[s] IMM d = 0xff
[V] a:0x45 b:0xb8 c:0x15 d:0xff s:0x1 i:0x6 f:0
[I] op:0x4 arg1:0x2 arg2:0x1
[s] ADD a d
[V] a:0x44 b:0xb8 c:0x15 d:0xff s:0x1 i:0x7 f:0
[I] op:0x4 arg1:0x40 arg2:0x1
[s] ADD b d
[V] a:0x44 b:0xb7 c:0x15 d:0xff s:0x1 i:0x8 f:0
[I] op:0x80 arg1:0 arg2:0x2
[s] STK NONE a
[s] ... pushing a
[V] a:0x44 b:0xb7 c:0x15 d:0xff s:0x2 i:0x9 f:0
[I] op:0x80 arg1:0 arg2:0x40
[s] STK NONE b
[s] ... pushing b
[V] a:0x44 b:0xb7 c:0x15 d:0xff s:0x3 i:0xa f:0 #######
[I] op:0x40 arg1:0x2 arg2:0x2
[s] LDM a = *a # a1[0x44]
[V] a:0x89 b:0xb7 c:0x15 d:0xff s:0x3 i:0xb f:0
[I] op:0x40 arg1:0x40 arg2:0x40
[s] LDM b = *b # a1[0xb7]
[V] a:0x89 b:0x5b c:0x15 d:0xff s:0x3 i:0xc f:0
[I] op:0x8 arg1:0x2 arg2:0x40
[s] CMP a b
[V] a:0x89 b:0x5b c:0x15 d:0xff s:0x3 i:0xd f:0x14
[I] op:0x80 arg1:0x40 arg2:0
[s] STK b NONE
[s] ... popping b
[V] a:0x89 b:0xb7 c:0x15 d:0xff s:0x2 i:0xe f:0x14
[I] op:0x80 arg1:0x2 arg2:0
[s] STK a NONE
[s] ... popping a
[V] a:0x44 b:0xb7 c:0x15 d:0xff s:0x1 i:0xf f:0x14
[I] op:0x20 arg1:0x1 arg2:0x16
[s] IMM d = 0x16
[V] a:0x44 b:0xb7 c:0x15 d:0x16 s:0x1 i:0x10 f:0x14
[I] op:0x10 arg1:0x4 arg2:0x1
[j] JMP N d
[j] ... TAKEN
[V] a:0x44 b:0xb7 c:0x15 d:0x16 s:0x1 i:0x17 f:0x14
[I] op:0x80 arg1:0x1 arg2:0x20
[s] STK d c
[s] ... pushing c
[s] ... popping d
[V] a:0x44 b:0xb7 c:0x15 d:0x15 s:0x1 i:0x18 f:0x14
[I] op:0x80 arg1:0x4 arg2:0
[s] STK i NONE
[s] ... popping i
[V] a:0x44 b:0xb7 c:0x15 d:0x15 s:0 i:0xa5 f:0x14
[I] op:0x20 arg1:0x20 arg2:0
[s] IMM c = 0
[V] a:0x44 b:0xb7 c:0 d:0x15 s:0 i:0xa6 f:0x14
[I] op:0x8 arg1:0x1 arg2:0x20
[s] CMP d c
[V] a:0x44 b:0xb7 c:0 d:0x15 s:0 i:0xa7 f:0x14
[I] op:0x20 arg1:0x1 arg2:0xaa
[s] IMM d = 0xaa
[V] a:0x44 b:0xb7 c:0 d:0xaa s:0 i:0xa8 f:0x14
[I] op:0x10 arg1:0x1 arg2:0x1
[j] JMP E d
[j] ... NOT TAKEN
[V] a:0x44 b:0xb7 c:0 d:0xaa s:0 i:0xa9 f:0x14
[I] op:0x20 arg1:0x1 arg2:0x18
[s] IMM d = 0x18
[V] a:0x44 b:0xb7 c:0 d:0x18 s:0 i:0xaa f:0x14
[I] op:0x10 arg1:0x12 arg2:0x1
[j] JMP LG d
[j] ... TAKEN
[V] a:0x44 b:0xb7 c:0 d:0x18 s:0 i:0x19 f:0x14
[I] op:0x20 arg1:0x40 arg2:0xd4
[s] IMM b = 0xd4
[V] a:0x44 b:0xd4 c:0 d:0x18 s:0 i:0x1a f:0x14
[I] op:0x20 arg1:0x20 arg2:0xa
[s] IMM c = 0xa
[V] a:0x44 b:0xd4 c:0xa d:0x18 s:0 i:0x1b f:0x14
[I] op:0x20 arg1:0x2 arg2:0x1
[s] IMM a = 0x1
[V] a:0x1 b:0xd4 c:0xa d:0x18 s:0 i:0x1c f:0x14
[I] op:0x2 arg1:0x2 arg2:0x1
[s] SYS 0x2 d
[s] ... write

rax+0x300a1首地址,那么可以读出目标字符串

1
2
3
4
pwndbg> x /21bx $rax+0xb7 + 0x300 -20
0x7ffe834dd363: 0x43 0xed 0xf2 0x06 0x74 0x8f 0xb8 0x43
0x7ffe834dd36b: 0xd0 0x49 0xd5 0x94 0x09 0x9d 0x9b 0xf0
0x7ffe834dd373: 0xa6 0x6c 0xe7 0x62 0x5b

找到目标字符串,然后根据上述的vmcode能够找到对应的输入字符串,最后做一个减法即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *
# context(arch="amd64",os="linux",log_level="debug",terminal=['tmux','splitw','-h'])
# p = gdb.debug('/tmp/babyrev-level-20-0','b interpreter_loop')
p = process("/challenge/babyrev-level-20-0")
al = [0x43-0xa5, 0xed-0xce, 0xf2-0x67, 0x06-0xab, 0x74-0x98, 0x8f-0x46, 0xb8-0x63, 0x43-0xe1, 0xd0-0x48,0x49-0x37, 0xd5-0x3e, 0x94-0x7f, 0x09-0xc1, 0x9d-0xfa, 0x9b-0x53, 0xf0-0x5f, 0xa6-0x99, 0x6c-0x31, 0xe7-0x38, 0x62-0x8f, 0x5b - 0x89]
payload = b''
for i in range(len(al)):
# print(al[i])
payload += struct.pack('B', (al[i]) % 256)
# payload = struct.pack('21B', *al)
# gdb.attach(p)
# pause()
p.send(payload)

z = p.readline()
while(z):
print(z)
z = p.readline()

level20.1

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
a:0 b:0 c:0 d:0 s:0 i:1 f:0
0x140c6 # 40 : IMM b(1) = c6
a:0 b:c6 c:0 d:0 s:0 i:2 f:0
0x80801 # 08 : stk
a:0 b:c6 c:0 d:0 s:0 i:c7 f:0
0x140c2
a:0 b:c2 c:0 d:0 s:0 i:c8 f:0
0x104005 # 40 : IMM c(0x10) = 05
a:0 b:c2 c:5 d:0 s:0 i:c9 f:0
0x404001 # 40 : IMM a(0x40) = 0
a:1 b:c2 c:5 d:0 s:0 i:ca f:0
0x48002 # 80 :SYS
a:1 b:c2 c:5 d:5 s:0 i:cb f:0
0x840
a:1 b:c2 c:5 d:5 s:1 i:cc f:0
0x801
a:1 b:c2 c:5 d:5 s:2 i:cd f:0
0x810
a:1 b:c2 c:5 d:5 s:3 i:ce f:0
0x14030
a:1 b:30 c:5 d:5 s:3 i:cf f:0
0x104022
a:1 b:30 c:22 d:5 s:3 i:d0 f:0
0x404000
a:0 b:30 c:22 d:5 s:3 i:d1 f:0
0x18002
a:0 b:30 c:22 d:15 s:3 i:d2 f:0
0x100800
a:0 b:30 c:5 d:15 s:2 i:d3 f:0
0x10800
a:0 b:c2 c:5 d:15 s:1 i:d4 f:0
0x400800
a:1 b:c2 c:5 d:15 s:0 i:d5 f:0
0x84002
a:1 b:c2 c:5 d:15 s:0 i:3 f:0
0x840
a:1 b:c2 c:5 d:15 s:1 i:4 f:0
0x801
a:1 b:c2 c:5 d:15 s:2 i:5 f:0
0x810
a:1 b:c2 c:5 d:15 s:3 i:6 f:0
0x404030
a:30 b:c2 c:5 d:15 s:3 i:7 f:0
0x1040fe
a:30 b:c2 c:fe d:15 s:3 i:8 f:0
0x10140 # 01 : LDM b = *a
a:30 b:9e c:fe d:15 s:3 i:9 f:0
0x11010 # 10 : ADD b c
a:30 b:9c c:fe d:15 s:3 i:a f:0
0x400201 # 02 : STM a = *b a1[0x30] = user1 + 0xfe
a:30 b:9c c:fe d:15 s:3 i:b f:0
0x404031
a:31 b:9c c:fe d:15 s:3 i:c f:0
0x10409b
a:31 b:9c c:9b d:15 s:3 i:d f:0
0x10140
a:31 b:1f c:9b d:15 s:3 i:e f:0
0x11010
a:31 b:ba c:9b d:15 s:3 i:f f:0
0x400201 # 02 : STM a = *b a1[0x31] = user2 + 0x9b
a:31 b:ba c:9b d:15 s:3 i:10 f:0
0x404032
a:32 b:ba c:9b d:15 s:3 i:11 f:0
0x10403c
a:32 b:ba c:3c d:15 s:3 i:12 f:0
0x10140
a:32 b:8b c:3c d:15 s:3 i:13 f:0
0x11010
a:32 b:c7 c:3c d:15 s:3 i:14 f:0
0x400201
a:32 b:c7 c:3c d:15 s:3 i:15 f:0
0x404033
a:33 b:c7 c:3c d:15 s:3 i:16 f:0
0x1040cc
a:33 b:c7 c:cc d:15 s:3 i:17 f:0
0x10140
a:33 b:5b c:cc d:15 s:3 i:18 f:0
0x11010
a:33 b:27 c:cc d:15 s:3 i:19 f:0
0x400201
a:33 b:27 c:cc d:15 s:3 i:1a f:0
0x404034
a:34 b:27 c:cc d:15 s:3 i:1b f:0
0x1040e3
a:34 b:27 c:e3 d:15 s:3 i:1c f:0
0x10140
a:34 b:dc c:e3 d:15 s:3 i:1d f:0
0x11010
a:34 b:bf c:e3 d:15 s:3 i:1e f:0
0x400201
a:34 b:bf c:e3 d:15 s:3 i:1f f:0
0x404035
a:35 b:bf c:e3 d:15 s:3 i:20 f:0
0x1040b0
a:35 b:bf c:b0 d:15 s:3 i:21 f:0
0x10140
a:35 b:49 c:b0 d:15 s:3 i:22 f:0
0x11010
a:35 b:f9 c:b0 d:15 s:3 i:23 f:0
0x400201
a:35 b:f9 c:b0 d:15 s:3 i:24 f:0
0x404036
a:36 b:f9 c:b0 d:15 s:3 i:25 f:0
0x10401e
a:36 b:f9 c:1e d:15 s:3 i:26 f:0
0x10140
a:36 b:55 c:1e d:15 s:3 i:27 f:0
0x11010
a:36 b:73 c:1e d:15 s:3 i:28 f:0
0x400201
a:36 b:73 c:1e d:15 s:3 i:29 f:0
0x404037
a:37 b:73 c:1e d:15 s:3 i:2a f:0
0x1040e6
a:37 b:73 c:e6 d:15 s:3 i:2b f:0
0x10140
a:37 b:62 c:e6 d:15 s:3 i:2c f:0
0x11010
a:37 b:48 c:e6 d:15 s:3 i:2d f:0
0x400201
a:37 b:48 c:e6 d:15 s:3 i:2e f:0
0x404038
a:38 b:48 c:e6 d:15 s:3 i:2f f:0
0x104088
a:38 b:48 c:88 d:15 s:3 i:30 f:0
0x10140
a:38 b:88 c:88 d:15 s:3 i:31 f:0
0x11010
a:38 b:10 c:88 d:15 s:3 i:32 f:0
0x400201
a:38 b:10 c:88 d:15 s:3 i:33 f:0
0x404039
a:39 b:10 c:88 d:15 s:3 i:34 f:0
0x104012
a:39 b:10 c:12 d:15 s:3 i:35 f:0
0x10140
a:39 b:12 c:12 d:15 s:3 i:36 f:0
0x11010
a:39 b:24 c:12 d:15 s:3 i:37 f:0
0x400201
a:39 b:24 c:12 d:15 s:3 i:38 f:0
0x40403a
a:3a b:24 c:12 d:15 s:3 i:39 f:0
0x1040a1
a:3a b:24 c:a1 d:15 s:3 i:3a f:0
0x10140
a:3a b:97 c:a1 d:15 s:3 i:3b f:0
0x11010
a:3a b:38 c:a1 d:15 s:3 i:3c f:0
0x400201
a:3a b:38 c:a1 d:15 s:3 i:3d f:0
0x40403b
a:3b b:38 c:a1 d:15 s:3 i:3e f:0
0x1040d3
a:3b b:38 c:d3 d:15 s:3 i:3f f:0
0x10140
a:3b b:15 c:d3 d:15 s:3 i:40 f:0
0x11010
a:3b b:e8 c:d3 d:15 s:3 i:41 f:0
0x400201
a:3b b:e8 c:d3 d:15 s:3 i:42 f:0
0x40403c
a:3c b:e8 c:d3 d:15 s:3 i:43 f:0
0x1040c3
a:3c b:e8 c:c3 d:15 s:3 i:44 f:0
0x10140
a:3c b:48 c:c3 d:15 s:3 i:45 f:0
0x11010
a:3c b:b c:c3 d:15 s:3 i:46 f:0
0x400201
a:3c b:b c:c3 d:15 s:3 i:47 f:0
0x40403d
a:3d b:b c:c3 d:15 s:3 i:48 f:0
0x104002
a:3d b:b c:2 d:15 s:3 i:49 f:0
0x10140
a:3d b:a3 c:2 d:15 s:3 i:4a f:0
0x11010
a:3d b:a5 c:2 d:15 s:3 i:4b f:0
0x400201
a:3d b:a5 c:2 d:15 s:3 i:4c f:0
0x40403e
a:3e b:a5 c:2 d:15 s:3 i:4d f:0
0x1040b2
a:3e b:a5 c:b2 d:15 s:3 i:4e f:0
0x10140
a:3e b:48 c:b2 d:15 s:3 i:4f f:0
0x11010
a:3e b:fa c:b2 d:15 s:3 i:50 f:0
0x400201
a:3e b:fa c:b2 d:15 s:3 i:51 f:0
0x40403f
a:3f b:fa c:b2 d:15 s:3 i:52 f:0
0x1040df
a:3f b:fa c:df d:15 s:3 i:53 f:0
0x10140
a:3f b:91 c:df d:15 s:3 i:54 f:0
0x11010
a:3f b:70 c:df d:15 s:3 i:55 f:0
0x400201
a:3f b:70 c:df d:15 s:3 i:56 f:0
0x404040
a:40 b:70 c:df d:15 s:3 i:57 f:0
0x104095
a:40 b:70 c:95 d:15 s:3 i:58 f:0
0x10140
a:40 b:d c:95 d:15 s:3 i:59 f:0
0x11010
a:40 b:a2 c:95 d:15 s:3 i:5a f:0
0x400201
a:40 b:a2 c:95 d:15 s:3 i:5b f:0
0x404041
a:41 b:a2 c:95 d:15 s:3 i:5c f:0
0x1040f6
a:41 b:a2 c:f6 d:15 s:3 i:5d f:0
0x10140
a:41 b:3b c:f6 d:15 s:3 i:5e f:0
0x11010
a:41 b:31 c:f6 d:15 s:3 i:5f f:0
0x400201
a:41 b:31 c:f6 d:15 s:3 i:60 f:0
0x404042
a:42 b:31 c:f6 d:15 s:3 i:61 f:0
0x104098
a:42 b:31 c:98 d:15 s:3 i:62 f:0
0x10140
a:42 b:af c:98 d:15 s:3 i:63 f:0
0x11010
a:42 b:47 c:98 d:15 s:3 i:64 f:0
0x400201
a:42 b:47 c:98 d:15 s:3 i:65 f:0
0x404043
a:43 b:47 c:98 d:15 s:3 i:66 f:0
0x104057
a:43 b:47 c:57 d:15 s:3 i:67 f:0
0x10140
a:43 b:d3 c:57 d:15 s:3 i:68 f:0
0x11010
a:43 b:2a c:57 d:15 s:3 i:69 f:0
0x400201
a:43 b:2a c:57 d:15 s:3 i:6a f:0
0x404044
a:44 b:2a c:57 d:15 s:3 i:6b f:0
0x104066
a:44 b:2a c:66 d:15 s:3 i:6c f:0
0x10140
a:44 b:d2 c:66 d:15 s:3 i:6d f:0
0x11010
a:44 b:38 c:66 d:15 s:3 i:6e f:0
0x400201
a:44 b:38 c:66 d:15 s:3 i:6f f:0
0x404045
a:45 b:38 c:66 d:15 s:3 i:70 f:0
0x10400c
a:45 b:38 c:c d:15 s:3 i:71 f:0
0x10140
a:45 b:0 c:c d:15 s:3 i:72 f:0
0x11010
a:45 b:c c:c d:15 s:3 i:73 f:0
0x400201
a:45 b:c c:c d:15 s:3 i:74 f:0
0x404046
a:46 b:c c:c d:15 s:3 i:75 f:0
0x104077
a:46 b:c c:77 d:15 s:3 i:76 f:0
0x10140
a:46 b:0 c:77 d:15 s:3 i:77 f:0
0x11010
a:46 b:77 c:77 d:15 s:3 i:78 f:0
0x400201
a:46 b:77 c:77 d:15 s:3 i:79 f:0
0x404047
a:47 b:77 c:77 d:15 s:3 i:7a f:0
0x1040e5
a:47 b:77 c:e5 d:15 s:3 i:7b f:0
0x10140
a:47 b:0 c:e5 d:15 s:3 i:7c f:0
0x11010
a:47 b:e5 c:e5 d:15 s:3 i:7d f:0
0x400201
a:47 b:e5 c:e5 d:15 s:3 i:7e f:0
0x404048
a:48 b:e5 c:e5 d:15 s:3 i:7f f:0
0x10406d
a:48 b:e5 c:6d d:15 s:3 i:80 f:0
0x10140
a:48 b:0 c:6d d:15 s:3 i:81 f:0
0x11010
a:48 b:6d c:6d d:15 s:3 i:82 f:0
0x400201
a:48 b:6d c:6d d:15 s:3 i:83 f:0
0x404049
a:49 b:6d c:6d d:15 s:3 i:84 f:0
0x104042
a:49 b:6d c:42 d:15 s:3 i:85 f:0
0x10140
a:49 b:0 c:42 d:15 s:3 i:86 f:0
0x11010
a:49 b:42 c:42 d:15 s:3 i:87 f:0
0x400201
a:49 b:42 c:42 d:15 s:3 i:88 f:0
0x40404a
a:4a b:42 c:42 d:15 s:3 i:89 f:0
0x1040bf
a:4a b:42 c:bf d:15 s:3 i:8a f:0
0x10140
a:4a b:0 c:bf d:15 s:3 i:8b f:0
0x11010
a:4a b:bf c:bf d:15 s:3 i:8c f:0
0x400201
a:4a b:bf c:bf d:15 s:3 i:8d f:0
0x40404b
a:4b b:bf c:bf d:15 s:3 i:8e f:0
0x10401c
a:4b b:bf c:1c d:15 s:3 i:8f f:0
0x10140
a:4b b:0 c:1c d:15 s:3 i:90 f:0
0x11010
a:4b b:1c c:1c d:15 s:3 i:91 f:0
0x400201 # 最后一个, STM *a = b, a1[0x4b] = user28 + 1c
a:4b b:1c c:1c d:15 s:3 i:92 f:0
0x100800
a:4b b:1c c:5 d:15 s:2 i:93 f:0
0x10800
a:4b b:c2 c:5 d:15 s:1 i:94 f:0
0x400800
a:1 b:c2 c:5 d:15 s:0 i:95 f:0
0x840d5
a:1 b:c2 c:5 d:15 s:0 i:d6 f:0
0x404030
a:30 b:c2 c:5 d:15 s:0 i:d7 f:0
0x14080
a:30 b:80 c:5 d:15 s:0 i:d8 f:0
0x10401c
a:30 b:80 c:1c d:15 s:0 i:d9 f:0
0x24002
a:30 b:80 c:1c d:2 s:0 i:da f:0
0x21008
a:30 b:80 c:1c d:dc s:0 i:db f:0
0x802
a:30 b:80 c:1c d:dc s:1 i:dc f:0
0x84095
a:30 b:80 c:1c d:dc s:1 i:96 f:0
0x401010
a:4c b:80 c:1c d:dc s:1 i:97 f:0
0x11010
a:4c b:9c c:1c d:dc s:1 i:98 f:0
0x240ff
a:4c b:9c c:1c d:ff s:1 i:99 f:0
0x401002
a:4b b:9c c:1c d:ff s:1 i:9a f:0
0x11002
a:4b b:9b c:1c d:ff s:1 i:9b f:0
0x840
a:4b b:9b c:1c d:ff s:2 i:9c f:0
0x801
a:4b b:9b c:1c d:ff s:3 i:9d f:0
0x400140 # 01 : LDM a = *a
a:1c b:9b c:1c d:ff s:3 i:9e f:0
0x10101 # 01 : LDM b = *b
a:1c b:63 c:1c d:ff s:3 i:9f f:0
0x400401 # 04 : CMP a b === cmp a1[0x4b] a1[0x9b]
a:1c b:63 c:1c d:ff s:3 i:a0 f:c
0x10800
a:1c b:9b c:1c d:ff s:2 i:a1 f:c
0x400800
a:4b b:9b c:1c d:ff s:1 i:a2 f:c
0x240a9
a:4b b:9b c:1c d:a9 s:1 i:a3 f:c
0x82002
a:4b b:9b c:1c d:a9 s:1 i:aa f:c
0x20810
a:4b b:9b c:1c d:1c s:1 i:ab f:c
0x80800
a:4b b:9b c:1c d:1c s:0 i:dd f:c
0x104000
a:4b b:9b c:0 d:1c s:0 i:de f:c
0x20410
a:4b b:9b c:0 d:1c s:0 i:df f:a
0x240b1
a:4b b:9b c:0 d:b1 s:0 i:e0 f:a
0x102002
a:4b b:9b c:0 d:b1 s:0 i:e1 f:a
0x240ab
a:4b b:9b c:0 d:ab s:0 i:e2 f:a
0x62002
a:4b b:9b c:0 d:ab s:0 i:ac f:a
0x140b8
a:4b b:b8 c:0 d:ab s:0 i:ad f:a
0x10400a
a:4b b:b8 c:a d:ab s:0 i:ae f:a
0x404001
a:1 b:b8 c:a d:ab s:0 i:af f:a
0x48002
a:1 b:b8 c:a d:a s:0 i:b0 f:a
0x404001
a:1 b:b8 c:a d:a s:0 i:b1 f:a
0x88000

起始位置没有变,还是$rax + 0x300,加上我们的偏移就是$rax + 0x300 + 0x9b - 27,最后拿到目标字符串

1
2
3
4
5
pwndbg>  x /28bx $rax + 0x300 +0x9b -27
0x7ffd7698ca20: 0x38 0x62 0x4d 0x42 0x6e 0xdf 0x72 0xff
0x7ffd7698ca28: 0x09 0x8e 0x2b 0x6f 0x1e 0xc8 0x03 0xe2
0x7ffd7698ca30: 0x53 0x3b 0x07 0xfd 0x79 0x6e 0x01 0x57
0x7ffd7698ca38: 0xa8 0x61 0xa8 0x63

最后得出exp,但是我感觉我手动的有点麻烦,后面数据多的话写个脚本处理吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from pwn import *
# context(arch="amd64",os="linux",log_level="debug",terminal=['tmux','splitw','-h'])
# p = gdb.debug('/tmp/babyrev-level-20-1','b printf')
p = process("/challenge/babyrev-level-20-1")
al = [0x38-0xfe, 0x62-0x9b, 0x4d-0x3c, 0x42-0xcc, 0x6e-0xe3, 0xdf-0xb0, 0x72-0x1e, 0xff-0xe6, 0x9-0x88, 0x8e-0x12, 0x2b-0xa1, 0x6f-0xd3, 0x1e-0xc3, 0xc8-0x02, 0x03-0xb2, 0xe2-0xdf, 0x53-0x95, 0x3b-0xf6, 0x07-0x98, 0xfd-0x57, 0x79-0x66, 0x6e-0xc, 0x01-0x77, 0x57-0xe5, 0xa8-0x6d, 0x61-0x42, 0xa8-0xbf,0x63- 0x1c]
print(len(al))
payload = b''
for i in range(len(al)):
# print(al[i])

payload += struct.pack('B', (al[i]) % 256)
# payload = struct.pack('21B', *al)
# gdb.attach(p)
# pause()
p.send(payload)

z = p.readline()
while(z):
print(z)
z = p.readline()

level21.0

这题需要自己写yancode,可以参考20.0,然后调试它。可以发现yancode是以三个字节三个字节作为一个指令的。也就是一个opcode加两个参数。那么根据不同的opcode和参数做出不同的操作。

这里需要做的是:将/flag字符串写入内存中,然后调用open,也就是SYS open打开/flag。它会返回一个文件描述符,通常为0x3。然后再调用SYS read,将0x3读入到内存中,它会返回读入的字节数,就是flag的长度为0x39。最后使用SYS write把内存中的flag读出来。exp如下:

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
52
53
54
55
56
57
58
59
60
61
62
from pwn import *
# context(arch="amd64",os="linux",log_level="debug",terminal=['tmux','splitw','-h'])
# p = gdb.debug('/tmp/babyrev-level-21-0', 'b interpreter_loop')
p = process("/challenge/babyrev-level-21-0")
payload = b''
imm_a= 0x403010 # IMM a = 0x30
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x402f40 # IMM b = 0x2f '/'
payload += p32(imm_b, endianness="big")[1:]
stm_a = 0x204010 # STM *a = b
payload += p32(stm_a, endianness="big")[1:]
imm_a= 0x403110 # IMM a = 0x31
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x406640 # IMM b = 0x66 'f'
payload += p32(imm_b, endianness="big")[1:]
stm_a = 0x204010 # STM *a = b
payload += p32(stm_a, endianness="big")[1:]
imm_a= 0x403210 # IMM a = 0x32
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x406c40 # IMM b = 0x6c 'l'
payload += p32(imm_b, endianness="big")[1:]
stm_a = 0x204010 # STM *a = b
payload += p32(stm_a, endianness="big")[1:]
imm_a= 0x403310 # IMM a = 0x33
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x406140 # IMM b = 0x61 'a'
payload += p32(imm_b, endianness="big")[1:]
stm_a = 0x204010 # STM *a = b
payload += p32(stm_a, endianness="big")[1:]
imm_a= 0x403410 # IMM a = 0x34
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x406740 # IMM b = 0x67 'g'
payload += p32(imm_b, endianness="big")[1:]
stm_a = 0x204010 # STM *a = b
payload += p32(stm_a, endianness="big")[1:]
imm_a= 0x403010 # IMM a = 0x30
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x400040 # IMM b = 0
payload += p32(imm_b, endianness="big")[1:]
sys_open = 0x081008 # open /flag
payload += p32(sys_open, endianness="big")[1:]
imm_b = 0x404040 # IMM b = 0x40
payload += p32(imm_b, endianness="big")[1:]
imm_c = 0x40ff08 # IMM c = 0xff
payload += p32(imm_c, endianness="big")[1:]
sys_read = 0x080801 # SYS Read
payload += p32(sys_read, endianness="big")[1:]
imm_a = 0x400110 # IMM a = 0x01
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x404040 # IMM b = 0x3
payload += p32(imm_b, endianness="big")[1:]
sys_read = 0x080820 # SYS write
payload += p32(sys_read, endianness="big")[1:]
exi = 0x084004 # exit
# pause()
payload += p32(exi, endianness="big")[1:]
print(payload)
p.send(payload)
for i in range(100):
print(p.readline())

p.close()

level21.1

1
2
3
4
5
6
7
8
40 imm
80 add
02 stk
04 stm
01 ldm
20 cmp
10 jmp
8 sys
1
2
3
4
5
6
7
64	a
8 b
32 c
1 d
16 s
4 i
2 f

ida把对应的变量替换。因为每次指令对应的opcode以及变量对应的变量code都会变化。因此这里做一个替换。

不过替换之后还是有问题,通过gdb调试过程中发现,参数顺序换了。也就是arg1 和 arg2又恢复成正常顺序了,上面那题arg1 和 arg2是反着的。最后exp:

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
52
53
54
55
56
57
58
59
60
61
62
from pwn import *
# context(arch="amd64",os="linux",log_level="debug",terminal=['tmux','splitw','-h'])
# p = gdb.debug('/tmp/babyrev-level-21-1', 'b interpreter_loop')
p = process("/challenge/babyrev-level-21-1")
payload = b''
imm_a= 0x404030 # IMM a = 0x30
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x40082f # IMM b = 0x2f '/'
payload += p32(imm_b, endianness="big")[1:]
stm_a = 0x044008 # STM *a = b
payload += p32(stm_a, endianness="big")[1:]
imm_a= 0x404031 # IMM a = 0x31
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x400866 # IMM b = 0x66 'f'
payload += p32(imm_b, endianness="big")[1:]
stm_a = 0x044008 # STM *a = b
payload += p32(stm_a, endianness="big")[1:]
imm_a= 0x404032 # IMM a = 0x32
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x40086c # IMM b = 0x6c 'l'
payload += p32(imm_b, endianness="big")[1:]
stm_a = 0x044008 # STM *a = b
payload += p32(stm_a, endianness="big")[1:]
imm_a= 0x404033 # IMM a = 0x33
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x400861 # IMM b = 0x61 'a'
payload += p32(imm_b, endianness="big")[1:]
stm_a = 0x044008 # STM *a = b
payload += p32(stm_a, endianness="big")[1:]
imm_a= 0x404034 # IMM a = 0x34
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x400867 # IMM b = 0x67 'g'
payload += p32(imm_b, endianness="big")[1:]
stm_a = 0x044008 # STM *a = b
payload += p32(stm_a, endianness="big")[1:]
imm_a= 0x404030 # IMM a = 0x30
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x400800 # IMM b = 0
payload += p32(imm_b, endianness="big")[1:]
sys_open = 0x082040 # open /flag
payload += p32(sys_open, endianness="big")[1:]
imm_b = 0x400840 # IMM b = 0x40
payload += p32(imm_b, endianness="big")[1:]
imm_c = 0x4020ff # IMM c = 0xff
payload += p32(imm_c, endianness="big")[1:]
sys_read = 0x080420 # SYS Read
payload += p32(sys_read, endianness="big")[1:]
imm_a = 0x404001 # IMM a = 0x01
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x400840 # IMM b = 0x3
payload += p32(imm_b, endianness="big")[1:]
sys_read = 0x081020 # SYS write
payload += p32(sys_read, endianness="big")[1:]
exi = 0x080108 # exit
# pause()
payload += p32(exi, endianness="big")[1:]
print(payload)
p.send(payload)
for i in range(100):
print(p.readline())

p.close()

level22.0

因为opcode和var_code的总数不是很多,可以记录一下。

opcode op
0x1 ADD
0x2 IMM
0x4 STK
0x8 JMP
0x10 LDM
0x20 SYS
0x40 STM
0x80 CMP

变量记录如下:

变量 Code
a 0x04
b 0x40
c 0x01
d 0x10
s 0x02
i 0x80
f 0x08

并且测试的时候发现,arg1在三字节的第一个位置,arg2在三字节中的第二个位置,opcode在最后。

关于SYS而言,Sleep是08,write是01,read_code是04,open是20,exit是40,read是80

针对SYS指令,第一个字节是syscode,第二个位置是变量code,第三个位置是opcode。

这种情况下,改exp就很快了。

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
52
53
54
55
56
57
58
59
60
61
62
from pwn import *
# context(arch="amd64",os="linux",log_level="debug",terminal=['tmux','splitw','-h'])
# p = gdb.debug('/tmp/babyrev-level-21-1', 'b interpreter_loop')
p = process("/challenge/babyrev-level-22-0")
payload = b''
imm_a= 0x043002 # IMM a = 0x30
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x402f02 # IMM b = 0x2f '/'
payload += p32(imm_b, endianness="big")[1:]
stm_a = 0x044040 # STM *a = b
payload += p32(stm_a, endianness="big")[1:]
imm_a= 0x043102 # IMM a = 0x31
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x406602 # IMM b = 0x66 'f'
payload += p32(imm_b, endianness="big")[1:]
stm_a = 0x044040 # STM *a = b
payload += p32(stm_a, endianness="big")[1:]
imm_a= 0x043202 # IMM a = 0x32
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x406c02 # IMM b = 0x6c 'l'
payload += p32(imm_b, endianness="big")[1:]
stm_a = 0x044040 # STM *a = b
payload += p32(stm_a, endianness="big")[1:]
imm_a= 0x043302 # IMM a = 0x33
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x406102 # IMM b = 0x61 'a'
payload += p32(imm_b, endianness="big")[1:]
stm_a = 0x044040 # STM *a = b
payload += p32(stm_a, endianness="big")[1:]
imm_a= 0x043402 # IMM a = 0x34
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x406702 # IMM b = 0x67 'g'
payload += p32(imm_b, endianness="big")[1:]
stm_a = 0x044040 # STM *a = b
payload += p32(stm_a, endianness="big")[1:]
imm_a= 0x043002 # IMM a = 0x30
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x400002 # IMM b = 0
payload += p32(imm_b, endianness="big")[1:]
sys_open = 0x200420 # open /flag
payload += p32(sys_open, endianness="big")[1:]
imm_b = 0x404002 # IMM b = 0x40
payload += p32(imm_b, endianness="big")[1:]
imm_c = 0x01ff02 # IMM c = 0xff
payload += p32(imm_c, endianness="big")[1:]
sys_read = 0x800120 # SYS Read
payload += p32(sys_read, endianness="big")[1:]
imm_a = 0x040102 # IMM a = 0x01
payload += p32(imm_a, endianness="big")[1:]
imm_b = 0x404002 # IMM b = 0x40
payload += p32(imm_b, endianness="big")[1:]
sys_read = 0x010420 # SYS write
payload += p32(sys_read, endianness="big")[1:]
exi = 0x0400420 # exit
# pause()
payload += p32(exi, endianness="big")[1:]
print(payload)
p.send(payload)
for i in range(200):
print(p.readline())

p.close()

level22.1

根据discord以及一些别人的wp,发现得查看Crash信息,才能知道。跑一下爆破脚本:

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
import subprocess
from pwn import *

command= ['/challenge/babyrev-level-22-0']

data = bytearray()

with open('res.txt', 'w') as file:
file.write('')

values = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80]
for i in values:
data.append(0x31) # arg1不相关,因此可以随便设置一个。但是得设置!
for j in values:
data.append(j)
data.append(i)
print(data.hex())
try:
res = subprocess.run(command,input=data,stdout=subprocess.PIPE, stderr=subprocess.PIPE,timeout=2)
with open('res.txt','ab') as file:
file.write(data.hex().encode('ascii'))
file.write(res.stdout[1074:])
except subprocess.TimeoutExpired:
print("timeout",data.hex())
data.pop()
data.pop()
data.clear()

对于22.0跑出来的结果如下(过滤出超时的部分):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
timeout 310108
timeout 310208
timeout 310408
timeout 310808
timeout 311008
timeout 312008
timeout 314008
timeout 318008
timeout 310120
timeout 310220
timeout 310420
timeout 310820
timeout 311020
timeout 314020
timeout 318020
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
310101
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x1 arg1:0x31 arg2:0x1
[s] ADD ? c
Machine CRASHED due to: unknown register
310201
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x1 arg1:0x31 arg2:0x2
[s] ADD ? s
Machine CRASHED due to: unknown register
310401
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x1 arg1:0x31 arg2:0x4
[s] ADD ? a
Machine CRASHED due to: unknown register
310801
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x1 arg1:0x31 arg2:0x8
[s] ADD ? f
Machine CRASHED due to: unknown register
311001
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x1 arg1:0x31 arg2:0x10
[s] ADD ? d
Machine CRASHED due to: unknown register
312001
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x1 arg1:0x31 arg2:0x20
[s] ADD ? ?
Machine CRASHED due to: unknown register
314001
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x1 arg1:0x31 arg2:0x40
[s] ADD ? b
Machine CRASHED due to: unknown register
318001
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x1 arg1:0x31 arg2:0x80
[s] ADD ? i
Machine CRASHED due to: unknown register
310102
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x2 arg1:0x31 arg2:0x1
[s] IMM ? = 0x1
Machine CRASHED due to: unknown register
310202
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x2 arg1:0x31 arg2:0x2
[s] IMM ? = 0x2
Machine CRASHED due to: unknown register
310402
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x2 arg1:0x31 arg2:0x4
[s] IMM ? = 0x4
Machine CRASHED due to: unknown register
310802
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x2 arg1:0x31 arg2:0x8
[s] IMM ? = 0x8
Machine CRASHED due to: unknown register
311002
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x2 arg1:0x31 arg2:0x10
[s] IMM ? = 0x10
Machine CRASHED due to: unknown register
312002
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x2 arg1:0x31 arg2:0x20
[s] IMM ? = 0x20
Machine CRASHED due to: unknown register
314002
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x2 arg1:0x31 arg2:0x40
[s] IMM ? = 0x40
Machine CRASHED due to: unknown register
318002
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x2 arg1:0x31 arg2:0x80
[s] IMM ? = 0x80
Machine CRASHED due to: unknown register
310104
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x4 arg1:0x31 arg2:0x1
[s] STK ? c
[s] ... pushing c
[s] ... popping ?
Machine CRASHED due to: unknown register
310204
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x4 arg1:0x31 arg2:0x2
[s] STK ? s
[s] ... pushing s
[s] ... popping ?
Machine CRASHED due to: unknown register
310404
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x4 arg1:0x31 arg2:0x4
[s] STK ? a
[s] ... pushing a
[s] ... popping ?
Machine CRASHED due to: unknown register
310804
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x4 arg1:0x31 arg2:0x8
[s] STK ? f
[s] ... pushing f
[s] ... popping ?
Machine CRASHED due to: unknown register
311004
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x4 arg1:0x31 arg2:0x10
[s] STK ? d
[s] ... pushing d
[s] ... popping ?
Machine CRASHED due to: unknown register
312004
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x4 arg1:0x31 arg2:0x20
[s] STK ? ?
[s] ... pushing ?
Machine CRASHED due to: unknown register
314004
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x4 arg1:0x31 arg2:0x40
[s] STK ? b
[s] ... pushing b
[s] ... popping ?
Machine CRASHED due to: unknown register
318004
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x4 arg1:0x31 arg2:0x80
[s] STK ? i
[s] ... pushing i
[s] ... popping ?
Machine CRASHED due to: unknown register
310110
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x10 arg1:0x31 arg2:0x1
[s] LDM ? = *c
Machine CRASHED due to: unknown register
310210
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x10 arg1:0x31 arg2:0x2
[s] LDM ? = *s
Machine CRASHED due to: unknown register
310410
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x10 arg1:0x31 arg2:0x4
[s] LDM ? = *a
Machine CRASHED due to: unknown register
310810
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x10 arg1:0x31 arg2:0x8
[s] LDM ? = *f
Machine CRASHED due to: unknown register
311010
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x10 arg1:0x31 arg2:0x10
[s] LDM ? = *d
Machine CRASHED due to: unknown register
312010
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x10 arg1:0x31 arg2:0x20
[s] LDM ? = *?
Machine CRASHED due to: unknown register
314010
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x10 arg1:0x31 arg2:0x40
[s] LDM ? = *b
Machine CRASHED due to: unknown register
318010
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x10 arg1:0x31 arg2:0x80
[s] LDM ? = *i
Machine CRASHED due to: unknown register
312020
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x20 arg1:0x31 arg2:0x20
[s] SYS 0x31 ?
[s] ... open
Machine CRASHED due to: unknown register
310140
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x40 arg1:0x31 arg2:0x1
[s] STM *? = c
Machine CRASHED due to: unknown register
310240
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x40 arg1:0x31 arg2:0x2
[s] STM *? = s
Machine CRASHED due to: unknown register
310440
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x40 arg1:0x31 arg2:0x4
[s] STM *? = a
Machine CRASHED due to: unknown register
310840
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x40 arg1:0x31 arg2:0x8
[s] STM *? = f
Machine CRASHED due to: unknown register
311040
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x40 arg1:0x31 arg2:0x10
[s] STM *? = d
Machine CRASHED due to: unknown register
312040
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x40 arg1:0x31 arg2:0x20
[s] STM *? = ?
Machine CRASHED due to: unknown register
314040
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x40 arg1:0x31 arg2:0x40
[s] STM *? = b
Machine CRASHED due to: unknown register
318040
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x40 arg1:0x31 arg2:0x80
[s] STM *? = i
Machine CRASHED due to: unknown register
310180
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x80 arg1:0x31 arg2:0x1
[s] CMP ? c
Machine CRASHED due to: unknown register
310280
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x80 arg1:0x31 arg2:0x2
[s] CMP ? s
Machine CRASHED due to: unknown register
310480
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x80 arg1:0x31 arg2:0x4
[s] CMP ? a
Machine CRASHED due to: unknown register
310880
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x80 arg1:0x31 arg2:0x8
[s] CMP ? f
Machine CRASHED due to: unknown register
311080
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x80 arg1:0x31 arg2:0x10
[s] CMP ? d
Machine CRASHED due to: unknown register
312080
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x80 arg1:0x31 arg2:0x20
[s] CMP ? ?
Machine CRASHED due to: unknown register
314080
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x80 arg1:0x31 arg2:0x40
[s] CMP ? b
Machine CRASHED due to: unknown register
318080
[V] a:0 b:0 c:0 d:0 s:0 i:0x1 f:0
[I] op:0x80 arg1:0x31 arg2:0x80
[s] CMP ? i
Machine CRASHED due to: unknown register

根据观察,可以发现:IMM,ADD,STK,LDM,STM和CMP不会出现Timeout。SYS和JMP会出现超时, 但是SYS open不会出现超时。

那么回推到level22.1:

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
300101
timeout 300101
300201
timeout 300201
300401
timeout 300401
300801
timeout 300801
301001
timeout 301001
302001
timeout 302001
304001
timeout 304001
308001
timeout 308001
300120
timeout 300120
300220
timeout 300220
300420
timeout 300420
300820
timeout 300820
301020
timeout 301020
302020
timeout 302020
304020
308020
timeout 308020

能够确定,01是JMP指令,20是SYS指令。且xx4020是open syscall。

然后我们把arg1改成0x00后发现(timeout设置为1):

对level22.0来说,JMP,STK和SYS都会超时7个。

对于level22.1来说,0180会超时7个,20会超时8个。

80是STK指令

把arg1改成0x10后发现:

对于level22.0来说,JMP和IMM都会超时8个,其余超时7个。

对于level22.1来说,0102超时8个,其余超时7个。

02是IMM指令

把arg1改成0x20后发现:

对于level22.0来说,JMP超时8个,SYS超时7个(open不超时),其余不超时。

对于level22.1来说,0102超时8个,其余超时7个。

把arg1改成0x40后发现:

对于level22.0来说,SYS都不超因为是exit,JMP,IMM全超时,其余超时7个。

对于level22.1来说,opcode20和opcode01超时。其余都不超时。

把arg1改成0x01后发现:

对于level22.1来说,SYS都不超时,JMP和IMM超时8个。其余超时7个,因此结合0x40参数来说,可以确定0x01是exit参数。随后可以使用imm + exit来确定i寄存器的位置。超时说明imm赋值了i寄存器,导致控制流改变,没有正确退出。得出i08

总结一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
JMP: 01
IMM: 02
SYS: 20 | open:40 exit:01
STK: 80
STM: ?
LDM: ?
ADD: ?
CMP: ?
-------------------------------------
a: ?
b: ?
c: ?
d: ?
s: ?
i: 08
f: ?

到这儿以后,根据之前的shellcode发现,指令这块儿只拿到STM就够了。那么如何让STM在LDM,ADD,CMP中脱颖而出呢?依然是改变i寄存器的值,只要这个改变,那么控制流就会改变。而ADD和LDM都会改变i的值,因此会超时。

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
import subprocess
from pwn import *

command= ['/challenge/babyrev-level-22-1']

data = bytearray()

# with open('res.txt', 'w') as file:
# file.write('')

values = [0x04, 0x08, 0x10, 0x40]
for i in values:
data.append(0x01)
data.append(0x30)
data.append(0x02) # IMM reg0x1 = 0x30

data.append(0x08) # i寄存器
data.append(0x01) # 0x1寄存器
data.append(i) # 依次改成04 08 10 40测试即可
data.append(0x01)
data.append(0x01)
data.append(0x20)
print(data.hex())
try:
res = subprocess.run(command,input=data,stdout=subprocess.PIPE, stderr=subprocess.PIPE,timeout=1)
except subprocess.TimeoutExpired:
print("timeout",data.hex())
data.clear()

结果为:

1
2
3
4
5
6
013002080104010120
timeout 013002080104010120
013002080108010120
013002080110010120
013002080140010120
timeout 013002080140010120

因此,可以判断出ADD指令和LDM指令在0x040x40中。而STM指令和CMP指令在0x080x10中。

进一步区STM和CMP指令需要借助JMP指令。因为CMP+JMP指令会导致跳转,从而超时。但是STM+JMP指令不会导致跳转。所以,CMP+JMP测试:

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
import subprocess
from pwn import *

command= ['/challenge/babyrev-level-22-1']

data = bytearray()

# with open('res.txt', 'w') as file:
# file.write('')

values = [0x08, 0x10]
values_2 = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80]
for i in values:
for j in values_2:
data.append(0x01)
data.append(0x30)
data.append(0x02) # IMM reg0x1 = 0x30

data.append(0x08) # arg1 i
data.append(0x08) # arg2 i
data.append(i) # CMP/STM i i
data.append(j)
data.append(0x01)
data.append(0x01)
data.append(0x01)
data.append(0x01)
data.append(0x20)
print(data.hex())
try:
res = subprocess.run(command,input=data,stdout=subprocess.PIPE, stderr=subprocess.PIPE,timeout=1)
except subprocess.TimeoutExpired:
print("timeout",data.hex())
data.clear()

这里对于JMP指令的参数是不知道的,因此也需要循环遍历。所以是双重循环。最后结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
hacker@reverse-engineering~level22-1:~/Desktop$ python vm.py 
013002080808010101010120
013002080808020101010120
013002080808040101010120
013002080808080101010120
013002080808100101010120
013002080808200101010120
013002080808400101010120
013002080808800101010120
013002080810010101010120
013002080810020101010120
013002080810040101010120
013002080810080101010120
013002080810100101010120
013002080810200101010120
013002080810400101010120
timeout 013002080810400101010120
013002080810800101010120

因此,确定到08081010是CMP指令。则08是STM指令的opcode。最后总结一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
JMP: 01
IMM: 02
SYS: 20 | open:40 exit:01
STK: 80
STM: 08
LDM: 04|40
ADD: 04|40
CMP: 10
-------------------------------------
a: ?
b: ?
c: ?
d: ?
s: ?
i: 08
f: ?

接下来通过SYS sleep来确定reg_a,因为SYS sleep会休眠reg_a秒。

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
import subprocess
from pwn import *

command= ['/challenge/babyrev-level-22-1']

data = bytearray()

# with open('res.txt', 'w') as file:
# file.write('')

values = [0x02, 0x4, 0x08, 0x10,0x20, 0x80]
values_2 = [0x01, 0x02, 0x04, 0x10, 0x20, 0x40, 0x80]
for i in values:
for j in values_2:
data.append(j)
data.append(0x10)
data.append(0x02) # IMM reg j = 0x10

data.append(i)
data.append(0x1) # sleep | write | read_code | read_mem
data.append(0x20)

data.append(0x01)
data.append(0x01)
data.append(0x20)
print(data.hex())
try:
res = subprocess.run(command,input=data,stdout=subprocess.PIPE, stderr=subprocess.PIPE,timeout=5)
except subprocess.TimeoutExpired:
print("timeout",data.hex())
data.clear()

结果为:timeout 101002020120010120。那么可以知道0x10为reg_a,且sleep的code为0x02。再次汇总:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
JMP: 01
IMM: 02
SYS: 20 | open:40 exit:01 sleep:02
STK: 80
STM: 08
LDM: 04|40
ADD: 04|40
CMP: 10
-------------------------------------
a: 10
b: ?
c: ?
d: ?
s: ?
i: 08
f: ?

接下来可以确定write,因为可以将rax置为0x1这样就会输出在屏幕中了,因此我们可以遍历rcx,因为rcx控制的是输出字符数量,再遍历read | write | read_code

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
import subprocess
from pwn import *

command= ['/challenge/babyrev-level-22-1']
data = bytearray()

# with open('res.txt', 'w') as file:
# file.write('')

values = [0x4, 0x08, 0x10,0x20, 0x80]
values_2 = [0x01, 0x02, 0x04, 0x20, 0x40, 0x80]
for i in values:
for j in values_2:
data.append(j)
data.append(0x01)
data.append(0x02) # IMM c = 0x01

data.append(0x10)
data.append(0x01)
data.append(0x02) # IMM a = 0x01

data.append(i)
data.append(0x01) # write | read_code | read_mem
data.append(0x20)

data.append(0x01)
data.append(0x01)
data.append(0x20)
print(data.hex())
try:
res = subprocess.run(command,input=data,stdout=subprocess.PIPE, stderr=subprocess.PIPE,timeout=1)
print(len(res.stdout))
except subprocess.TimeoutExpired:
print("timeout",data.hex())
data.clear()

查看结果,可以找到长度不一致的输入。这个就是我们找到的write和rcx:

1
2
3
4
5
6
7
8
9
10
800102100102080120010120
1075
010102100102100120010120
1075
020102100102100120010120
1076
040102100102100120010120
1075
200102100102100120010120
1075

那么可以知道,write是0x10,rcx是0x02。然后read也很简单,写一个exp,并且使用interactive,如果这个interactive一直在等待输入,那么说明是read_memory或者read_code。exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from pwn import *
# context(arch="amd64",os="linux",log_level="debug",terminal=['tmux','splitw','-h'])
# p = gdb.debug('/challenge/babyrev-level-22-1', 'b *$rebase(0x2345)')
p = process("/challenge/babyrev-level-22-1")
payload = b''
imm_c = 0x020102
payload += p32(imm_c, endianness="big")[1:]
imm_a = 0x100002
payload += p32(imm_a, endianness="big")[1:]
sys_read = 0x201020 # read_mem | read_code | other
payload += p32(sys_read, endianness="big")[1:]
sys_exit = 0x010120
payload += p32(sys_exit, endianness="big")[1:]
print(payload)
p.send(payload)
# for i in range(50):
# print(p.readline())
p.interactive()
p.close()

最终确定,read_mem和read_code是2008之中的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
JMP: 01
IMM: 02
SYS: 20 | open:04 | 40 exit:01 sleep:02 write:10 read:08|20
STK: 80
STM: 08
LDM: 04|40
ADD: 04|40
CMP: 10
-------------------------------------
a: 10
b: 04
c: 02
d: 01|04|20|80
s: 01|04|20|80
i: 08
f: 01|04|20|80

最后,即可使用Shellcode的爆破。依次去试出来。

这里发现了一个错误…因为一开始错误的认为Open是0x40导致后面的exp一直出不来。最后试了一下0x4出来了。因此如果open有问题,那么就也进行一个尝试即可。


pwn.college: Reverse Engineering
https://loboq1ng.github.io/2025/03/12/pwn-college-Reverse-Engineering/
作者
Lobo Q1ng
发布于
2025年3月12日
许可协议