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 源路由…...
算法基础课第二部分
算法基础课 第四讲 数学知识AcWing1381. 阶乘(同余,因式分解) 质数AcWing 866. 质数的判定---试除法AcWing 868. 质数的判定---埃氏筛AcWing867. 分解质因数---试除法AcWing 197. 阶乘---分解质因数---埃式筛 约数AcWing 869. 求约数---试除法AcWing 870. 约数个数-…...
【数据结构】外部排序、多路平衡归并与败者树、置换-选择排序(生成初始归并段)、最佳归并树算法
目录 1、外部排序 1.1 基本概念 1.2 方法 2、多路平衡归并与败者树 2.1 K路平衡归并 2.2 败者树 3、置换-选择排序(生成初始归并段)编辑 4、最佳归并树 4.1 理论基础编辑 4.2 构造方法 编辑 5、各种排序算法的性质 1、外部排序 1.1 基本概…...
抽象工厂模式 创建性模式之五
在看这篇文章之前,请先看看“简单工厂模式”和“工厂方法模式”这两篇博文,会更有助于理解。我们现在已经知道,简单工厂模式就是用一个简单工厂去创建多个产品,工厂方法模式是每一个具体的工厂只生产一个具体的产品,然…...
servlet如何获取PUT和DELETE请求的参数
1. servlet为何不能获取PUT和DELETE请求的参数 Servlet的规范是POST的数据需要转给request.getParameter*()方法,没有规定PUT和DELETE请求也这么做 The Servlet spec requires form data to be available for HTTP POST but not for HTTP PUT or PATCH requests. T…...
【Vue.js】使用Element中的Mock.js搭建首页导航左侧菜单---【超高级教学】
一,Mock.js 1.1 认识Mock.js Mock.js是一个用于前端开发中生成随机数据、模拟接口响应的 JavaScript 库。模拟数据的生成器,用来帮助前端调试开发、进行前后端的原型分离以及用来提高自动化测试效率 总结来说,Element中的Mock.js是一个用于…...
从技术创新到应用实践,百度智能云发起大模型平台应用开发挑战赛!
大模型已经成为未来技术发展方向的重大变革,热度之下更需去虚向实,让技术走进产业场景。在这样的背景下,百度智能云于近期发起了“百度智能云千帆大模型平台应用开发挑战赛”。 挖掘大模型落地应用 千帆大模型平台应用开发挑战赛启动 在不久前…...
简单三步 用GPT-4和Gamma自动生成PPT PDF
1. 用GPT-4 生产PPT内容 我想把下面的文章做成PPT,请你给出详细的大纲和内容 用于谋生的知识,学生主要工作是学习,成年人的工作是养家糊口,这是基本的要求,在这之上,才能有更高的追求。 不要短期期望过高…...
QT设置弹窗显示屏幕中央
Qt设置每次运行弹窗显示屏幕中央 要确保Qt应用程序中的弹出窗口每次都显示在屏幕的中央,您可以使用以下方法: 使用QMessageBox的move方法手动设置窗口位置: #include <QApplication> #include <QMessageBox> #include <QDesk…...
正点原子嵌入式linux驱动开发——STM32MP1启动详解
STM32单片机是直接将程序下载到内部 Flash中,上电以后直接运行内部 Flash中的程序。 STM32MP157内部没有供用户使用的 Flash,系统都是存放在外部 Flash里面的,比如 EMMC、NAND等,因此 STM32MP157上电以后需要从外部 Flash加载程序…...
FPGA的数字钟带校时闹钟报时功能VHDL
名称:基于FPGA的数字钟具有校时闹钟报时功能 软件:Quartus 语言:VHDL 要求: 1、计时功能:这是数字钟设计的基本功能,每秒钟更新一次,并且能在显示屏上显示当前的时间。 2、闹钟功能:如果当前的时间与闹钟设置的时…...
邯郸专业做网站报价/查关键词热度的网站
在实际的开发过程中,我们经常需要用到缓存。使用缓存常见的一个场景就是key不在缓存中,这个时候我们会去读取这个key对应的值,然后把这个值放到缓存中,代码如下: public class CacheNoFuture {private ConcurrentHashM…...
网站开发模板下载/长春网站建设推广
一、编码表的由来 计算机只能识别二进制数据,早期由来是电信号。为了方便应用计算机,让它可以识别各个国家的文字。就将各个国家的文字用数字来表示,并一一对应,形成一张表。这就是编码表 常见的编码表: ASCII:美国标准信息交换码。用一个字节的7位可以表示。ISO8859-1…...
做网站高手/今日头条网站推广
开发框架 1. ORM, LLBL Gen,NHibernate 2. 接口与实现分离,界面与逻辑分离,分五个项目, BusinessLogic, Interface,Manager,Validation,EntryForm 3. SQL与ORM 4. 通讯集成 Remoting/WCF 5. Control/Component: NumberiEditor…...
商业网站定义/seo sem
“秋招“求职季已经过了大半,有的小伙伴已经在这个赛季的前半段成功突围,顺利地找到了心仪的新东家,还有部分小伙伴仍每天苦苦煎熬,不得上岸,辗转在面试之间。 说到求职面试,不得不提的就是那些“招人恨”…...
网页导航设计步骤/seo排名优化公司
经典动态规划问题。用dp[i][j]表示字符串s的以i开头,以j结尾的子串的最大回文子序列的长度。我们要求的s的最长回文子序列的长度就是dp[0][n - 1]。考虑一下数组的初始化,对于所有的i(0 < i < n),都有dp[i][i] 1,表示单个字…...
有哪些调查网站可以做兼职/黑龙江网络推广好做吗
题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。方法一:新建一个字符串进行替换 * 创建一个新的buffer对象 对原来的字符串进行遍历 遇到一个数值…...