テストファイル:https : //lanzous.com/ibh1vch
コード分析
void __noreturn start() { DWORD NumberOfBytesWritten; // [esp + 0h] [ebp-4h] NumberOfBytesWritten = 0 ; hFile = GetStdHandle(0xFFFFFFF6 ); dword_403074 = GetStdHandle(0xFFFFFFF5 ); WriteFile(dword_403074、aG1v3M3T3hFl4g、0x13u、&NumberOfBytesWritten、0 ); sub_4010F0(); if (sub_401050()) WriteFile(dword_403074、aG00dJ0b、0xAu、&NumberOfBytesWritten、0 ); それ以外の場合は WriteFile(dword_403074、aN0tT00H0tRWe7r、0x24u、&NumberOfBytesWritten、0 ); ExitProcess(0 ); }
ここでは、sub_4010F0およびsub_401050関数を分析します。
sub_4010F0関数
signed int sub_4010F0() { unsigned int v0; // eax char Buffer [ 260 ]; // [esp + 0h] [ebp-110h] DWORD NumberOfBytesRead; // [esp + 104h] [ebp-Ch] unsigned int i; // [esp + 108h] [ebp-8h] char v5; // [esp + 10Fh] [ebp-1h] v5 = 0 ; for(i = 0 ; i < 0x104 ; ++ i) Buffer [i] = 0 ; ReadFile(hFile、Buffer、0x104u、&NumberOfBytesRead、0 ); for(i = 0 ;; ++ i) { v0 = sub_401020(Buffer); if(i> = v0) ブレーク; v5 = Buffer [i]; if(v5!= 10 && v5!= 13 ) { if (v5) byte_403078 [i] = v5; } } return 1 ; }
sub_401050関数
符号付きint sub_401050() { int v0; // ST04_4 int i; // [esp + 4h] [ebp-8h] unsigned int j; // [esp + 4h] [ebp-8h] char v4; // [esp + Bh] [ebp-1h] v0 = sub_401020(byte_403078); v4 = sub_401000(); 以下のための(I = V 0 - 1 ; I> = 0 ; - I) { byte_403180 [I] = V4 ^ byte_403078 [I]。 v4 = byte_403078 [i]; } for(j = 0 ; j < 0x27 ; ++ j) { if(byte_403180 [j]!= (unsigned __int8)byte_403000 [j]) return 0 ; } return 1 ; }
または分析を逆にします
sub_401050関数は、文字列に対して逆OR演算を実行し、既知の文字列byte_403000と比較します。
sub_4010F0関数は、入力文字列から/ r / nを削除します。
スクリプト
#- * -コーディング:UTF-8 - * - ARR2 = [0x0Dの、0x26,0x49,0x45,0x2A、0x17,0x78,0x44,0x2B、0x6C、0x5D、0x5Eの、0x45,0x12,0x2F、0x17の、 0x2Bを、0x44の、0x6F、0x6E、0x56,0x09,0x5F、0x45,0x47,0x73,0x26,0x0A、0x0Dを、0x13,0x17,0x48 、 0x42,0x01,0x40,0x4D、0x0Cの、0x02,0x69 ] ARR1 = [] V4 = 4 用 I における範囲(LEN(ARR2)-1、-1、-1 ): arr1.append(ARR2 [I] ^ V4) V4 = ARR1 [-1 ] プリント(' フラグ{ ' + '' .join([ CHR(X)のために X でarr1 [::-1]])+ ' } ')
フラグを取得!
フラグ{[email protected]}