BUUCTF reverse wp 65 - 70
[SWPU2019]ReverseMe
反编译的伪码看不明白, 直接动调
这里显示"Please input your flag", 然后接受输入, 再和32进行比较, 应该是flag长度要求32位, 符合要求则跳转到loc_E528EE
分支继续执行
动调之后伪码可以读了
int __cdecl main(int argc, const char **argv, const char **envp)
{int v3; // ecxint *v4; // eaxint v5; // ecxint *v6; // eaxchar *v7; // esiint i; // ediunsigned int xor_len; // kr00_4void **v10; // ecx__int128 *v11; // ecxchar *checkval; // ecx__int128 *buf; // edxunsigned int v14; // ediint checkarr; // eaxint v16; // eaxbool v17; // cfunsigned __int8 v18; // alunsigned __int8 v19; // alunsigned __int8 v20; // alconst char *output; // edxint *v22; // eaxchar *v23; // eaxint v25; // [esp-14h] [ebp-D8h]int v26; // [esp-10h] [ebp-D4h]void *input[4]; // [esp+24h] [ebp-A0h] BYREFint length; // [esp+34h] [ebp-90h]unsigned int v29; // [esp+38h] [ebp-8Ch]__int128 processed[2]; // [esp+3Ch] [ebp-88h] BYREFint v31; // [esp+5Ch] [ebp-68h]__int128 v32; // [esp+60h] [ebp-64h] BYREF__int128 v33; // [esp+70h] [ebp-54h]int v34; // [esp+80h] [ebp-44h]char xorval[16]; // [esp+84h] [ebp-40h] BYREFchar v36[32]; // [esp+94h] [ebp-30h] BYREFint v37; // [esp+C0h] [ebp-4h]length = 0;v29 = 15;LOBYTE(input[0]) = 0;v37 = 1;v4 = sub_E52DA0(v3, "Please input your flag: ");sub_E53050(v4);sub_E537B0((int)&dword_E80068, input);strcpy(xorval, "SWPU_2019_CTF");if ( length == 32 ){*(_DWORD *)&v36[16] = -1173078761;*(_DWORD *)&v36[20] = 494076752;*(_DWORD *)&v36[24] = -1811652486;*(_DWORD *)&v36[28] = 688582768;i = 0;v32 = 0i64;v34 = 0;v33 = 0i64;xor_len = strlen(xorval);do // xor{v10 = input;if ( v29 >= 0x10 )v10 = (void **)input[0];*((_BYTE *)v10 + i) ^= xorval[i % xor_len];++i;}while ( i < 32 );v11 = (__int128 *)input;v7 = (char *)input[0];if ( v29 >= 0x10 )v11 = (__int128 *)input[0];v31 = 0;memset(processed, 0, sizeof(processed));v32 = *v11;v33 = v11[1];sub_E525C0(v25, v26, 256, (unsigned int)&v32, (unsigned int)processed);// ?*(_DWORD *)v36 = 4161746867;*(_DWORD *)&v36[4] = 1571732668;checkval = v36;*(_DWORD *)&v36[8] = -2041750854;buf = processed;*(_DWORD *)&v36[12] = -748513468;v14 = 28;*(_DWORD *)&v36[16] = 371505743;*(_DWORD *)&v36[20] = 443719435;*(_DWORD *)&v36[24] = 644704357;*(_DWORD *)&v36[28] = 1741188026;while ( 1 ){checkarr = *(_DWORD *)checkval;if ( *(_DWORD *)checkval != *(_DWORD *)buf )break;checkval += 4;buf = (__int128 *)((char *)buf + 4);v17 = v14 < 4;v14 -= 4;if ( v17 ){v16 = 0;goto LABEL_19;}}v17 = (unsigned __int8)checkarr < *(_BYTE *)buf;// v15 < v13if ( (_BYTE)checkarr == *(_BYTE *)buf&& (v18 = checkval[1], v17 = v18 < *((_BYTE *)buf + 1), v18 == *((_BYTE *)buf + 1))&& (v19 = checkval[2], v17 = v19 < *((_BYTE *)buf + 2), v19 == *((_BYTE *)buf + 2))&& (v20 = checkval[3], v17 = v20 < *((_BYTE *)buf + 3), v20 == *((_BYTE *)buf + 3)) ){v16 = 0;}else{v16 = v17 ? -1 : 1; // v17 should be True}
LABEL_19:if ( v16 ) // v16 should be 0output = "Try again!\r\n";elseoutput = "Congratulations! I always knew you could do it.";v22 = sub_E52DA0((int)checkval, output);sub_E53050(v22);sub_E5ADBE("pause");}else{v6 = sub_E52DA0(v5, "Try again!\r\n");sub_E53050(v6);sub_E5ADBE("pause");v7 = (char *)input[0];}if ( v29 >= 0x10 ){v23 = v7;if ( v29 + 1 >= 0x1000 ){v7 = (char *)*((_DWORD *)v7 - 1);if ( (unsigned int)(v23 - v7 - 4) > 0x1F )_invalid_parameter_noinfo_noreturn();}sub_E564DE(v7);}return 0;
}
checkval可以直接动调出来, 和input处理过后的值进行比较, 全部通过就是congratulation, 需要逆sub_E525C0
这个函数, 动调一下猜测是某种加密函数, Findcrypt一下没有明确结果, 继续读一下伪码
void __cdecl sub_E525C0(int a1, int a2, int a3, unsigned int input, unsigned int processed)
{unsigned __int8 *v5; // ecxunsigned int process_tmp; // ebxunsigned __int8 *v7; // esiunsigned int v8; // ediunsigned int v9; // esiunsigned int v10; // edxunsigned int v11; // esi_DWORD *v12; // ecxint v13; // eaxunsigned int v14; // ebxchar *v15; // esi__m128i v16; // xmm0__m128i v17; // xmm1__m128i v18; // xmm0__m128i v19; // xmm1__m128i v20; // xmm0__m128i v21; // xmm1__m128i v22; // xmm0__m128i v23; // xmm1int v24; // ebxunsigned int v25; // eaxchar *v26; // esiunsigned int v27; // ediint v28; // ecxsigned int v29; // [esp+20h] [ebp-20h]int v30; // [esp+24h] [ebp-1Ch]_DWORD *Block; // [esp+28h] [ebp-18h]int v32[4]; // [esp+2Ch] [ebp-14h] BYREFprocess_tmp = processed;v7 = v5;v8 = (unsigned int)(a3 + 31) >> 5;v30 = 4 * v8;Block = malloc(4 * v8);v32[0] = -1839987866;v32[1] = 120;v32[2] = -1839987866;v32[3] = 120;sub_E52270(v7, (unsigned __int8 *)v32);sub_E520E0();sub_E52150();sub_E51F80();v29 = 0;if ( v8 ){do{dword_E80D94 = (2 * dword_E80DA4) ^ (unsigned __int16)(dword_E80DBC ^ (2 * dword_E80DA4));dword_E80D78 = (dword_E80DB8 << 16) | ((unsigned int)dword_E80DAC >> 15);v9 = (dword_E80D70 << 16) | ((unsigned int)dword_E80D90 >> 15);dword_E80D8C = (dword_E80D68 << 16) | ((unsigned int)dword_E80D84 >> 15);dword_E80D7C = v9;Block[v29] = v9 ^ sub_E52150();sub_E51F80();++v29;}while ( v29 < (int)v8 );process_tmp = processed;}v10 = 0;if ( v8 ){v11 = input;if ( v8 < 0x10 || process_tmp <= input + v30 - 4 && process_tmp + v30 - 4 >= input ){v12 = Block;}else{v12 = Block;if ( process_tmp > (unsigned int)&Block[v8 - 1] || process_tmp + v30 - 4 < (unsigned int)Block ){v13 = input + 16;v12 = Block;v14 = process_tmp + 32;v15 = (char *)Block - input;do{v16 = *(__m128i *)(v13 - 16);v13 += 64;v14 += 64;v17 = _mm_xor_si128(*(__m128i *)&Block[v10], v16);v18 = *(__m128i *)(v13 - 64);*(__m128i *)(v14 - 96) = v17;v19 = _mm_xor_si128(*(__m128i *)&v15[v13 - 64], v18);v20 = *(__m128i *)(v13 - 48);*(__m128i *)(processed - input + v13 - 64) = v19;v15 = (char *)Block - input;v21 = _mm_xor_si128(*(__m128i *)((char *)Block + v14 - processed - 64), v20);v22 = *(__m128i *)(v13 - 32);*(__m128i *)(v14 - 64) = v21;v23 = *(__m128i *)&Block[v10 + 12];v10 += 16;*(__m128i *)(v14 - 48) = _mm_xor_si128(v23, v22);}while ( v10 < (v8 & 0xFFFFFFF0) );process_tmp = processed;v11 = input;}}if ( v10 < v8 ){v24 = process_tmp - input;v25 = v11 + 4 * v10;v26 = (char *)v12 - input;v27 = v8 - v10;do{v28 = *(_DWORD *)&v26[v25];v25 += 4;*(_DWORD *)(v24 + v25 - 4) = *(_DWORD *)(v25 - 4) ^ v28;--v27;}while ( v27 );}}free(Block);
}
发现processed
在前面一大段操作里并没有作为左值进行, 只有最后一段进行了相关的赋值操作, 所以processed
的值只在这一段指令之后确定
伪码不清不楚, 直接读汇编, 结合动调的数值进行对比, 得知[esi + eax]存的就是与input处理之后数值xor的数组
shift+E导出, 两次xor处理, 逆回去就是flag
xorval = 'SWPU_2019_CTF'checkval = [0xB3, 0x37, 0x0F, 0xF8, 0xBC, 0xBC, 0xAE, 0x5D, 0xBA, 0x5A, 0x4D, 0x86, 0x44, 0x97, 0x62, 0xD3, 0x4F, 0xBA, 0x24, 0x16, 0x0B, 0x9F, 0x72, 0x1A, 0x65, 0x68, 0x6D, 0x26, 0xBA, 0x6B, 0xC8, 0x67
]
# print(len(xorval))process = [0x86, 0x0C, 0x3E, 0xCA, 0x98, 0xD7, 0xAE, 0x19, 0xE2, 0x77, 0x6B, 0xA6, 0x6A, 0xA1, 0x77, 0xB0, 0x69, 0x91, 0x37, 0x05, 0x7A, 0xF9, 0x7B, 0x30, 0x43, 0x5A, 0x4B, 0x10, 0x86, 0x7D, 0xD4, 0x28
]tmp = [0 for _ in range(32)]
for i in range(32):tmp[i] = process[i] ^ checkval[i]for i in range(32):tmp[i] ^= ord(xorval[i % len(xorval)])tmp[i] = chr(tmp[i])flag = ''.join(tmp)
print(flag)
[羊城杯 2020]login
pyinstaller, 解包工具 https://github.com/extremecoders-re/pyinstxtractor
>python pyinstxtractor.py attachment.exe
[+] Processing attachment.exe
[+] Pyinstaller version: 2.1+
[+] Python version: 3.6
[+] Length of package: 6021662 bytes
[+] Found 59 files in CArchive
[+] Beginning extraction...please standby
[+] Possible entry point: pyiboot01_bootstrap.pyc
[+] Possible entry point: login.pyc
[!] Warning: This script is running in a different Python version than the one used to build the executable.
[!] Please run this script in Python 3.6 to prevent extraction errors during unmarshalling
[!] Skipping pyz extraction
[+] Successfully extracted pyinstaller archive: attachment.exeYou can now use a python decompiler on the pyc files within the extracted directory
用uncompyle6
进行反编译, 拿到源码
# uncompyle6 version 3.9.0
# Python bytecode version base 3.6 (3379)
# Decompiled from: Python 3.6.13 |Anaconda, Inc.| (default, Mar 16 2021, 11:37:27) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: login.py
import sys
input1 = input('input something:')
if len(input1) != 14:print('Wrong length!')sys.exit()
else:code = []for i in range(13):code.append(ord(input1[i]) ^ ord(input1[i + 1]))code.append(ord(input1[13]))a1 = code[2]a2 = code[1]a3 = code[0]a4 = code[3]a5 = code[4]a6 = code[5]a7 = code[6]a8 = code[7]a9 = code[9]a10 = code[8]a11 = code[10]a12 = code[11]a13 = code[12]a14 = code[13]if (a1 * 88 + a2 * 67 + a3 * 65 - a4 * 5 + a5 * 43 + a6 * 89 + a7 * 25 + a8 * 13 - a9 * 36 + a10 * 15 + a11 * 11 + a12 * 47 - a13 * 60 + a14 * 29 == 22748) & \(a1 * 89 + a2 * 7 + a3 * 12 - a4 * 25 + a5 * 41 + a6 * 23 + a7 * 20 - a8 * 66 + a9 * 31 + a10 * 8 + a11 * 2 - a12 * 41 - a13 * 39 + a14 * 17 == 7258) & \(a1 * 28 + a2 * 35 + a3 * 16 - a4 * 65 + a5 * 53 + a6 * 39 + a7 * 27 + a8 * 15 - a9 * 33 + a10 * 13 + a11 * 101 + a12 * 90 - a13 * 34 + a14 * 23 == 26190) & \(a1 * 23 + a2 * 34 + a3 * 35 - a4 * 59 + a5 * 49 + a6 * 81 + a7 * 25 + (a8 << 7) - a9 * 32 + a10 * 75 + a11 * 81 + a12 * 47 - a13 * 60 + a14 * 29 == 37136) & \(a1 * 38 + a2 * 97 + a3 * 35 - a4 * 52 + a5 * 42 + a6 * 79 + a7 * 90 + a8 * 23 - a9 * 36 + a10 * 57 + a11 * 81 + a12 * 42 - a13 * 62 - a14 * 11 == 27915) & \(a1 * 22 + a2 * 27 + a3 * 35 - a4 * 45 + a5 * 47 + a6 * 49 + a7 * 29 + a8 * 18 - a9 * 26 + a10 * 35 + a11 * 41 + a12 * 40 - a13 * 61 + a14 * 28 == 17298) & \(a1 * 12 + a2 * 45 + a3 * 35 - a4 * 9 - a5 * 42 + a6 * 86 + a7 * 23 + a8 * 85 - a9 * 47 + a10 * 34 + a11 * 76 + a12 * 43 - a13 * 44 + a14 * 65 == 19875) & \(a1 * 79 + a2 * 62 + a3 * 35 - a4 * 85 + a5 * 33 + a6 * 79 + a7 * 86 + a8 * 14 - a9 * 30 + a10 * 25 + a11 * 11 + a12 * 57 - a13 * 50 - a14 * 9 == 22784) & \(a1 * 8 + a2 * 6 + a3 * 64 - a4 * 85 + a5 * 73 + a6 * 29 + a7 * 2 + a8 * 23 - a9 * 36 + a10 * 5 + a11 * 2 + a12 * 47 - a13 * 64 + a14 * 27 == 9710) & \(a1 * 67 - a2 * 68 + a3 * 68 - a4 * 51 - a5 * 43 + a6 * 81 + a7 * 22 - a8 * 12 - a9 * 38 + a10 * 75 + a11 * 41 + a12 * 27 - a13 * 52 + a14 * 31 == 13376) & \(a1 * 85 + a2 * 63 + a3 * 5 - a4 * 51 + a5 * 44 + a6 * 36 + a7 * 28 + a8 * 15 - a9 * 6 + a10 * 45 + a11 * 31 + a12 * 7 - a13 * 67 + a14 * 78 == 24065) & \(a1 * 47 + a2 * 64 + a3 * 66 - a4 * 5 + a5 * 43 + a6 * 112 + a7 * 25 + a8 * 13 - a9 * 35 + a10 * 95 + a11 * 21 + a12 * 43 - a13 * 61 + a14 * 20 == 27687) & \(a1 * 89 + a2 * 67 + a3 * 85 - a4 * 25 + a5 * 49 + a6 * 89 + a7 * 23 + a8 * 56 - a9 * 92 + a10 * 14 + a11 * 89 + a12 * 47 - a13 * 61 - a14 * 29 == 29250) & \(a1 * 95 + a2 * 34 + a3 * 62 - a4 * 9 - a5 * 43 + a6 * 83 + a7 * 25 + a8 * 12 - a9 * 36 + a10 * 16 + a11 * 51 + a12 * 47 - a13 * 60 - a14 * 24 == 15317):print('flag is GWHT{md5(your_input)}')print('Congratulations and have fun!')else:print('Sorry,plz try again...')
# okay decompiling login.pyc
z3解方程组
from z3 import *a1 = Int('a1')
a2 = Int('a2')
a3 = Int('a3')
a4 = Int('a4')
a5 = Int('a5')
a6 = Int('a6')
a7 = Int('a7')
a8 = Int('a8')
a9 = Int('a9')
a10 = Int('a10')
a11 = Int('a11')
a12 = Int('a12')
a13 = Int('a13')
a14 = Int('a14')solver = Solver()
solver.add(a1 * 88 + a2 * 67 + a3 * 65 - a4 * 5 + a5 * 43 + a6 * 89 + a7 * 25 + a8 * 13 - a9 * 36 + a10 * 15 + a11 * 11 + a12 * 47 - a13 * 60 + a14 * 29 == 22748)
solver.add(a1 * 89 + a2 * 7 + a3 * 12 - a4 * 25 + a5 * 41 + a6 * 23 + a7 * 20 - a8 * 66 + a9 * 31 + a10 * 8 + a11 * 2 - a12 * 41 - a13 * 39 + a14 * 17 == 7258)
solver.add(a1 * 28 + a2 * 35 + a3 * 16 - a4 * 65 + a5 * 53 + a6 * 39 + a7 * 27 + a8 * 15 - a9 * 33 + a10 * 13 + a11 * 101 + a12 * 90 - a13 * 34 + a14 * 23 == 26190)
solver.add(a1 * 23 + a2 * 34 + a3 * 35 - a4 * 59 + a5 * 49 + a6 * 81 + a7 * 25 + a8 * 128 - a9 * 32 + a10 * 75 + a11 * 81 + a12 * 47 - a13 * 60 + a14 * 29 == 37136)
solver.add(a1 * 38 + a2 * 97 + a3 * 35 - a4 * 52 + a5 * 42 + a6 * 79 + a7 * 90 + a8 * 23 - a9 * 36 + a10 * 57 + a11 * 81 + a12 * 42 - a13 * 62 - a14 * 11 == 27915)
solver.add(a1 * 22 + a2 * 27 + a3 * 35 - a4 * 45 + a5 * 47 + a6 * 49 + a7 * 29 + a8 * 18 - a9 * 26 + a10 * 35 + a11 * 41 + a12 * 40 - a13 * 61 + a14 * 28 == 17298)
solver.add(a1 * 12 + a2 * 45 + a3 * 35 - a4 * 9 - a5 * 42 + a6 * 86 + a7 * 23 + a8 * 85 - a9 * 47 + a10 * 34 + a11 * 76 + a12 * 43 - a13 * 44 + a14 * 65 == 19875)
solver.add(a1 * 79 + a2 * 62 + a3 * 35 - a4 * 85 + a5 * 33 + a6 * 79 + a7 * 86 + a8 * 14 - a9 * 30 + a10 * 25 + a11 * 11 + a12 * 57 - a13 * 50 - a14 * 9 == 22784)
solver.add(a1 * 8 + a2 * 6 + a3 * 64 - a4 * 85 + a5 * 73 + a6 * 29 + a7 * 2 + a8 * 23 - a9 * 36 + a10 * 5 + a11 * 2 + a12 * 47 - a13 * 64 + a14 * 27 == 9710)
solver.add(a1 * 67 - a2 * 68 + a3 * 68 - a4 * 51 - a5 * 43 + a6 * 81 + a7 * 22 - a8 * 12 - a9 * 38 + a10 * 75 + a11 * 41 + a12 * 27 - a13 * 52 + a14 * 31 == 13376)
solver.add(a1 * 85 + a2 * 63 + a3 * 5 - a4 * 51 + a5 * 44 + a6 * 36 + a7 * 28 + a8 * 15 - a9 * 6 + a10 * 45 + a11 * 31 + a12 * 7 - a13 * 67 + a14 * 78 == 24065)
solver.add(a1 * 47 + a2 * 64 + a3 * 66 - a4 * 5 + a5 * 43 + a6 * 112 + a7 * 25 + a8 * 13 - a9 * 35 + a10 * 95 + a11 * 21 + a12 * 43 - a13 * 61 + a14 * 20 == 27687)
solver.add(a1 * 89 + a2 * 67 + a3 * 85 - a4 * 25 + a5 * 49 + a6 * 89 + a7 * 23 + a8 * 56 - a9 * 92 + a10 * 14 + a11 * 89 + a12 * 47 - a13 * 61 - a14 * 29 == 29250)
solver.add(a1 * 95 + a2 * 34 + a3 * 62 - a4 * 9 - a5 * 43 + a6 * 83 + a7 * 25 + a8 * 12 - a9 * 36 + a10 * 16 + a11 * 51 + a12 * 47 - a13 * 60 - a14 * 24 == 15317)if solver.check():model = solver.model()print(model)'''
[a13 = 88,a3 = 10,a4 = 7,a10 = 108,a12 = 74,a1 = 119,a7 = 28,a6 = 43,a9 = 52,a14 = 33,a5 = 104,a8 = 91,a2 = 24,a11 = 88]
'''
提取置换表, 然后xor逆回去
'''
[a13 = 88,a3 = 10,a4 = 7,a10 = 108,a12 = 74,a1 = 119,a7 = 28,a6 = 43,a9 = 52,a14 = 33,a5 = 104,a8 = 91,a2 = 24,a11 = 88]a1 = code[2]
a2 = code[1]
a3 = code[0]
a4 = code[3]
a5 = code[4]
a6 = code[5]
a7 = code[6]
a8 = code[7]
a9 = code[9]
a10 = code[8]
a11 = code[10]
a12 = code[11]
a13 = code[12]
a14 = code[13]
'''flag = [0 for _ in range(14)]table = [2, 1, 0, 3, 4, 5, 6, 7, 9, 8, 10, 11, 12, 13]
sols = [119, 24, 10, 7, 104, 43, 28, 91, 52, 108, 88, 74, 88, 33]
table_sols = [0 for _ in range(14)]for i in range(14):table_sols[i] = sols[table[i]]flag[13] = table_sols[13]
for i in range(12, -1, -1):flag[i] = table_sols[i] ^ flag[i + 1]for i in range(14):flag[i] = chr(flag[i])flag = ''.join(flag)
print(flag)
[QCTF2018]Xman-babymips
注意python进行移位操作, 需要& 0xff
确保不溢出
checklist = [82, 253, 22, 164, 137, 189, 146, 128, 19, 65, 84, 160, 141, 69, 24, 129, 222, 252, 149, 240, 22, 121, 26, 21, 91, 117, 31, 0
]checkfirst = [81, 124, 106, 123, 103]flag = ''# first 5 bytes
for i in range(len(checkfirst)):flag += chr(checkfirst[i] ^ (32 - i))# last bytes
for i in range(5, 32):checkval = checklist[i - 5]for j in range(128):tmp = jif i % 2 == 1: # oddv1 = ((tmp >> 2) & 0xff) | ((tmp << 6) & 0xff)else: # evenv1 = ((tmp << 2) & 0xff) | ((tmp >> 6) & 0xff)if v1 == checkval:tmp ^= 32 - iflag += chr(tmp)print(i, chr(j))breakprint(flag)
[UTCTF2020]babymips
int __cdecl main(int argc, const char **argv, const char **envp)
{int v3; // $v0char input[24]; // [sp+18h] [+18h] BYREFchar flag[24]; // [sp+30h] [+30h] BYREFchar checklist[84]; // [sp+48h] [+48h] BYREFstd::string::basic_string(input, argv, envp);v3 = std::operator<<<std::char_traits<char>>(&std::cout, "enter the flag");std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>);std::operator>><char>(&std::cin, input);memcpy(checklist, &checkval, sizeof(checklist));std::string::basic_string(flag, input);check((int)checklist, (int)flag);std::string::~string(flag);std::string::~string(input);return 0;
}int __fastcall check(int checklist, int flag)
{int v2; // $v0int v4; // $v0unsigned int i; // [sp+1Ch] [+1Ch]if ( std::string::size(flag) != 78 ){
LABEL_2: // wrongv2 = std::operator<<<std::char_traits<char>>(&std::cout, "incorrect");return std::ostream::operator<<(v2, &std::endl<char,std::char_traits<char>>);}else{for ( i = 0; i < std::string::size(flag); ++i ){if ( (*(char *)std::string::operator[](flag, i) ^ (i + 23)) != *(char *)(checklist + i) )goto LABEL_2;} // correctv4 = std::operator<<<std::char_traits<char>>(&std::cout, "correct!");return std::ostream::operator<<(v4, &std::endl<char,std::char_traits<char>>);}
}
checklist = [98, 108, 127, 118, 122, 123, 102, 115, 118, 80, 82, 125, 64, 84, 85, 121, 64, 73, 71, 77, 116, 25, 123, 106, 66, 10, 79, 82, 125, 105, 79, 83, 12, 100, 16, 15, 30, 74, 103, 3, 124, 103, 2, 106, 49, 103, 97, 55, 122, 98, 44, 44, 15, 110, 23, 0, 22, 15, 22, 10, 109, 98, 115, 37, 57, 118, 46, 28, 99, 120, 43, 116, 50, 22, 32, 34, 68, 25, 0,
]flag = ''for i in range(len(checklist) - 1):flag += chr(checklist[i] ^ (23 + i))print(flag)
[GKCTF 2021]QQQQT
搜一下Enigma VB, 找到一个现有的解包工具 https://www.52pojie.cn/thread-1575691-1-1.html
shift+F12 没有明显的字符串, 那就一个个函数看(只需要考虑用户代码, 忽略框架代码), 找到可能的关键逻辑, 注释在伪码中
void __thiscall sub_4012F0(_DWORD *this)
{int v1; // edi_BYTE *v2; // esiconst char *v3; // edx_BYTE *v4; // esiint v5; // ecxint v6; // eaxint v7; // ecxint v8; // edxint v9; // ediint v10; // esi_BYTE *v11; // ecxunsigned int len_input; // ecxsize_t v13; // [esp-8h] [ebp-A8h]char v15[4]; // [esp+10h] [ebp-90h] BYREFchar v16[4]; // [esp+14h] [ebp-8Ch] BYREF_BYTE *v17; // [esp+18h] [ebp-88h]const char *input; // [esp+1Ch] [ebp-84h]int v19; // [esp+20h] [ebp-80h]int v20; // [esp+24h] [ebp-7Ch] BYREF_BYTE *v21; // [esp+28h] [ebp-78h] BYREFchar v22[60]; // [esp+2Ch] [ebp-74h] BYREF__int128 v23[2]; // [esp+68h] [ebp-38h] BYREF__int64 v24; // [esp+88h] [ebp-18h]int v25; // [esp+9Ch] [ebp-4h]QLineEdit::text(*(_DWORD *)(this[6] + 4), v15);// inputv25 = 0;QString::toLatin1(v15, v16);LOBYTE(v25) = 1;input = QByteArray::data((QByteArray *)v16); // input processedmemset(v23, 0, sizeof(v23));v24 = 0i64;strcpy(v22, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");// 58 chars guess it as base58v20 = 138 * strlen(input) / 0x64;v13 = v20 + 1;v1 = 0;v21 = malloc(v20 + 1);v2 = v21;memset(v21, 0, v13);v3 = input;v19 = (int)(input + 1);if ( strlen(input) ){v4 = &v2[v20];v17 = v4;while ( 1 ){v19 = ((char)*v4 << 8) + v3[v1];v5 = v19 / 58;*v4 = v19 % 58;if ( v5 ){do{v6 = (char)*--v4;v7 = (v6 << 8) + v5;v19 = v7 / 58;*v4 = v7 % 58; // / and % 58 v5 = v19;}while ( v19 );v4 = v17;}if ( ++v1 >= strlen(input) )break;v3 = input;}v2 = v21;}v8 = 0;if ( !*v2 ){do++v8;while ( !v2[v8] );}v9 = v20;if ( v8 <= v20 ){v10 = v2 - (_BYTE *)v23;do{v11 = (char *)v23 + v8++;*v11 = v22[(char)v11[v10]];}while ( v8 <= v9 );}if ( !qstrcmp((const char *)v23, "56fkoP8KhwCf3v7CEz") )// check{if ( input )len_input = strlen(input);elselen_input = -1;v21 = (_BYTE *)QString::fromAscii_helper(input, len_input);LOBYTE(v25) = 2;v20 = QString::fromAscii_helper("flag", 4);LOBYTE(v25) = 3;QMessageBox::warning(this, &v20, &v21, 1024, 0);// print flagQString::~QString((QString *)&v20);QString::~QString((QString *)&v21);}QByteArray::~QByteArray((QByteArray *)v16);QString::~QString((QString *)v15);
}
b58解密就是flag
相关文章:

BUUCTF reverse wp 65 - 70
[SWPU2019]ReverseMe 反编译的伪码看不明白, 直接动调 这里显示"Please input your flag", 然后接受输入, 再和32进行比较, 应该是flag长度要求32位, 符合要求则跳转到loc_E528EE分支继续执行 动调之后伪码可以读了 int __cdecl main(int argc, const char **arg…...

xorm数据库操作之Join、Union
golang的数据库操作xorm使用起来非常方便,不用再自己写SQl语句,而且xorm自己给我们做了SQL防注入等操作,用起来既方便又安全。此次文章我不会记录xorm的基本操作,我值记录一些特殊用法问题,包括动态创建表单、基于xorm…...

排序:基数排序算法分析
1.算法思想 假设长度为n的线性表中每个结点aj的关键字由d元组 ( k j d − 1 , k j d − 2 , k j d − 3 , . . . , k j 1 , k j 0 ) (k_{j}^{d-1},k_{j}^{d-2},k_{j}^{d-3},... ,k_{j}^{1} ,k_{j}^{0}) (kjd−1,kjd−2,kjd−3,...,kj1,kj0)组成, 其中&am…...

用go实现http服务端和请求端
一、概述 本文旨在学习记录下如何用go实现建立一个http服务器,同时构造一个专用格式的http客户端。 二、代码实现 2.1 构造http服务端 1、http服务处理流程 基于HTTP构建的服务标准模型包括两个端,客户端(Client)和服务端(Server)。HTTP 请求从客户端…...

幂级数和幂级数的和函数有什么关系?
幂级数和幂级数的和函数有什么关系? 本文例子引用自:80_1幂级数运算,逐项积分、求导【小元老师】高等数学,考研数学 求幂级数 ∑ n 1 ∞ 1 n x n \sum\limits_{n1}^{\infty}\frac{1}{n}x^n n1∑∞n1xn 的和函数 ÿ…...

Git多账号管理通过ssh 公钥的方式,git,gitlab,gitee
按照目前国内访问git,如果不科学上网,我们很大可能访问会超时。基于这个,所以我现在的git 配置已经增加到了3个了 一个公司gitlab,一个git,一个gitee. 以下基于这个环境,我们来说明下如何创建配置ssh公钥。…...
在nodejs常见的不良做法及其优化解决方案
在nodejs常见的不良做法及其优化解决方案 当涉及到在express和nodejs中开发应用程序时。遵循最佳实践对于确保项目的健壮性、可维护性和安全性至关重要。 在本文中,我们将探索开发人员经常遇到的几种常见的错误做法,并通过代码示例研究优化的最佳做法&…...
关于layui upload上传组件上传文件无反应的问题
最近使用layui upload组件时,碰到了上传文件无反应的问题,感到非常困惑。 因为使用layui upload组件不是一次两次了,之前每次都可以,这次使用同样的配方,同样的姿势,为什么就不行了呢? 照例先…...

容器网络之Flannel
第一个问题位置变化,往往是通过一个称为注册中心的地方统一管理的,这个是应用自己做的。当一个应用启动的时候,将自己所在环境的 IP 地址和端口,注册到注册中心指挥部,这样其他的应用请求它的时候,到指挥…...
SVM(下):如何进行乳腺癌检测?
⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据开发、数据分析等。 🐴欢迎小伙伴们点赞👍🏻、收藏⭐️、…...

嵌入式Linux应用开发-第十五章具体单板的按键驱动程序
嵌入式Linux应用开发-第十五章具体单板的按键驱动程序 第十五章 具体单板的按键驱动程序(查询方式)15.1 GPIO操作回顾15.2 AM335X的按键驱动程序(查询方式)15.2.1 先看原理图确定引脚及操作方法15.2.2 再看芯片手册确定寄存器及操作方法15.2.3 编程15.2.3.1 程序框架15.2.3.2 硬…...

MySQL体系结构和四层架构介绍
MySQL体系结构图如下: 四层介绍 1. 连接层: 它的主要功能是处理客户端与MySQL服务器之间的连接(比如Java应用程序通过JDBC连接MySQL)。当客户端应用程序连接到MySQL服务器时,连接层对用户进行身份验证、建立安全连接并管理会话状态。它还处理…...

【产品运营】如何做好B端产品规划
产品规划是基于当下掌握的多维度信息,为追求特定目的,而制定的产品资源投入计划。 产品规划是基于当下掌握的多维度信息(客户需求、市场趋势、竞争对手、竞争策略等),为追求特定目的(商业增长、客户满意等&…...
ruoyi-启动
1 springboot 版本 git 地址 ruoyi-vue-pro: 🔥 官方推荐 🔥 RuoYi-Vue 全新 Pro 版本,优化重构所有功能。基于 Spring Boot MyBatis Plus Vue & Element 实现的后台管理系统 微信小程序,支持 RBAC 动态权限、数据权限…...

select完成服务器并发
服务器 #include <myhead.h>#define PORT 4399 //端口号 #define IP "192.168.0.191"//IP地址//键盘输入事件 int keybord_events(fd_set readfds); //客户端交互事件 int cliRcvSnd_events(int , struct sockaddr_in*, fd_set *, int *); //客户端连接事件 …...

初级篇—第四章聚合函数
文章目录 聚合函数介绍聚合函数介绍COUNT函数AVG和SUM函数MIN和MAX函数 GROUP BY语法基本使用使用多个列分组WITH ROLLUP HAVING基本使用WHERE和HAVING的对比开发中的选择 SELECT的执行过程查询的结构SQL 的执行原理 练习流程函数 聚合函数介绍 聚合函数作用于一组数据&#x…...

计算机图像处理-中值滤波
非线性滤波 非线性滤波是利用原始图像跟模版之间的一种逻辑关系得到结果,常用的非线性滤波方法有中值滤波和高斯双边滤波,分别对应cv2.medianBlur(src, ksize)方法和cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])方法。 …...

Golang中的包和模块设计
Go,也被称为Golang,是一种静态类型、编译型语言,因其简洁性和对并发编程的强大支持而受到开发者们的喜爱。Go编程的一个关键方面是其包和模块系统,它允许创建可重用、可维护和高效的代码。本博客文章将深入探讨在Go中设计包和模块…...

web:[极客大挑战 2019]Upload
题目 页面显示为一个上传,猜测上传一句话木马文件 先查看源代码看一下有没有有用的信息,说明要先上传图片,先尝试上传含有一句话木马的图片 构造payload <?php eval($_POST[123]);?> 上传后页面显示为,不能包含<&…...

ICMP差错包
ICMP报文分类 Type Code 描述 查询/差错 0-Echo响应 0 Echo响应报文 查询 3-目的不可达 0 目标网络不可达报文 差错 1 目标主机不可达报文 差错 2 目标协议不可达报文 差错 3 目标端口不可达报文 差错 4 要求分段并设置DF flag标志报文 差错 5 源路由…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...

【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...

基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...
Qt Quick Controls模块功能及架构
Qt Quick Controls是Qt Quick的一个附加模块,提供了一套用于构建完整用户界面的UI控件。在Qt 6.0中,这个模块经历了重大重构和改进。 一、主要功能和特点 1. 架构重构 完全重写了底层架构,与Qt Quick更紧密集成 移除了对Qt Widgets的依赖&…...