12. goforfun(寄)
前面是一些无关紧要的初始化
下面看到疑似rc4
虽然函数支离破碎,但可以看到rc4的结构,异或的部分做了魔改
后面似乎是base64换表,但脚本跑不出来,这里的算法没搞懂,只能贴一下别的dalao的
先逆后面的不明加密
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
unsigned char findPos(const unsigned char* base64_map, unsigned char c)//查找下标所在位置
{
for (int i = 0; i < strlen((const char*)base64_map); i++)
{
if (base64_map[i] == c)
return i;
}
}
unsigned char* base64_decode(const unsigned char* code0)
{
unsigned char* code = (unsigned char*)code0;
unsigned char base64_map[65] = "8G+cazk2jqb7w01CtoKH4FsrgR3vVmQ9pPhXLAleOd/nB6DfIxMWYiUZ5SEJyNuT";
long len, str_len, flag = 0;
unsigned char* res;
len = strlen((const char*)code);
if (code[len - 1] == '=')
{
if (code[len - 2] == '=')
{
flag = 1;
str_len = len / 4 * 3 - 2;
}
else
{
flag = 2;
str_len = len / 4 * 3 - 1;
}
}
else
str_len = len / 4 * 3;
res = (unsigned char*)malloc(sizeof(unsigned char) * str_len + 1);
unsigned char a[4] = { 0 };
for (int i = 0, j = 0; j < str_len - flag; j += 3, i += 4)
{
a[0] = findPos(base64_map, code[i]); //code[]每一个字符对应base64表中的位置,用位置值反推原始数据值
a[1] = findPos(base64_map, code[i + 1]);
a[2] = findPos(base64_map, code[i + 2]);
a[3] = findPos(base64_map, code[i + 3]);
res[j] = a[0] | ((a[1] & 0x3) << 6);//第一个字符对应
res[j + 1] = ((a[1] & 0x3c) >> 2) | ((a[2] & 0xf) << 4);
res[j + 2] = ((a[3] & 0x3f) << 2) | ((a[2] & 0x30) >> 4);
}
switch (flag)
{
case 0:break;
case 1:
{
a[0] = findPos(base64_map, code[len - 4]);
a[1] = findPos(base64_map, code[len - 3]);
res[str_len - 1] = a[0] | ((a[1] & 0x3) << 6);
break;
}
case 2: {
a[0] = findPos(base64_map, code[len - 4]);
a[1] = findPos(base64_map, code[len - 3]);
a[2] = findPos(base64_map, code[len - 2]);
res[str_len - 2] = a[0] | ((a[1] & 0x3) << 6);//第一个字符对应
res[str_len - 1] = ((a[1] & 0x3c) >> 2) | ((a[2] & 0xf) << 4);
break;
}
}
res[str_len] = '\0';
return res;
}
int main() {
unsigned char BaseData[] = "HZ0sMJXqxHgUb2b9RNg+1xw=";
unsigned char* result = base64_decode(BaseData);//魔改base
for (int i = 0; i < 17; i++)
printf("%#x,", result[i]);
return 0;
}
//0xd3,0xdd,0x58,0xf2,0x3e,0x26,0xf1,0x84,0xd9,0xca,0xa1,0x7c,0x59,0x8f,0x9,0x4e,0xcc,
之后rc4比较好还原一点
#goforfun wp
enc = "HZ0sMJXqxHgUb2b9RNg+1xw"
#enc = [0x48,0x5a,0x30,0x73,0x4d,0x4a,0x58,0x71,0x78,0x48,0x67,0x55,0x62,0x32,0x62,0x39,0x52,0x4e,0x67,0x2b,0x31,0x78,0x77]
key = 'happynewyear'
basemap = "8G+cazk2jqb7w01CtoKH4FsrgR3vVmQ9pPhXLAleOd/nB6DfIxMWYiUZ5SEJyNuT"
enc1=[0xd3,0xdd,0x58,0xf2,0x3e,0x26,0xf1,0x84,0xd9,0xca,0xa1,0x7c,0x59,0x8f,0x9,0x4e,0xcc]
enc2 = enc1[::-1]
#魔改rc4
s_box = [0]*256
for i in range(255,-1,-1):
s_box[i] = - 1 - i
#print(s_box)
v8 = 0
v9 = 0
while ( v8 < 256 ):
v10 = s_box[v8]
v11 = v8
v12 = v8 - 12 * (((2863311531 * v8) >> 32) >> 3)
v9 += ord(key[v12%len(key)]) + v10
v9 %= 256
s_box[v11] = s_box[v9]
s_box[v9] = v10
v8 = v11 + 1
#S盒初始化
#print(s_box)
v4 = 0
v5 = 0
v6 = 0
for i in range(len(enc2)):
v7 = s_box[v5 + 1]%256
v8 = (v7 + v6)%256
s_box[v5 + 1] = s_box[v8]
s_box[v8] = v7
enc2[v4] ^= s_box[(v7 + s_box[v5 + 1])%256] ^ 0x2F
enc2[v4] &= 0xFF
v4 += 1
v5 += 1
v6 = v8
flag = ''
for i in range(len(enc2)):
flag += chr(enc2[i])
print(flag)
#go_a_nice_journey
13. 出题人的密码是什么
修花指令得到主逻辑,反调试也patch掉
然后下面有一堆函数需要找加密在哪里,只能慢慢来找,可以把翻过的函数改名字减少重复劳动
中间__rdtsc函数部分是检测时间的函数,调试的时候跳过就行
__rdtsc 是一个在 x86 和 x86-64 架构上的内建函数,它读取当前的时间戳计数器(Time Stamp Counter, TSC)。时间戳计数器是一个由 CPU 提供的 64 位寄存器,它以一种非常高的频率(通常是 CPU 的主频)自增。由于其递增的频率非常高,它常被用作一个高精度的时间源,尤其是在需要测量代码执行时间等场景中。
最后发现两个加密部分
类似CRC的部分需要动调获得key的值,虽然是随机生成的但是其值不变
修改标志寄存器SF的跳过检验
key=0x33077D
从二进制角度理解更容易逆向
和0比较实际上是比较最高位(标志位)是0还是1:
- 如果是1(负数),就左移一位(*2)与key异或
由于key最后一位是1,v6左移一位最后一位是0,异或结果最后一位必然是1。因此逆向的时候,如果一次加密后最后一位是1,这次加密前它肯定是负数
- 如果是0(正数),就左移一位,最后一位就变成0。同理,最后一位是0的本次加密前一定是正数。
由此可以构建逆向脚本。
简单的异或
提一下密文就可以逆了
#出题人密码
crypto = [0xB4, 0xBB, 0xD8, 0xEB, 0xD0, 0x6E, 0xAB, 0xCA, 0x65, 0x8E,
0x4B, 0xE9, 0x4D, 0xD4, 0x4A, 0xF3, 0x7D, 0x29, 0xC2, 0xF9,
0x95, 0x89, 0xA4, 0x85, 0x9D, 0xCD, 0xDF, 0x77, 0xFD, 0x45,
0xCB, 0x5D, 0x7D, 0xFD, 0x93, 0x4B, 0xBC, 0xF6, 0x7C, 0xF3,
0x24, 0x42, 0xF5, 0xD2, 0xDD, 0xE3, 0x56, 0xAE]
#异或部分逆向
enc2 = [0]*len(crypto)
for i in range(len(crypto)):
enc2[i] = ((crypto[i] ^ 0x25) - 5) & 0xff #这边要多加括号和限制位数,不然结果会有问题
print(enc2)
key = 0x33077D
#CRC部分逆向
def decrc(value, key):
for i in range(64):
if value & 1: #最后一位是1,加密前肯定是负数
value = (value ^ key) >> 1
value |= 0x8000000000000000 #还原最高位
else: #最后一位是0,加密前必为正数
value = value >> 1
return value
flag = b''
for i in range(0, len(enc2), 8):
enc1 = int.from_bytes(enc2[i: i + 8], 'little')
flag += decrc(enc1, key).to_bytes(8, 'little')
print(flag)
'''
[140, 153, 248, 201, 240, 70, 137, 234, 59, 166, 105, 199, 99, 236, 106, 209, 83, 7, 226, 215, 171, 167, 124, 155, 179, 227, 245, 77, 211, 91, 233, 115, 83, 211, 177, 105, 148, 206, 84, 209, 252, 98, 203, 242, 243, 193, 110, 134]
b'begin{Th1s_reverse_pr0blem_may_t@ke_some_time#!}'
'''
14. ezvm
前面有一堆内存分配也不到有啥用
flag长度为32
34行 进去一大堆数据,猜测是opcode操作码
37行 可以看到最后的密文
35、36行很奇怪,动调后可以发现是虚拟机的初始化和分发函数
似乎是形成一个结构体存储opcode里的内容
修一修数据类型得到dispatcher部分的逻辑
根据不同的操作码调用不同偏移地址的函数(有些我已经改了名字先不管)
然后分析各个函数模拟的操作(我也不会分析……只是对着官方wp稍微理解一下)
提一下opcode打印指令,好在不是所有的函数都被用到了
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
unsigned char opcode[] =
{
0x70, 0x00, 0x00, 0x00, 0x1E, 0x71, 0x30, 0x73, 0x00, 0x7A,
0x73, 0x10, 0x67, 0x01, 0x7B, 0x74, 0x00, 0x7A, 0x75, 0x0B,
0x70, 0x00, 0x00, 0x00, 0x1E, 0x71, 0x30, 0x7B, 0x75, 0x01,
0x70, 0x00, 0x00, 0x00, 0x1E, 0x71, 0x30, 0x73, 0x10, 0x7A,
0x73, 0x00, 0x6D, 0x01, 0x74, 0x00, 0x75, 0x09, 0x66
};
for (int i = 0; i < 49; i++)
{
if ((opcode[i] >= 0x66 && opcode[i] <= 0x7C) && (opcode[i - 1] >= 0x66 && opcode[i - 1] <= 0x7C))
{
printf("\n");
}
switch (opcode[i])
{
case 0x66:
printf("nop ");
continue;
case 0x67:
printf("add ");
continue;
case 0x68:
printf("sub ");
continue;
case 0x69:
printf("mul ");
continue;
case 0x6A:
printf("div ");
continue;
case 0x6B:
printf("inc ");
continue;
case 0x6C:
printf("dec ");
continue;
case 0x6D:
printf("xor ");
continue;
case 0x6E:
printf("and ");
continue;
case 0x6F:
printf("push ");
continue;
case 0x70:
printf("pushd ");
continue;
case 0x71:
printf("pop ");
continue;
case 0x72:
printf("mov ");
continue;
case 0x73:
printf("movd ");
continue;
case 0x74:
printf("move2d ");
continue;
case 0x75:
printf("loop ");
continue;
case 0x76:
printf("cmp ");
continue;
case 0x77:
printf("jl ");
continue;
case 0x78:
printf("jg ");
continue;
case 0x79:
printf("jz ");
continue;
case 0x7A:
printf("incd ");
continue;
case 0x7B:
printf("decd ");
continue;
case 0x7C:
printf("xor_ops ");
continue;
default:
if (opcode[i + 1] >= 0x66 && opcode[i + 1] <= 0x7C)
{
printf("%#x\n", opcode[i]);
}
else
{
printf("%#x, ", opcode[i]);
}
continue;
}
}
return 0;
}
/*
pushd 0, 0, 0, 0x1e
pop 0x30
movd 0
incd
movd 0x10
add 0x1
decd
move2d 0
incd
loop 0xb
pushd 0, 0, 0, 0x1e
pop 0x30
decd
loop 0x1
pushd 0, 0, 0, 0x1e
pop 0x30
movd 0x10
incd
movd 0
xor 0x1
move2d 0
loop 0x9
nop
*/
然后看不懂一点,贴一下官方wp
PUSHD, 0x00, 0x00, 0x00, 0x1E, //flag length-2
POP, 0x30, //r3 = 0x2f
MOVD, 0x00, //loop begin r0=dd
INCD,
// d[i]+=d[i+1]
MOVD, 0x10, // r1 = d[i]
ADD, 0x01, // r0 += r1
DECD, //i--
MOV2D, 0x00,
INCD, // d[i] = r0
LOOP, 0x0B, //loop
//i=0
PUSHD, 0x00, 0x00, 0x00, 0x1E,//flag length-2
POP, 0x30,
DECD, //loop begin
LOOP, 0x01,
PUSHD, 0x00, 0x00, 0x00, 0x1E,//flag length-2
POP, 0x30,
// d[i]^=d[i-1]
MOVD, 0x10, //loop begin
INCD,
MOVD, 0x00,
XOR, 0x01,
MOV2D, 0x00,
LOOP, 0x09, //loop
END
data = [0xC7, 0x0B, 0xDB, 0x0C, 0xE5, 0x08, 0xAD, 0xDE, 0xAF, 0xCD, 0x67, 0xBF, 0x1F, 0xBF, 0x1E, 0x68, 0xFE, 0x25, 0xFD, 0x6F, 0x08, 0x50, 0xCD, 0x15, 0xB0, 0x21, 0x8B, 0x3E, 0xFD, 0x73, 0xED, 0x90]
for i in range(len(data)-1,0,-1):
data[i]^=data[i-1]
for i in range(len(data)-2,-1,-1):
data[i]-=data[i+1]
print(bytes(data))
#b'begin{r3@11y_A_B4by_34$y_FK_Vm!}'
15. babyvm(寄)
完全学不懂,存一份脚本吧
opcode=[]
with open('opcode.vm','rb') as file:
content=file.read()
for i in range(0,len(content),4):
opcode1=int.from_bytes(content[i:i+4],byteorder='little',signed=True)
opcode.append(opcode1)
memory=[]
with open('memory.vm','rb') as file:
content=file.read()
for i in range(0,len(content),4):
memory1=int.from_bytes(content[i:i+4],byteorder='little',signed=True)
memory.append(memory1)
opcode_key = {
1:'{} add {} {}',
2:'{} sub {} {}',
3:'{} mul {} {}',
4:'{} div {} {}',
5:'{} in_pointer 0',
6:'{} out_pointer 0',
7:'{} push flag',
8:'{} pop output',
9:'{} scanf flag',
10:'{} show flag',
11:'{} jmp {}',
12:'{} njmp ',
13:'{} len',
}
def get_eip(eip):
return '_' + str(eip) + ':'
v16=opcode
i=0
disam=''
while i>=0 and i< len(opcode):
x=v16[i]
if x == 1:
disam += opcode_key[x].format(get_eip(i), memory[v16[(i + 2)]], memory[v16[(i + 2 + 1)]]) + '\n'
memory[v16[i + 1]] = memory[v16[i + 2]] + memory[v16[i + 2 + 1]]
i += 3 + 1
continue
if x == 2:
disam += opcode_key[x].format(get_eip(i), memory[v16[(i + 2 + 1)]], memory[v16[(i + 2)]]) + '\n'
memory[v16[i + 1]] = memory[v16[i + 2]] + memory[v16[i + 2 + 1]]
#print(memory[v16[i + 1]])+'\n')
i += 3 + 1
continue
if x == 3:
disam += opcode_key[x].format(get_eip(i), memory[v16[(i + 2)]], memory[v16[(i + 2 + 1)]]) + '\n'
memory[v16[i + 1]] = memory[v16[i + 2]] * memory[v16[i + 2 + 1]]
print(memory[v16[i + 1 +2]])
print(',')
i += 3 + 1
continue
if x == 4:
disam += opcode_key[x].format(get_eip(i), memory[v16[(i + 2)]], memory[v16[(i + 2 + 1)]]) + '\n'
memory[v16[i + 1]] = memory[v16[i + 2]] / memory[v16[i + 2 + 1]]
i += 3 + 1
continue
if x == 5:
disam += opcode_key[x].format(get_eip(i)) + '\n'
v5 = 0
i += v5 + 1
continue
if x == 6:
disam += opcode_key[x].format(get_eip(i)) + '\n'
v6 = 0
i += v6 + 1
continue
if x == 7:
disam += opcode_key[x].format(get_eip(i)) + '\n'
v7 = 2
i += v7 + 1
continue
if x == 8:
disam += opcode_key[x].format(get_eip(i)) + '\n'
v8 = 2
i += v8 + 1
continue
if x == 9:
disam += opcode_key[x].format(get_eip(i)) + '\n'
buf = 1
i += buf + 1
continue
if x == 10:
disam += opcode_key[x].format(get_eip(i)) + '\n'
v10 = 1
i += v10 + 1
continue
if x == 11:
disam += opcode_key[x].format(get_eip(i), memory[v16[(i + 1)]]) + '\n'
v11 = 2
i += v11 + 1
continue
if x == 12:
disam += opcode_key[x].format(get_eip(i)) + '\n'
v12 = 2
i += v12 + 1
continue
if x == 13:
disam += opcode_key[x].format(get_eip(i)) + '\n'
v13 = 2
i += v13 + 1
continue
disam+='exit(0)\n'
i += 1
continue
#print(disam)
from z3 import *
flag = []
key = [115
,
26
,
128
,
200
,
21
,
234
,
172
,
152
,
39
,
71
,
55
,
28
,
105
,
42
,
75
,
63
,
114
,
205
,
2
,
222
,
212
,
148
,
17
,
74
,
87
,
253
,
250
,
136
,
89
,
211
,
49
,
26
,
115
,
88
,
181
,
195
,
237
,
10
,
119
,
121
,
229
,
172
,
230
,
123
,
245
,
127
,
119
,
157
,
208
,
159
,
37
,
32
,
5
,
207
,
145
,
75
,
251
,
60
,
135
,
125
,
181
,
83
,
66
,
43
,
85
,
198
,
89
,
205
,
114
,
221
,
105
,
145
,
155
,
91
,
123
,
48
,
76
,
64
,
141
,
22
,
211
,
225
,
204
,
55
,
107
,
76
,
7
,
39
,
199
,
84
,
167
,
62
,
219
,
54
,
6
,
144
,
55
,
98
,
186
,
116
,
149
,
163
,
127
,
186
,
46
,
118
,
247
,
194
,
9
,
165
,
169
,
224
,
68
,
129
,
54
,
15
,
134
,
39
,
185
,
248
,
245
,
159
,
64
,
241
,
163
,
116
,
4
,
15
,
126
,
170
,
10
,
110
,
251
,
169
,
252
,
99
,
199
,
188
,
149
,
72
,
233
,
38
,
197
,
105
,
202
,
2
,
22
,
225
,
189
,
166
,
239
,
220
,
70
,
98
,
194
,
129
,
27
,
236
,
159
,
62
,
152
,
67
,
72
,
35
,
12
,
55
,
139
,
4
,
169
,
142
,
135
,
122
,
3
,
166
,
139
,
62
,
23
,
92
,
11
,
136
,
96
,
141
,
38
,
124
,
139
,
43
,
15
,
119
,
30
,
252
,
255
,
123
,
223
,
200
,
21
,
117
,
231
,
9
,
239
,
222
,
249
,
91
,
66
,
21
,
121
,
146
,
5
,
180
,
6
,
80
,
112
,
255
,
239
,
17
,
39
,
254
,
153
,
118
,
47
,
217
,
84
,
96
,
190
,
188
,
255
,
181
,
188
,
124
,
47
,
70
,
201
,
160
,
126
,
210
,
236
,
22
,
120
,
181
,
197
,
69
,
51
,
173
,
216
,
143
,
41
,
174
,
184
,
189
,
111
,
133
,
79
,
36
,
99
,
140
,
120
,
144
,
80
,
231
,
187
,
107
,
173
,
39
,
151
,
161
,
139
,
233
,
143
,
205
,
170
,
125
,
209
,
54
,
128
,
134
,
55
,
246
,
157
,
57
,
42
,
195
,
5
,
49
,
235
,
8
,
84
,
9
,
219
,
90
,
109
,
164
,
38
,
159
,
218
,
214
,
22
,
205
,
7
,
57
,
210
,
131
,
107
,
67
,
107
,
141
,
129
,
250
,
97
,
3
,
26
,
215
,
119
,
213
,
255
,
183
,
229
,
1
,
27
,
9
,
88
,
59
,
57
,
72
,
91
,
96
,
125
,
105
,
94
,
235
,
138
,
39
,
145
,
130
,
126
,
147
,
254
,
179
,
181
,
183
,
216
,
211
,
164
,
205
,
28
,
160
,
233
,
70
,
109
,
51
,
0
,
71
,
99
,
163
,
37
,
98
,
46
,
44
,
138
,
135
,
191
,
144
,
13
,
240
,
143
,
53
,
75
,
23
,
26
,
224
,
31
,
199
,
182
,
220
,
130
,
61
,
170
,
130
,
253
,
240
,
182
,
9
,
245
,
96
,
170
,
79
,
249
,
16
,
121
,
6
,
7
,
69
,
212
,
133
,
52
,
20
,
225
,
102
,
228
,
121
,
56
,
208
]
v = [217114,270581,291585,234325,240502,277604,286168,290450,179355,272487,249816,305636,276217,294166,237236,242008,289929,221788,268459,247407]
for i in range(20):
flag.append(BitVec('%d' % i, 8)) #char型
s = Solver()
s.add(flag[0]*key[0]+flag[1]*key[1]+flag[2]*key[2]+flag[3]*key[3]+flag[4]*key[4]+flag[5]*key[5]+flag[6]*key[6]+flag[7]*key[7]+flag[8]*key[8]+flag[9]*key[9]+flag[10]*key[10]+flag[11]*key[11]+flag[12]*key[12]+flag[13]*key[13]+flag[14]*key[14]+flag[15]*key[15]+flag[16]*key[16]+flag[17]*key[17]+flag[18]*key[18]+flag[19]*key[19]==v[0])
s.add(flag[0]*key[20]+flag[1]*key[21]+flag[2]*key[22]+flag[3]*key[23]+flag[4]*key[24]+flag[5]*key[25]+flag[6]*key[26]+flag[7]*key[27]+flag[8]*key[28]+flag[9]*key[29]+flag[10]*key[30]+flag[11]*key[31]+flag[12]*key[32]+flag[13]*key[33]+flag[14]*key[34]+flag[15]*key[35]+flag[16]*key[36]+flag[17]*key[37]+flag[18]*key[38]+flag[19]*key[39]==v[1])
s.add(flag[0]*key[40]+flag[1]*key[41]+flag[2]*key[42]+flag[3]*key[43]+flag[4]*key[44]+flag[5]*key[45]+flag[6]*key[46]+flag[7]*key[47]+flag[8]*key[48]+flag[9]*key[49]+flag[10]*key[50]+flag[11]*key[51]+flag[12]*key[52]+flag[13]*key[53]+flag[14]*key[54]+flag[15]*key[55]+flag[16]*key[56]+flag[17]*key[57]+flag[18]*key[58]+flag[19]*key[59]==v[2])
s.add(flag[0]*key[60]+flag[1]*key[61]+flag[2]*key[62]+flag[3]*key[63]+flag[4]*key[64]+flag[5]*key[65]+flag[6]*key[66]+flag[7]*key[67]+flag[8]*key[68]+flag[9]*key[69]+flag[10]*key[70]+flag[11]*key[71]+flag[12]*key[72]+flag[13]*key[73]+flag[14]*key[74]+flag[15]*key[75]+flag[16]*key[76]+flag[17]*key[77]+flag[18]*key[78]+flag[19]*key[79]==v[3])
s.add(flag[0]*key[80]+flag[1]*key[81]+flag[2]*key[82]+flag[3]*key[83]+flag[4]*key[84]+flag[5]*key[85]+flag[6]*key[86]+flag[7]*key[87]+flag[8]*key[88]+flag[9]*key[89]+flag[10]*key[90]+flag[11]*key[91]+flag[12]*key[92]+flag[13]*key[93]+flag[14]*key[94]+flag[15]*key[95]+flag[16]*key[96]+flag[17]*key[97]+flag[18]*key[98]+flag[19]*key[99]==v[4])
s.add(flag[0]*key[100]+flag[1]*key[101]+flag[2]*key[102]+flag[3]*key[103]+flag[4]*key[104]+flag[5]*key[105]+flag[6]*key[106]+flag[7]*key[107]+flag[8]*key[108]+flag[9]*key[109]+flag[10]*key[110]+flag[11]*key[111]+flag[12]*key[112]+flag[13]*key[113]+flag[14]*key[114]+flag[15]*key[115]+flag[16]*key[116]+flag[17]*key[117]+flag[18]*key[118]+flag[19]*key[119]==v[5])
s.add(flag[0]*key[120]+flag[1]*key[121]+flag[2]*key[122]+flag[3]*key[123]+flag[4]*key[124]+flag[5]*key[125]+flag[6]*key[126]+flag[7]*key[127]+flag[8]*key[128]+flag[9]*key[129]+flag[10]*key[130]+flag[11]*key[131]+flag[12]*key[132]+flag[13]*key[133]+flag[14]*key[134]+flag[15]*key[135]+flag[16]*key[136]+flag[17]*key[137]+flag[18]*key[138]+flag[19]*key[139]==v[6])
s.add(flag[0]*key[140]+flag[1]*key[141]+flag[2]*key[142]+flag[3]*key[143]+flag[4]*key[144]+flag[5]*key[145]+flag[6]*key[146]+flag[7]*key[147]+flag[8]*key[148]+flag[9]*key[149]+flag[10]*key[150]+flag[11]*key[151]+flag[12]*key[152]+flag[13]*key[153]+flag[14]*key[154]+flag[15]*key[155]+flag[16]*key[156]+flag[17]*key[157]+flag[18]*key[158]+flag[19]*key[159]==v[7])
s.add(flag[0]*key[160]+flag[1]*key[161]+flag[2]*key[162]+flag[3]*key[163]+flag[4]*key[164]+flag[5]*key[165]+flag[6]*key[166]+flag[7]*key[167]+flag[8]*key[168]+flag[9]*key[169]+flag[10]*key[170]+flag[11]*key[171]+flag[12]*key[172]+flag[13]*key[173]+flag[14]*key[174]+flag[15]*key[175]+flag[16]*key[176]+flag[17]*key[177]+flag[18]*key[178]+flag[19]*key[179]==v[8])
s.add(flag[0]*key[180]+flag[1]*key[181]+flag[2]*key[182]+flag[3]*key[183]+flag[4]*key[184]+flag[5]*key[185]+flag[6]*key[186]+flag[7]*key[187]+flag[8]*key[188]+flag[9]*key[189]+flag[10]*key[190]+flag[11]*key[191]+flag[12]*key[192]+flag[13]*key[193]+flag[14]*key[194]+flag[15]*key[195]+flag[16]*key[196]+flag[17]*key[197]+flag[18]*key[198]+flag[19]*key[199]==v[9])
s.add(flag[0]*key[200]+flag[1]*key[201]+flag[2]*key[202]+flag[3]*key[203]+flag[4]*key[204]+flag[5]*key[205]+flag[6]*key[206]+flag[7]*key[207]+flag[8]*key[208]+flag[9]*key[209]+flag[10]*key[210]+flag[11]*key[211]+flag[12]*key[212]+flag[13]*key[213]+flag[14]*key[214]+flag[15]*key[215]+flag[16]*key[216]+flag[17]*key[217]+flag[18]*key[218]+flag[19]*key[219]==v[10])
s.add(flag[0]*key[220]+flag[1]*key[221]+flag[2]*key[222]+flag[3]*key[223]+flag[4]*key[224]+flag[5]*key[225]+flag[6]*key[226]+flag[7]*key[227]+flag[8]*key[228]+flag[9]*key[229]+flag[10]*key[230]+flag[11]*key[231]+flag[12]*key[232]+flag[13]*key[233]+flag[14]*key[234]+flag[15]*key[235]+flag[16]*key[236]+flag[17]*key[237]+flag[18]*key[238]+flag[19]*key[239]==v[11])
s.add(flag[0]*key[240]+flag[1]*key[241]+flag[2]*key[242]+flag[3]*key[243]+flag[4]*key[244]+flag[5]*key[245]+flag[6]*key[246]+flag[7]*key[247]+flag[8]*key[248]+flag[9]*key[249]+flag[10]*key[250]+flag[11]*key[251]+flag[12]*key[252]+flag[13]*key[253]+flag[14]*key[254]+flag[15]*key[255]+flag[16]*key[256]+flag[17]*key[257]+flag[18]*key[258]+flag[19]*key[259]==v[12])
s.add(flag[0]*key[260]+flag[1]*key[261]+flag[2]*key[262]+flag[3]*key[263]+flag[4]*key[264]+flag[5]*key[265]+flag[6]*key[266]+flag[7]*key[267]+flag[8]*key[268]+flag[9]*key[269]+flag[10]*key[270]+flag[11]*key[271]+flag[12]*key[272]+flag[13]*key[273]+flag[14]*key[274]+flag[15]*key[275]+flag[16]*key[276]+flag[17]*key[277]+flag[18]*key[278]+flag[19]*key[279]==v[13])
s.add(flag[0]*key[280]+flag[1]*key[281]+flag[2]*key[282]+flag[3]*key[283]+flag[4]*key[284]+flag[5]*key[285]+flag[6]*key[286]+flag[7]*key[287]+flag[8]*key[288]+flag[9]*key[289]+flag[10]*key[290]+flag[11]*key[291]+flag[12]*key[292]+flag[13]*key[293]+flag[14]*key[294]+flag[15]*key[295]+flag[16]*key[296]+flag[17]*key[297]+flag[18]*key[298]+flag[19]*key[299]==v[14])
s.add(flag[0]*key[300]+flag[1]*key[301]+flag[2]*key[302]+flag[3]*key[303]+flag[4]*key[304]+flag[5]*key[305]+flag[6]*key[306]+flag[7]*key[307]+flag[8]*key[308]+flag[9]*key[309]+flag[10]*key[310]+flag[11]*key[311]+flag[12]*key[312]+flag[13]*key[313]+flag[14]*key[314]+flag[15]*key[315]+flag[16]*key[316]+flag[17]*key[317]+flag[18]*key[318]+flag[19]*key[319]==v[15])
s.add(flag[0]*key[320]+flag[1]*key[321]+flag[2]*key[322]+flag[3]*key[323]+flag[4]*key[324]+flag[5]*key[325]+flag[6]*key[326]+flag[7]*key[327]+flag[8]*key[328]+flag[9]*key[329]+flag[10]*key[330]+flag[11]*key[331]+flag[12]*key[332]+flag[13]*key[333]+flag[14]*key[334]+flag[15]*key[335]+flag[16]*key[336]+flag[17]*key[337]+flag[18]*key[338]+flag[19]*key[339]==v[16])
s.add(flag[0]*key[340]+flag[1]*key[341]+flag[2]*key[342]+flag[3]*key[343]+flag[4]*key[344]+flag[5]*key[345]+flag[6]*key[346]+flag[7]*key[347]+flag[8]*key[348]+flag[9]*key[349]+flag[10]*key[350]+flag[11]*key[351]+flag[12]*key[352]+flag[13]*key[353]+flag[14]*key[354]+flag[15]*key[355]+flag[16]*key[356]+flag[17]*key[357]+flag[18]*key[358]+flag[19]*key[359]==v[17])
s.add(flag[0]*key[360]+flag[1]*key[361]+flag[2]*key[362]+flag[3]*key[363]+flag[4]*key[364]+flag[5]*key[365]+flag[6]*key[366]+flag[7]*key[367]+flag[8]*key[368]+flag[9]*key[369]+flag[10]*key[370]+flag[11]*key[371]+flag[12]*key[372]+flag[13]*key[373]+flag[14]*key[374]+flag[15]*key[375]+flag[16]*key[376]+flag[17]*key[377]+flag[18]*key[378]+flag[19]*key[379]==v[18])
s.add(flag[0]*key[380]+flag[1]*key[381]+flag[2]*key[382]+flag[3]*key[383]+flag[4]*key[384]+flag[5]*key[385]+flag[6]*key[386]+flag[7]*key[387]+flag[8]*key[388]+flag[9]*key[389]+flag[10]*key[390]+flag[11]*key[391]+flag[12]*key[392]+flag[13]*key[393]+flag[14]*key[394]+flag[15]*key[395]+flag[16]*key[396]+flag[17]*key[397]+flag[18]*key[398]+flag[19]*key[399]==v[19])
if s.check() == sat:
print(s.model())
end={18 : 97,
2 : 118,
12 : 118,
13 : 109,
3 : 101,
10 : 110,
15 : 104,
17 : 104,
7 : 110,
16 : 97,
5 : 102,
14 : 95,
9 : 105,
6 : 117,
11 : 95,
1 : 97,
19 : 97,
8 : 95,
0 : 104,
4 : 95}
flag=''
for i in range(20):
flag+=chr(end[i])
print(flag)
16. 真龙之力
尝试安装失败,是因为xml被改了
可以用MT管理器或者AndroidKiller
修改AndroidManifest.xml
调用者不被允许测试的测试程序-CSDN博客文章浏览阅读2.3k次。报错:调用者不被允许测试的测试程序原因:未对测试功能加以限制(直接从Android Studio调试运行应该默认是开了调试模式)解决方法: 在application标签里面添加android:testOnly="false"属性即可..._调用者不被允许测试的测试程序https://blog.csdn.net/kicinio/article/details/117232493#:~:text=%E6%8A%A5%E9%94%99%EF%BC%9A%E8%B0%83%E7%94%A8%E8%80%85%E4%B8%8D%E8%A2%AB%E5%85%81%E8%AE%B8%E6%B5%8B%E8%AF%95%E7%9A%84%E6%B5%8B%E8%AF%95%E7%A8%8B%E5%BA%8F%E5%8E%9F%E5%9B%A0%EF%BC%9A%E6%9C%AA%E5%AF%B9%E6%B5%8B%E8%AF%95%E5%8A%9F%E8%83%BD%E5%8A%A0%E4%BB%A5%E9%99%90%E5%88%B6%EF%BC%88%E7%9B%B4%E6%8E%A5%E4%BB%8EAndroid%20Studio%E8%B0%83%E8%AF%95%E8%BF%90%E8%A1%8C%E5%BA%94%E8%AF%A5%E9%BB%98%E8%AE%A4%E6%98%AF%E5%BC%80%E4%BA%86%E8%B0%83%E8%AF%95%E6%A8%A1%E5%BC%8F%EF%BC%89%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95%EF%BC%9A,%3Capplication...%20android%3AtestOnly%3D%22false%22...%20%3C%2Fapplication%3E%E5%9C%A8application%E6%A0%87%E7%AD%BE%E9%87%8C%E9%9D%A2%E6%B7%BB%E5%8A%A0android%3AtestOnly%3D%22false%22%E5%B1%9E%E6%80%A7%E5%8D%B3%E5%8F%AF..._%E8%B0%83%E7%94%A8%E8%80%85%E4%B8%8D%E8%A2%AB%E5%85%81%E8%AE%B8%E6%B5%8B%E8%AF%95%E7%9A%84%E6%B5%8B%E8%AF%95%E7%A8%8B%E5%BA%8F
MT管理器
改一下即可
AndroidKiller方便一点
安装后需要key和ID
jadx看一下源码
第一个按钮做了加密
具体逻辑在lib的libdragon.so
里面
第二个按钮也进行了一些加密
进行了类似于RC4初始化的打乱,但没有异或操作,也就是说只是改变了顺序,可以用索引还原。
解压apk用IDA分析libdragon.so
应该是以v43作为xtea的key,把v42加密了,加密后的KEY(v42)应该在这
解一下KEY
#include<stdio.h>
#include<string.h>
int main()
{
unsigned int __cdecl xtea_decryption(unsigned int* a1, const unsigned int* a2);
//unsigned int teakey[4] = { 0x76543210 , 0xFEDCBA98 , 0x89ABCDEF, 0x1234567 };
unsigned int teakey[4] = { 0x1234567, 0x89ABCDEF , 0xFEDCBA98 , 0x76543210 };
unsigned int enc[4] = { 0x1b253544,0xfcc56bb0 };
xtea_decryption(enc, teakey);
printf("%x\n", enc);
printf("%s", enc);
return 0;
}
unsigned int __cdecl xtea_decryption(unsigned int* a1, const unsigned int* a2)
{
unsigned int result; // eax
int i; // [esp+0h] [ebp-18h]
unsigned int sum; // [esp+8h] [ebp-10h]
unsigned int v5; // [esp+Ch] [ebp-Ch]
unsigned int v6; // [esp+10h] [ebp-8h]
v6 = *a1;
v5 = a1[1];
sum = 0x9E3779B9 *32;
for (i = 0; i < 32; ++i)
{
v5 -= (a2[(sum >> 11) & 3] + sum) ^ (v6 + ((v6 >> 4) ^ (32 * v6)));
sum -= 0x9E3779B9;
v6 -= (a2[sum & 3] + sum) ^ (v5 + ((v5 >> 4) ^ (32 * v5)));
}
*a1 = v6;
result = v5;
a1[1] = v5;
return result;
}
//e4aff8a8
//4202SDYY
端序问题跑出来是反的 YYDS2024
打乱的密文 i{biecfuialflnlv_eegieo}Ntt
长度为27,我们输入一串长度27的字符串来查索引
输出vfaxnwtidyzulemjrqbckhs0gop
#dragonindex exp
table = "abcdefghijklmnopqrstuvwxyz0"
back = "vfaxnwtidyzulemjrqbckhs0gop"
enc = "i{biecfuialflnlv_eegieo}Ntt"
for i in table:
print(enc[back.index(i)],end="")
#begin{Neuvillette_official}