四处游走寻找关键代码
int __fastcall sub_400430(int a1, unsigned int a2, int a3)
{
unsigned int v3; // $v0
int v4; // $v0
int v5; // $v0
int v6; // $v0
unsigned int i; // [sp+8h] [+8h]
unsigned int v9; // [sp+8h] [+8h]
int v10; // [sp+Ch] [+Ch]
v10 = 0;
for ( i = 0; i < a2; ++i )
{
v3 = i % 3;
if ( i % 3 == 1 )
{
v5 = v10++;
*(_BYTE *)(a3 + v5) = byte_410200[16 * (*(_BYTE *)(a1 + i - 1) & 3) + ((*(unsigned __int8 *)(a1 + i) >> 4) & 0xF)];
}
else if ( v3 == 2 )
{
*(_BYTE *)(a3 + v10) = byte_410200[4 * (*(_BYTE *)(a1 + i - 1) & 0xF) + ((*(unsigned __int8 *)(a1 + i) >> 6) & 3)];
v6 = v10 + 1;
v10 += 2;
*(_BYTE *)(a3 + v6) = byte_410200[*(_BYTE *)(a1 + i) & 0x3F];
}
else if ( !v3 )
{
v4 = v10++;
*(_BYTE *)(a3 + v4) = byte_410200[(*(unsigned __int8 *)(a1 + i) >> 2) & 0x3F];
}
}
v9 = i - 1;
if ( v9 % 3 )
{
if ( v9 % 3 == 1 )
{
*(_BYTE *)(a3 + v10) = byte_410200[4 * (*(_BYTE *)(a1 + v9) & 0xF)];
*(_BYTE *)(a3 + v10 + 1) = 61;
}
}
else
{
*(_BYTE *)(a3 + v10) = byte_410200[16 * (*(_BYTE *)(a1 + v9) & 3)];
*(_BYTE *)(a3 + v10 + 1) = 61;
*(_BYTE *)(a3 + v10 + 2) = 61;
}
return 0;
}
变表base64, 拿板子秒了
import base64
encodestr = '_r-+_Cl5;vgq_pdme7#7eC0='
changebase64 = '@,.1fgvw#`/2ehux$~\"3dity%_;4cjsz^+{5bkrA&=}6alqB*-[70mpC()]89noD'
# print(len(changebase64))
originbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
trans_encodestr = encodestr.translate(str.maketrans(changebase64,originbase64))
flag = base64.b64decode(trans_encodestr)
print(flag)
打开发现是一大堆数据, 打开方式不对, 尝试ELF64格式再打开
得到反编译伪码
int __cdecl main(int argc, const char **argv, const char **envp)
{
signal(14, sig);
alarm(1u);
delay(6000000LL);
can_continue = 1337;
return 0;
}
unsigned __int64 generate()
{
char s[131]; // [rsp+0h] [rbp-B0h] BYREF
char v2[14]; // [rsp+83h] [rbp-2Dh] BYREF
char v3[31]; // [rsp+91h] [rbp-1Fh] BYREF
*(_QWORD *)&v3[23] = __readfsqword(0x28u);
if ( can_continue == 1337 )
{
s[64] = 35;
s[65] = 60;
s[66] = 73;
s[67] = 100;
s[68] = 85;
s[69] = 46;
s[70] = 119;
s[71] = 32;
s[72] = 45;
s[73] = 115;
s[74] = 63;
s[75] = 125;
s[76] = 44;
s[77] = 56;
s[78] = 108;
s[79] = 83;
s[80] = 84;
s[81] = 42;
s[82] = 90;
s[83] = 106;
s[84] = 87;
s[85] = 58;
s[86] = 102;
s[87] = 94;
s[88] = 77;
s[89] = 54;
s[90] = 101;
s[91] = 110;
s[92] = 112;
s[93] = 104;
s[94] = 99;
s[95] = 47;
s[96] = 79;
s[97] = 118;
s[98] = 37;
s[99] = 75;
s[100] = 11;
s[101] = 52;
s[102] = 76;
s[103] = 82;
s[104] = 103;
s[105] = 96;
s[106] = 95;
s[107] = 69;
s[108] = 123;
s[109] = 114;
s[110] = 59;
s[111] = 126;
s[112] = 74;
s[113] = 10;
s[114] = 107;
s[115] = 113;
s[116] = 67;
s[117] = 36;
s[118] = 92;
s[119] = 40;
s[120] = 34;
s[121] = 64;
s[122] = 50;
s[123] = 68;
s[124] = 98;
s[125] = 80;
s[126] = 13;
s[127] = 38;
s[128] = 49;
s[129] = 55;
s[130] = 12;
qmemcpy(v2, "]y>=xaVYA[BF3", 13);
v2[13] = (unsigned __int8)&unk_400BB4;
strcpy(v3, "!tQHu0Xi5|\t9N+zmG)o");
strcpy(s, "watevr{3ncrytion_is_overrated_youtube.com/watch?v=OPf0YbXqDm0}");
puts(s);
}
return __readfsqword(0x28u) ^ *(_QWORD *)&v3[23];
}
主要逻辑就是经过delay(6000000LL);
一大段时间, 最后generate
函数直接给flag
main函数直接就是控制流平坦化
用修复后的脚本去混淆, 参考 https://ylcao.top/2022/01/16/%E7%AC%A6%E5%8F%B7%E6%89%A7%E8%A1%8C%E5%8E%BB%E6%8E%A7%E5%88%B6%E6%B5%81%E5%B9%B3%E5%9D%A6%E5%8C%96/
>python deflat.py attachment 0x400620
*******************relevant blocks************************
prologue: 0x400620
main_dispatcher: 0x40063f
pre_dispatcher: 0x4020cc
retn: 0x401f54
relevant_blocks: ['0x4015d4', '0x40201b', '0x401e00', '0x401f2d', '0x401481', '0x401c69', '0x401efa', '0x401830', '0x401642', '0x401f97', '0x40180b', '0x401eb9', '0x401748', '0x4013ef', '0x4012f6', '0x401fb5', '0x402033', '0x40197d', '0x40136c', '0x401a73', '0x401d9a', '0x40204d', '0x402096', '0x4015c5', '0x401567', '0x401909', '0x401f09', '0x401c2b', '0x4014ae', '0x40199b', '0x401435', '0x401fa6', '0x401861', '0x401b34', '0x401b5d', '0x401f3c', '0x401521', '0x401caf', '0x4013cf', '0x4014f7', '0x401f60', '0x401960', '0x4016a0', '0x4018a7', '0x4011de', '0x401739', '0x4020c2', '0x401506', '0x4019e1', '0x4014d2', '0x401d2d', '0x401849', '0x4017fc', '0x4017ab', '0x401b25', '0x402072', '0x401d03', '0x401ad3', '0x4015fc', '0x401926', '0x401b75', '0x401326', '0x4016e6', '0x401e0f', '0x40200c', '0x401e73', '0x4015b6', '0x401a3d', '0x401ff4', '0x401305', '0x401fe5', '0x401d54', '0x401198', '0x4013b2', '0x401c1c', '0x40124f', '0x401c46', '0x401490', '0x401a8d', '0x401b4e', '0x401d45', '0x401765', '0x401bbb', '0x4018fa', '0x401691', '0x401c0d', '0x4015ed', '0x401a4c', '0x401d12', '0x40125e', '0x401fcd', '0x4012a4', '0x401940', '0x4014e8', '0x401121', '0x401e2d', '0x401ed6', '0x4020b3', '0x401117']
*******************symbolic execution*********************
-------------------dse 0x4015d4---------------------
WARNING | 2023-09-25 22:23:16,740 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing register with an unspecified value. This could indicate unwanted behavior.
...
...
...
0x4012a4: ['0x4012f6', '0x401f97']
0x401940: ['0x401960']
0x4014e8: ['0x4015d4']
0x401121: ['0x401198']
0x401e2d: ['0x401e73', '0x4020c2']
0x401ed6: ['0x401efa']
0x4020b3: ['0x401d9a']
0x401117: ['0x4015d4']
0x400620: ['0x401121']
0x401f54: []
************************patch*****************************
Successful! The recovered file: attachment_recovered
打开之后, 发现还有不少花指令
IDApython去花, IDA API版本是7.4+
参考API更新文档进行脚本编写 https://hex-rays.com/products/ida/support/ida74_idapython_no_bc695_porting_guide.shtml
from idc import *
st = 0x0000000000401117
end = 0x0000000000402144
def patch_nop(start,end):
for i in range(start,end):
patch_byte(i, 0x90)
def next_instr(addr):
return addr + get_item_size(addr)
addr = st
while(addr<end):
next = next_instr(addr)
if "ds:dword_603054" in GetDisasm(addr):
while(True):
addr = next
next = next_instr(addr)
if "jnz" in GetDisasm(addr):
dest = get_operand_value(addr, 0)
patch_byte(addr, 0xe9)
patch_byte(addr+5, 0x90)
offset = dest - (addr + 5)
patch_dword(addr + 1, offset)
print("patch bcf: 0x%x"%addr)
addr = next
break
else:
addr = next
print('---- patching done ----')
最后还原出主要代码
__int64 __fastcall main(int a1, char **a2, char **a3)
{
__int64 v3; // rax
unsigned __int64 v4; // rcx
__int64 v6; // [rsp+1E0h] [rbp-110h]
int v7; // [rsp+1E8h] [rbp-108h]
int v8; // [rsp+1ECh] [rbp-104h]
char s1[48]; // [rsp+1F0h] [rbp-100h] BYREF
char s[60]; // [rsp+220h] [rbp-D0h] BYREF
unsigned int v11; // [rsp+25Ch] [rbp-94h]
char *v12; // [rsp+260h] [rbp-90h]
int v13; // [rsp+288h] [rbp-68h]
bool v14; // [rsp+28Fh] [rbp-61h]
char *v15; // [rsp+290h] [rbp-60h]
int v16; // [rsp+298h] [rbp-58h]
bool v17; // [rsp+29Fh] [rbp-51h]
__int64 v18; // [rsp+2A0h] [rbp-50h]
bool v19; // [rsp+2AFh] [rbp-41h]
__int64 v20; // [rsp+2B0h] [rbp-40h]
__int64 v21; // [rsp+2B8h] [rbp-38h]
__int64 v22; // [rsp+2C0h] [rbp-30h]
__int64 v23; // [rsp+2C8h] [rbp-28h]
int v24; // [rsp+2D0h] [rbp-20h]
int v25; // [rsp+2D4h] [rbp-1Ch]
char *v26; // [rsp+2D8h] [rbp-18h]
int v27; // [rsp+2E0h] [rbp-10h]
int v28; // [rsp+2E4h] [rbp-Ch]
bool v29; // [rsp+2EBh] [rbp-5h]
v11 = 0;
memset(s, 0, 0x30uLL);
memset(s1, 0, sizeof(s1));
printf("Input:");
v12 = s;
v3 = 3824974737LL;
v4 = 3788079310LL;
LABEL_7:
v6 = v4 ^ v3;
LABEL_9:
v24 = v8++;
while ( 1 )
{
v16 = v8;
v17 = v8 < 64;
if ( v8 < 64 )
{
v18 = v6;
v19 = v6 < 0;
if ( v6 < 0 )
{
v20 = 2 * v6;
v21 = 2 * v6;
v3 = 2 * v6;
v4 = 0xB0004B7679FA26B3LL;
goto LABEL_7;
}
v22 = v6;
v23 = 2 * v6;
v6 *= 2LL;
goto LABEL_9;
}
v25 = 8 * v7;
v26 = &s1[8 * v7];
*(_QWORD *)v26 = v6;
v27 = ++v7;
v13 = v7;
v14 = v7 < 6;
if ( v7 >= 6 )
break;
v15 = s;
v6 = *(_QWORD *)&s[8 * v7];
v8 = 0;
}
v28 = memcmp(s1, &unk_402170, 0x30uLL);
v29 = v28 != 0;
if ( v28 )
puts("Wrong!");
else
puts("Correct!");
return v11;
}
CRC32编码, 输入 48 字节,平分 6 组,将每组 8 字节转化为 long 类型的值,对每组进行加密,先判断正负,然后将值乘 2,随后根据正负异或 0xB0004B7679FA26B3,循环 64 次,最后进行比较
checklist = [
'96','62','53','43','6D',
'F2','8F','BC','16','EE',
'30','05','78','00','01',
'52','EC','08','5F','93',
'EA','B5','C0','4D','50',
'F4','53','D8','AF','90',
'2B','34','81','36','2C',
'AA','BC','0E','25','8B',
'E4','8A','C6','A2','81',
'9F','75','55'
]
idx = 0
flag = ''
for i in range(6):
v4 = '0x' + checklist[idx + 7] + checklist[idx + 6] + \
checklist[idx + 5] + checklist[idx + 4] + checklist[idx + 3] + \
checklist[idx + 2] + checklist[idx + 1] + checklist[idx]
s = int(v4, 16)
for j in range(64):
if s & 1 == 1:
s = ((s ^ int('0xB0004B7679FA26B3', 16)) >> 1) | 0x8000000000000000
else:
s = s >> 1
idx = idx + 8
j = 0
while j < 8:
flag += chr(s & 0xFF)
s >>= 8
j += 1
print(flag)
int __cdecl sub_401340(int a1)
{
char i; // [esp+1Fh] [ebp-9h]
printf("Please input:");
scanf("%s", a1);
for ( i = 0; i <= 15; ++i )
{
if ( (*(_BYTE *)(i + a1) ^ *((_BYTE *)y1 + i)) != y2[i] )
exit(0);
}
return 0;
}
逆
#include
unsigned char y2[] = {
113, 4, 97, 88, 39, 30, 75, 34, 94, 100,
3, 38, 94, 23, 60, 122, 255, 255, 255, 255,
0, 64, 0, 0
};
unsigned char y1[] = {
35, 97, 62, 105, 84, 65, 24, 77, 110, 59,
101, 83, 48, 121, 69, 91
};
int main() {
char flag[17] = {0};
for (int i = 0; i <= 15; ++i) {
flag[i] = y1[i] ^ y2[i];
}
printf("%s\n", flag);
}
4 0 LOAD_CONST 0 (3)
3 LOAD_CONST 1 (37)
6 LOAD_CONST 2 (72)
9 LOAD_CONST 3 (9)
12 LOAD_CONST 4 (6)
15 LOAD_CONST 5 (132)
18 BUILD_LIST 6
21 STORE_NAME 0 (en)
5 24 LOAD_CONST 6 (101)
27 LOAD_CONST 7 (96)
30 LOAD_CONST 8 (23)
33 LOAD_CONST 9 (68)
36 LOAD_CONST 10 (112)
39 LOAD_CONST 11 (42)
42 LOAD_CONST 12 (107)
45 LOAD_CONST 13 (62)
48 LOAD_CONST 7 (96)
51 LOAD_CONST 14 (53)
54 LOAD_CONST 15 (176)
57 LOAD_CONST 16 (179)
60 LOAD_CONST 17 (98)
63 LOAD_CONST 14 (53)
66 LOAD_CONST 18 (67)
69 LOAD_CONST 19 (29)
72 LOAD_CONST 20 (41)
75 LOAD_CONST 21 (120)
78 LOAD_CONST 22 (60)
81 LOAD_CONST 23 (106)
84 LOAD_CONST 24 (51)
87 LOAD_CONST 6 (101)
90 LOAD_CONST 25 (178)
93 LOAD_CONST 26 (189)
96 LOAD_CONST 6 (101)
99 LOAD_CONST 27 (48)
102 BUILD_LIST 26
105 STORE_NAME 1 (output)
7 108 LOAD_CONST 28 ('welcome to GWHT2020')
111 PRINT_ITEM
112 PRINT_NEWLINE
9 113 LOAD_NAME 2 (raw_input)
116 LOAD_CONST 29 ('please input your flag:')
119 CALL_FUNCTION 1
122 STORE_NAME 3 (flag)
10 125 LOAD_NAME 3 (flag)
128 STORE_NAME 4 (str)
12 131 LOAD_NAME 5 (len)
134 LOAD_NAME 4 (str)
137 CALL_FUNCTION 1
140 STORE_NAME 6 (a)
13 143 LOAD_NAME 6 (a)
146 LOAD_CONST 30 (38)
149 COMPARE_OP 0 (<)
152 POP_JUMP_IF_FALSE 173
14 155 LOAD_CONST 31 ('lenth wrong!')
158 PRINT_ITEM
159 PRINT_NEWLINE
15 160 LOAD_NAME 7 (exit)
163 LOAD_CONST 32 (0)
166 CALL_FUNCTION 1
169 POP_TOP
170 JUMP_FORWARD 0 (to 173)
17 >> 173 LOAD_NAME 8 (ord)
176 LOAD_NAME 4 (str)
179 LOAD_CONST 32 (0)
182 BINARY_SUBSCR
183 CALL_FUNCTION 1
186 LOAD_CONST 33 (2020)
189 BINARY_MULTIPLY
190 LOAD_NAME 8 (ord)
193 LOAD_NAME 4 (str)
196 LOAD_CONST 34 (1)
199 BINARY_SUBSCR
200 CALL_FUNCTION 1
203 BINARY_ADD
204 LOAD_CONST 33 (2020)
207 BINARY_MULTIPLY
208 LOAD_NAME 8 (ord)
211 LOAD_NAME 4 (str)
214 LOAD_CONST 35 (2)
217 BINARY_SUBSCR
218 CALL_FUNCTION 1
221 BINARY_ADD
222 LOAD_CONST 33 (2020)
225 BINARY_MULTIPLY
226 LOAD_NAME 8 (ord)
229 LOAD_NAME 4 (str)
232 LOAD_CONST 0 (3)
235 BINARY_SUBSCR
236 CALL_FUNCTION 1
239 BINARY_ADD
240 LOAD_CONST 33 (2020)
243 BINARY_MULTIPLY
244 LOAD_NAME 8 (ord)
247 LOAD_NAME 4 (str)
250 LOAD_CONST 36 (4)
253 BINARY_SUBSCR
254 CALL_FUNCTION 1
257 BINARY_ADD
258 LOAD_CONST 37 (1182843538814603)
261 COMPARE_OP 2 (==)
264 POP_JUMP_IF_FALSE 275
18 267 LOAD_CONST 38 ('good!continue\xe2\x80\xa6\xe2\x80\xa6')
270 PRINT_ITEM
271 PRINT_NEWLINE
272 JUMP_FORWARD 15 (to 290)
20 >> 275 LOAD_CONST 39 ('bye~')
278 PRINT_ITEM
279 PRINT_NEWLINE
21 280 LOAD_NAME 7 (exit)
283 LOAD_CONST 32 (0)
286 CALL_FUNCTION 1
289 POP_TOP
23 >> 290 BUILD_LIST 0
293 STORE_NAME 9 (x)
24 296 LOAD_CONST 40 (5)
299 STORE_NAME 10 (k)
25 302 SETUP_LOOP 128 (to 433)
305 LOAD_NAME 11 (range)
308 LOAD_CONST 41 (13)
311 CALL_FUNCTION 1
314 GET_ITER
>> 315 FOR_ITER 114 (to 432)
318 STORE_NAME 12 (i)
26 321 LOAD_NAME 8 (ord)
324 LOAD_NAME 4 (str)
327 LOAD_NAME 10 (k)
330 BINARY_SUBSCR
331 CALL_FUNCTION 1
334 STORE_NAME 13 (b)
27 337 LOAD_NAME 8 (ord)
340 LOAD_NAME 4 (str)
343 LOAD_NAME 10 (k)
346 LOAD_CONST 34 (1)
349 BINARY_ADD
350 BINARY_SUBSCR
351 CALL_FUNCTION 1
354 STORE_NAME 14 (c)
28 357 LOAD_NAME 14 (c)
360 LOAD_NAME 0 (en)
363 LOAD_NAME 12 (i)
366 LOAD_CONST 4 (6)
369 BINARY_MODULO
370 BINARY_SUBSCR
371 BINARY_XOR
372 STORE_NAME 15 (a11)
29 375 LOAD_NAME 13 (b)
378 LOAD_NAME 0 (en)
381 LOAD_NAME 12 (i)
384 LOAD_CONST 4 (6)
387 BINARY_MODULO
388 BINARY_SUBSCR
389 BINARY_XOR
390 STORE_NAME 16 (a22)
30 393 LOAD_NAME 9 (x)
396 LOAD_ATTR 17 (append)
399 LOAD_NAME 15 (a11)
402 CALL_FUNCTION 1
405 POP_TOP
31 406 LOAD_NAME 9 (x)
409 LOAD_ATTR 17 (append)
412 LOAD_NAME 16 (a22)
415 CALL_FUNCTION 1
418 POP_TOP
32 419 LOAD_NAME 10 (k)
422 LOAD_CONST 35 (2)
425 INPLACE_ADD
426 STORE_NAME 10 (k)
429 JUMP_ABSOLUTE 315
>> 432 POP_BLOCK
33 >> 433 LOAD_NAME 9 (x)
436 LOAD_NAME 1 (output)
439 COMPARE_OP 2 (==)
442 POP_JUMP_IF_FALSE 453
34 445 LOAD_CONST 38 ('good!continue\xe2\x80\xa6\xe2\x80\xa6')
448 PRINT_ITEM
449 PRINT_NEWLINE
450 JUMP_FORWARD 15 (to 468)
36 >> 453 LOAD_CONST 42 ('oh,you are wrong!')
456 PRINT_ITEM
457 PRINT_NEWLINE
37 458 LOAD_NAME 7 (exit)
461 LOAD_CONST 32 (0)
464 CALL_FUNCTION 1
467 POP_TOP
39 >> 468 LOAD_NAME 5 (len)
471 LOAD_NAME 4 (str)
474 CALL_FUNCTION 1
477 STORE_NAME 18 (l)
40 480 LOAD_NAME 8 (ord)
483 LOAD_NAME 4 (str)
486 LOAD_NAME 18 (l)
489 LOAD_CONST 43 (7)
492 BINARY_SUBTRACT
493 BINARY_SUBSCR
494 CALL_FUNCTION 1
497 STORE_NAME 19 (a1)
41 500 LOAD_NAME 8 (ord)
503 LOAD_NAME 4 (str)
506 LOAD_NAME 18 (l)
509 LOAD_CONST 4 (6)
512 BINARY_SUBTRACT
513 BINARY_SUBSCR
514 CALL_FUNCTION 1
517 STORE_NAME 20 (a2)
42 520 LOAD_NAME 8 (ord)
523 LOAD_NAME 4 (str)
526 LOAD_NAME 18 (l)
529 LOAD_CONST 40 (5)
532 BINARY_SUBTRACT
533 BINARY_SUBSCR
534 CALL_FUNCTION 1
537 STORE_NAME 21 (a3)
43 540 LOAD_NAME 8 (ord)
543 LOAD_NAME 4 (str)
546 LOAD_NAME 18 (l)
549 LOAD_CONST 36 (4)
552 BINARY_SUBTRACT
553 BINARY_SUBSCR
554 CALL_FUNCTION 1
557 STORE_NAME 22 (a4)
44 560 LOAD_NAME 8 (ord)
563 LOAD_NAME 4 (str)
566 LOAD_NAME 18 (l)
569 LOAD_CONST 0 (3)
572 BINARY_SUBTRACT
573 BINARY_SUBSCR
574 CALL_FUNCTION 1
577 STORE_NAME 23 (a5)
45 580 LOAD_NAME 8 (ord)
583 LOAD_NAME 4 (str)
586 LOAD_NAME 18 (l)
589 LOAD_CONST 35 (2)
592 BINARY_SUBTRACT
593 BINARY_SUBSCR
594 CALL_FUNCTION 1
597 STORE_NAME 24 (a6)
46 600 LOAD_NAME 19 (a1)
603 LOAD_CONST 0 (3)
606 BINARY_MULTIPLY
607 LOAD_NAME 20 (a2)
610 LOAD_CONST 35 (2)
613 BINARY_MULTIPLY
614 BINARY_ADD
615 LOAD_NAME 21 (a3)
618 LOAD_CONST 40 (5)
621 BINARY_MULTIPLY
622 BINARY_ADD
623 LOAD_CONST 44 (1003)
626 COMPARE_OP 2 (==)
629 POP_JUMP_IF_FALSE 807
47 632 LOAD_NAME 19 (a1)
635 LOAD_CONST 36 (4)
638 BINARY_MULTIPLY
639 LOAD_NAME 20 (a2)
642 LOAD_CONST 43 (7)
645 BINARY_MULTIPLY
646 BINARY_ADD
647 LOAD_NAME 21 (a3)
650 LOAD_CONST 3 (9)
653 BINARY_MULTIPLY
654 BINARY_ADD
655 LOAD_CONST 45 (2013)
658 COMPARE_OP 2 (==)
661 POP_JUMP_IF_FALSE 807
48 664 LOAD_NAME 19 (a1)
667 LOAD_NAME 20 (a2)
670 LOAD_CONST 46 (8)
673 BINARY_MULTIPLY
674 BINARY_ADD
675 LOAD_NAME 21 (a3)
678 LOAD_CONST 35 (2)
681 BINARY_MULTIPLY
682 BINARY_ADD
683 LOAD_CONST 47 (1109)
686 COMPARE_OP 2 (==)
689 POP_JUMP_IF_FALSE 804
49 692 LOAD_NAME 22 (a4)
695 LOAD_CONST 0 (3)
698 BINARY_MULTIPLY
699 LOAD_NAME 23 (a5)
702 LOAD_CONST 35 (2)
705 BINARY_MULTIPLY
706 BINARY_ADD
707 LOAD_NAME 24 (a6)
710 LOAD_CONST 40 (5)
713 BINARY_MULTIPLY
714 BINARY_ADD
715 LOAD_CONST 48 (671)
718 COMPARE_OP 2 (==)
721 POP_JUMP_IF_FALSE 801
50 724 LOAD_NAME 22 (a4)
727 LOAD_CONST 36 (4)
730 BINARY_MULTIPLY
731 LOAD_NAME 23 (a5)
734 LOAD_CONST 43 (7)
737 BINARY_MULTIPLY
738 BINARY_ADD
739 LOAD_NAME 24 (a6)
742 LOAD_CONST 3 (9)
745 BINARY_MULTIPLY
746 BINARY_ADD
747 LOAD_CONST 49 (1252)
750 COMPARE_OP 2 (==)
753 POP_JUMP_IF_FALSE 798
51 756 LOAD_NAME 22 (a4)
759 LOAD_NAME 23 (a5)
762 LOAD_CONST 46 (8)
765 BINARY_MULTIPLY
766 BINARY_ADD
767 LOAD_NAME 24 (a6)
770 LOAD_CONST 35 (2)
773 BINARY_MULTIPLY
774 BINARY_ADD
775 LOAD_CONST 50 (644)
778 COMPARE_OP 2 (==)
781 POP_JUMP_IF_FALSE 795
52 784 LOAD_CONST 51 ('congraduation!you get the right flag!')
787 PRINT_ITEM
788 PRINT_NEWLINE
789 JUMP_ABSOLUTE 795
792 JUMP_ABSOLUTE 798
>> 795 JUMP_ABSOLUTE 801
>> 798 JUMP_ABSOLUTE 804
>> 801 JUMP_ABSOLUTE 807
>> 804 JUMP_FORWARD 0 (to 807)
>> 807 LOAD_CONST 52 (None)
810 RETURN_VALUE
bytecode 逆向, 直接读字节码, 人工还原到python源码, 没有现成的工具(有机会可以写一个), 唯硬逆一途
en = [3, 37, 72, 9, 6, 132]
output = [101, 96, 23, 68, 112, 42, 107, 62, 96, 53, 176, 179,
98, 53, 67, 29, 41, 120, 60, 106, 51, 101, 178, 189, 101, 48]
print('welcome to GWHT2020')
flag = input('please input your flag:')
str = flag
a = len(str)
if a < 38:
print('lenth wrong!')
exit(0)
if ord(str[0]) + 2020 * ord(str[1]) + 2020 * ord(str[3]) + 2020 * ord(str[4]) == 1182843538814603:
print('good!continue\xe2\x80\xa6\xe2\x80\xa6')
else:
print('bye~')
exit(0)
x = []
k = 5
for i in range(13):
b = ord(str[k])
c = ord(str[k + 1])
a11 = c ^ en[i % 6]
a22 = b ^ en[i % 6]
x.append(a11)
x.append(a22)
k += 2
if x == output:
print('good!continue\xe2\x80\xa6\xe2\x80\xa6')
else:
print('oh,you are wrong!')
exit(0)
l = len(str)
a1 = ord(str[l - 7])
a2 = ord(str[l - 6])
a3 = ord(str[l - 5])
a4 = ord(str[l - 4])
a5 = ord(str[l - 3])
a6 = ord(str[l - 2])
if a1 * 3 + a2 * 2 + a3 * 5 == 1003:
if a1 * 4 + a2 * 7 + a3 * 9 == 2013:
if a1 + a2 * 8 + a3 * 2 == 1109:
if a1 * 3 + a5 * 2 + a6 * 5 == 671:
if a4 * 4 + a5 * 7 + a6 * 9 == 1252:
if a4 + a5 * 8 + a6 * 2 == 644:
print('congraduation!you get the right flag!')
z3解方程
import z3
s = z3.Solver()
en = [3, 37, 72, 9, 6, 132]
output = [101, 96, 23, 68, 112, 42, 107, 62, 96, 53, 176, 179,
98, 53, 67, 29, 41, 120, 60, 106, 51, 101, 178, 189, 101, 48]
flag = [z3.Int(f'a{x}') for x in range(45)]
t1 = flag[0] * 2020 + flag[1]
t2 = t1 * 2020 + flag[2]
t3 = t2 * 2020 + flag[3]
t4 = t3 * 2020 + flag[4]
s.add(t4 == 1182843538814603)
for i in range(5):
s.add(flag[i] > 0)
s.add(flag[i] < 128)
k = 5
for i in range(13):
s.add(flag[k+1] == output[2*i] ^ en[i % 6])
s.add(flag[k] == output[2*i+1] ^ en[i % 6])
k += 2
l = len(flag)
a1 = flag[l - 7]
a2 = flag[l - 6]
a3 = flag[l - 5]
a4 = flag[l - 4]
a5 = flag[l - 3]
a6 = flag[l - 2]
s.add((a1 * 3 + a2 * 2 + a3 * 5) == 1003)
s.add((a1 * 4 + a2 * 7 + a3 * 9) == 2013)
s.add((a1 + a2 * 8 + a3 * 2) == 1109)
s.add((a4 * 3 + a5 * 2 + a6 * 5) == 671)
s.add((a4 * 4 + a5 * 7 + a6 * 9) == 1252)
s.add((a4 + a5 * 8 + a6 * 2) == 644)
for i in flag:
s.add(i > 0)
s.add(i < 128)
c = s.check()
if c == z3.unsat:
print('fail')
else:
model = s.model()
result = {}
for x in model:
key = int(str(x).replace('a', ''))
result[key] = model[x]
flag_result = [result[x].as_long() for x in sorted(result)]
flag_result = [chr(x) for x in flag_result]
print(''.join(flag_result))
# GWHT{cfa2b87b3f746a8f0ac5c5963faeff73