1.0

有这么个东西

1.1

还是一样,有个对比

2.0

首先,在原位置还有一个对比

其次,在上面对输入的字符串做了变换

要注意的是字符串是从0开始数的

2.1

还是老位置的对比
注意对比之前的操作

将v3和v5交换,这两个是什么呢,v3是字符串的第三位,v5是buf之后的一个数据

同时需要注意一个问题,buf字符串是int类型,意味着只有4位,在输入的时候却获取了5位,结合上面的分析,将字符串的第三位和第五位交换

3.0


buf一共5位,不难理解吧?

3.1

这好像没啥区别

4.0

当时好好学c语言确实是个不错的选择

4.1

一样的内容,感觉这两题他的对比值不应该这么写=.=

5.0

异或嘛,整个小脚本就出来了

5.1

一样的东西咯

6.0

首先看程序都做了什么

  • 对输入的字符串,奇数位异或0xE3,偶数为异或0xA1
  • 以对称中心交换位置
  • 从小到大排序

并且现在我们知道排序之后的内容,那么就可以直接不用管其他,以现在的位置,奇数位异或0xE3,偶数位异或0xA1,下面两个无效果直接绕过

6.1

三次交换

7.0

整理程序流程:

  • 交换第1位和第17位
  • 两次异或
  • 排序
  • 反序

根据上述流程可以将密文初步解密(两次异或+交换1和17的位置),但是解出来的东西无法显示,用python脚本进行输入

7.1

switch需要修复,修复教程:

总结程序流程:

  • 第4位和第14位交换位置(buf和v13都是8字节,并且v13在buf下面紧邻)

    v3 = BYTE3(buf);
    BYTE3(buf) = BYTE5(v13);
    BYTE5(v13) = v3;

  • 倒序
  • 从小到大排序
  • 再次倒序
  • 5个一组进行异或处理

说白了就是一堆排序外加一个异或处理,那么就可以直接异或回去找输入

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
#include<iostream>
using namespace std;

int main(int argc, char const *argv[])
{
int buf[] = {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, 0x00};


for (int n = 0; n <= 28; ++n )
{
switch ( (n % 5) )
{
case 0:
*(buf + n) ^= 0x75;
break;
case 1:
*(buf + n) ^= 0x7E;
break;
case 2:
*(buf + n) ^= 1;
break;
case 3:
*(buf + n) ^= 0x3D;
break;
case 4:
*(buf + n) ^= 0xC5;
break;
default:
continue;
}
}


for(int i =0; i<=28; i++)
{
printf("%c", buf[i]);
}
return 0;
}

8.0

首先修复switch

分析:

  • 从小到大排序
  • 奇偶位进行不同的异或处理
  • 同上
  • 倒序
  • 六个一组进行异或处理
  • 交换第14和第17位数据
  • 交换第6和第33位

这次的交换就需要先处理了,应为交换是放在最后的,所以一定会影响最终结果

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
#include<iostream>
using namespace std;

int main(int argc, char const *argv[])
{
int buf[] = {0xA6, 0x4E, 0x73, 0xB2, 0x56, 0x67, 0xA9, 0x40, 0x71, 0xB0,
0x55, 0x68, 0xAD, 0x4B, 0x75, 0xAE, 0x44, 0x71, 0xB6, 0x5F,
0x6C, 0xA2, 0x47, 0x7D, 0xBA, 0x53, 0x61, 0xA1, 0x45, 0x7F,
0xBB, 0x52, 0x6D, 0xA6, 0x43, 0x79, 0xBD, 0x00};

int a=buf[5];
buf[5] = buf[32];
buf[32] = a;

a= buf[13];
buf[13] = buf[16];
buf[16] = a;

for (int i1 = 0; i1 <= 36; ++i1 )
{
if ( (i1 % 6) <= 5 )
{
switch ( i1 % 6 )
{
case 0:
*(buf + i1) ^= 0xB5;
break;
case 1:
*(buf + i1) ^= 0x73;
break;
case 2:
*(buf + i1) ^= 0x6E;
break;
case 3:
*(buf + i1) ^= 0x80;
break;
case 4:
*(buf + i1) ^= 0x4B;
break;
case 5:
*(buf + i1) ^= 0x5E;
break;
default:
continue;
}
}
}

for (int n = 0; n <= 36; ++n )
{
if ( n % 2 )
{
*(buf + n) ^= 0x67;
*(buf + n) ^= 0x22;
}
else
{
*(buf + n) ^= 0x1A;
*(buf + n) ^= 0x70;
}
}




for(int i =0; i<=36; i++)
{
printf("%c", buf[i]);
}
return 0;
}

8.1

流程分析

  • 小到大排序
  • 交换第5和21位
  • 交换第2和25位
  • 交换第6和26位
  • 四个一组进行异或处理
  • 交换第4和30位
  • 倒序

按照顺序写脚本吧

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
#include<iostream>
using namespace std;

int main(int argc, char const *argv[])
{
int buf[] = {0x11, 0xFA, 0x4E, 0x66, 0x1E, 0x65, 0x4C, 0x74, 0x1A, 0xE6,
0x49, 0x68, 0x06, 0xEC, 0x5D, 0x69, 0x04, 0xEE, 0x52, 0x6E,
0x01, 0xEA, 0x51, 0x6F, 0x0E, 0xE5, 0x5C, 0x62, 0x0C, 0xF0,
0x57, 0xF7, 0x0B, 0xF5, 0x58, 0x00};

for (int m = 0; m <= 16; ++m )
{
int v8 = *(buf + m);
*(buf + m) = *(buf + 34 - m);
*(buf + 34 - m) = v8;
}

int a = buf[3];
buf[3] = buf[29];
buf[29] = a;

for (int k = 0; k <= 34; ++k )
{
int v3 = k % 4;
if ( k % 4 == 3 )
{
*(buf + k) ^= 7u;
}
else if ( v3 <= 3 )
{
if ( v3 == 2 )
{
*(buf + k) ^= 0x69u;
}
else if ( v3 <= 2 )
{
if ( v3 )
{
if ( v3 == 1 )
*(buf + k) ^= 0x82u;
}
else
{
*(buf + k) ^= 0x39u;
}
}
}
}

a = buf[6];
buf[6] = buf[26];
buf[26] = a;

a = buf[2];
buf[2] = buf[25];
buf[25] = a;

a = buf[5];
buf[5] = buf[21];
buf[21] = a;


for(int i =0; i<0x23; i++)
{
printf("%c", buf[i]);
}
return 0;
}

9.0

考的是patch,程序给了任意patch的能力,注意这个v12是程序加载基址

这样的话将下面的jnz改成jz就行,或者直接nop掉

9.1

同上

10.0

同上,注意只能改一个字节

10.1

同上

11.0

同上,只不过需要改两处

11.1

大致一样,注意第一个跳转

12.0

vm题,挺好玩,也就费了我一中午时间(T_T),输入我用的py进行输入的

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
[s] IMM b = 0x62
[s] IMM c = 0x8
[s] IMM a = 0
[s] SYS 0x4 a
[s] ... read_memory ----> read a1[0x62]
aaa
[s] ... return value (in register a): 0x4
[s] IMM b = 0x82
[s] IMM c = 0x1
[s] IMM a = 0xc8
[s] STM *b = a ----> a1[b]=a ====> a1[0x82]=0xc8
[s] ADD b c ----> b=b+c ====> b=0x83
[s] IMM a = 0xfc
[s] STM *b = a ----> a1[b]=a ====> a1[0x83]=0xfc
[s] ADD b c ----> b=b+c ====> b=0x84
[s] IMM a = 0x5b
[s] STM *b = a ----> a1[b]=a ====> a1[0x84]=0x5b
[s] ADD b c
[s] IMM a = 0xa8
[s] STM *b = a ----> a1[b]=a ====> a1[0x85]=0xa8
[s] ADD b c
[s] IMM a = 0x58
[s] STM *b = a ----> a1[b]=a ====> a1[0x86]=0x58
[s] ADD b c
[s] IMM a = 0xf4
[s] STM *b = a ----> a1[b]=a ====> a1[0x87]=0xf4
[s] ADD b c
[s] IMM a = 0x6b
[s] STM *b = a ----> a1[b]=a ====> a1[0x88]=0x6b
[s] ADD b c
[s] IMM a = 0xce
[s] STM *b = a ----> a1[b]=a ====> a1[0x89]=0xce
[s] ADD b c

v2 = memcmp((const void *)(a1 + 0x82), (const void *)(a1 + 0x62), 8uLL) == 0;

12.1

看起来和12.1差不多,就不分析了(一中午了,确实头疼,呜呜呜~)
直接试试

呜呜,做完试着看了下,vm太搞心态来

13.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
[s] IMM b = 0x42
[s] IMM c = 0x6
[s] IMM a = 0
[s] SYS 0x8 a
[s] ... read_memory read(0, a1[0x42], 0x6)
j
[s] ... return value (in register a): 0x2
[s] IMM b = 0x62
[s] IMM c = 0x1
[s] IMM a = 0xa2
[s] STM *b = a a1[0x62] = 0xa2
[s] ADD b c
[s] IMM a = 0x22
[s] STM *b = a a1[0x63] = 0x22
[s] ADD b c
[s] IMM a = 0xfb
[s] STM *b = a a1[0x64] = 0xfb
[s] ADD b c
[s] IMM a = 0x44
[s] STM *b = a a1[0x65] = 0x44
[s] ADD b c
[s] IMM a = 0x11
[s] STM *b = a a1[0x66] = 0x11
[s] ADD b c
[s] IMM a = 0x52
[s] STM *b = a a1[0x67] = 0x52
[s] ADD b c
[s] IMM b = 0x62
[s] LDM b = *b b = 0xa2
[s] IMM a = 0x42
[s] LDM a = *a a = a1[0x42]
[s] CMP a b

if ( (*(_BYTE *)(a1 + 262) & 0x10) == 0 )

[s] IMM b = 0x63
[s] LDM b = *b
[s] IMM a = 0x43
[s] LDM a = *a
[s] CMP a b

if ( (*(_BYTE *)(a1 + 262) & 0x10) == 0 )

[s] IMM b = 0x64
[s] LDM b = *b
[s] IMM a = 0x44
[s] LDM a = *a
[s] CMP a b

if ( (*(_BYTE *)(a1 + 262) & 0x10) == 0 )

[s] IMM b = 0x65
[s] LDM b = *b
[s] IMM a = 0x45
[s] LDM a = *a
[s] CMP a b

if ( (*(_BYTE *)(a1 + 262) & 0x10) == 0 )

[s] IMM b = 0x66
[s] LDM b = *b
[s] IMM a = 0x46
[s] LDM a = *a
[s] CMP a b

if ( (*(_BYTE *)(a1 + 262) & 0x10) == 0 )

[s] IMM b = 0x67
[s] LDM b = *b
[s] IMM a = 0x47
[s] LDM a = *a
[s] CMP a b

if ( (*(_BYTE *)(a1 + 262) & 0x10) == 0 )

[s] IMM a = 0x1
[s] IMM b = 0
[s] IMM c = 0x1

13.1

同上

14.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 = 0x7d
[s] IMM c = 0x6
[s] IMM a = 0
[s] SYS 0x4 a
[s] ... read_memory read a1[0x7d]
aaa
[s] ... return value (in register a): 0x4
[s] IMM b = 0x9d
[s] IMM c = 0x1
[s] IMM a = 0xbe
[s] STM *b = a a1[0x9d] = 0xbe
[s] ADD b c
[s] IMM a = 0x51
[s] STM *b = a a1[0x9e] = 0x51
[s] ADD b c
[s] IMM a = 0x36
[s] STM *b = a a1[0x9f] = 0x36
[s] ADD b c
[s] IMM a = 0x82
[s] STM *b = a a1[0xa0] = 0x82
[s] ADD b c
[s] IMM a = 0xb8
[s] STM *b = a a1[0xa1] = 0xb8
[s] ADD b c
[s] IMM a = 0x2d
[s] STM *b = a a1[0xa2] = 0x2d
[s] ADD b c
[s] IMM b = 0x9d
[s] IMM c = 0x1
[s] LDM a = *b a=0xbe
[s] IMM d = 0x89
[s] ADD a d a=0x147
[s] STM *b = a a1[0x9d] = 0x47
[s] ADD b c
[s] LDM a = *b
[s] IMM d = 0x81
[s] ADD a d
[s] STM *b = a a1[0x9d] = 0xd2
[s] ADD b c
[s] LDM a = *b
[s] IMM d = 0xd7
[s] ADD a d
[s] STM *b = a a1[0x9d] = 0x0d
[s] ADD b c
[s] LDM a = *b
[s] IMM d = 0xa8
[s] ADD a d
[s] STM *b = a a1[0x9d] = 0x2a
[s] ADD b c
[s] LDM a = *b
[s] IMM d = 0xa4
[s] ADD a d
[s] STM *b = a a1[0x9d] = 0x5c
[s] ADD b c
[s] LDM a = *b
[s] IMM d = 0xf
[s] ADD a d
[s] STM *b = a a1[0x9d] = 0x3c
[s] ADD b c
[s] IMM b = 0x9d
[s] LDM b = *b
[s] IMM a = 0x7d
[s] LDM a = *a
[s] CMP a b
[s] IMM b = 0x9e
[s] LDM b = *b
[s] IMM a = 0x7e
[s] LDM a = *a
[s] CMP a b
[s] IMM b = 0x9f
[s] LDM b = *b
[s] IMM a = 0x7f
[s] LDM a = *a
[s] CMP a b
[s] IMM b = 0xa0
[s] LDM b = *b
[s] IMM a = 0x80
[s] LDM a = *a
[s] CMP a b
[s] IMM b = 0xa1
[s] LDM b = *b
[s] IMM a = 0x81
[s] LDM a = *a
[s] CMP a b
[s] IMM b = 0xa2
[s] LDM b = *b
[s] IMM a = 0x82
[s] LDM a = *a
[s] CMP a b
[s] IMM a = 0x1
[s] IMM b = 0
[s] IMM c = 0x1

14.1

这个确实是比较恶心了,他把输入的数据进行了+运算,搞得有些得输入负数,用溢出的原理进行负数输入就好,分析就不放了,和上个题一样的

15.0

做顺了的话感觉还可以(主要是这套汇编指令特别熟悉了2333),不做分析了,比上一个还能简单一些感觉

15.1

数学没学好,脚本半天写不好,服了,0x一生之敌

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
aaa = [0xF2-0x1E,
0x58-0x1B,
0x47-0x19,
0xCD-0xC3,
0x4C-0xC1,
0xAE-0xA9,
0x2B-0xA7,
0x65-0x28,
0xB5-0x59,
0x6F-0x1E,
0xCB-0x9A,
0x61-0x8F]

flag = ''
for i in aaa:
print(hex(i))
if i < 0:
flag = hex(0x100+i)[2:].rjust(2, '0') + flag
print(hex(0x100+i))
else:
flag = hex(i)[2:].rjust(2, '0') + flag
print(hex(i))
print()

print(flag)

16.0