xman2018
re0
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s; // [rsp+0h] [rbp-20h]
int v5; // [rsp+18h] [rbp-8h]
int i; // [rsp+1Ch] [rbp-4h]
for ( i = 0; i <= 181; ++i )
{
envp = (const char **)(*((unsigned __int8 *)judge + i) ^ 0xCu);
*((_BYTE *)judge + i) ^= 0xCu;
}//smc
printf("Please input flag:", argv, envp);
__isoc99_scanf("%20s", &s);
v5 = strlen(&s);
if ( v5 == 14 && judge((__int64)&s) )
puts("Right!");
else
puts("Wrong!");
return 0;
}
decode using IDAPython
for i in xrange(0,182):
PatchByte(0x600B00 + i ,Byte(0x600B00 + i) ^ 0x0C)
after decoding
int __fastcall judge(__int64 a1)
{
char keys[14]; // [rsp+8h] [rbp-20h]
int i; // [rsp+24h] [rbp-4h]
keys[0] = 102;
keys[1] = 109;
keys[2] = 99;
keys[3] = 100;
keys[4] = 127;
keys[5] = 107;
keys[6] = 55;
keys[7] = 100;
keys[8] = 59;
keys[9] = 86;
keys[10] = 96;
keys[11] = 59;
keys[12] = 110;
keys[13] = 112;
for ( i = 0; i <= 13; ++i )
*(_BYTE *)(i + a1) ^= i;
for ( i = 0; i <= 13; ++i )
{
if ( *(_BYTE *)(i + a1) != keys[i] )
return 0;
}
return 1;
}
solve
keys = [0] * 14
keys[0] = 102;
keys[1] = 109;
keys[2] = 99;
keys[3] = 100;
keys[4] = 127;
keys[5] = 107;
keys[6] = 55;
keys[7] = 100;
keys[8] = 59;
keys[9] = 86;
keys[10] = 96;
keys[11] = 59;
keys[12] = 110;
keys[13] = 112;
flag = ""
for i in xrange(0,14):
flag += chr(keys[i] ^ i)
print flag
re1
check is here, find this using bp MessageBoxA
and inspecting stack trace
char __thiscall check(_BYTE *this, int a2)
{
int i; // edi
_BYTE *v3; // ebp
int v4; // edx
signed int v5; // esi
char ret; // [esp+13h] [ebp-1h]
i = 0;
v3 = this;
ret = 1;
v4 = 10;
v5 = 0;
do
{
srand(v4);
v4 = rand() % 10;
if ( *(_BYTE *)(i + a2) != v3[v5 + 0x60 + v4] )
ret = 0;
v5 += 10;
++i;
}
while ( v5 < 330 );
CString::~CString((CString *)&a2);
return ret;
}
patch the original cmp into mov, so that after the loop, a2 will become the flag
.text:00401658 mov ecx, 0Ah
.text:0040165D idiv ecx
.text:0040165F mov ecx, [esp+14h+arg_0]
.text:00401663 mov cl, [edi+ecx]
.text:00401666 lea eax, [esi+edx]
.text:00401669 cmp cl, [eax+ebp+60h]
.text:0040166D jz short loc_401674
.text:0040166F mov [esp+14h+ret], 0
patch into
mov ecx, 0Ah
idiv ecx
mov ecx, [esp+14h+arg_0]
lea eax, [esi+edx]
push eax
mov al,[eax+ebp+60h]
mov [edi+ecx],al
pop eax
;... some nops maybe
re2
int setWriteFileHook()
{
HMODULE v0; // eax
DWORD v2; // eax
v2 = GetCurrentProcessId();
hProcess = OpenProcess(0x1F0FFFu, 0, v2);
v0 = LoadLibraryA(LibFileName);
WriteFileAddr = (int)GetProcAddress(v0, ProcName);
lpAddress = (LPVOID)WriteFileAddr;
if ( !WriteFileAddr )
return printf((int)aApi);
unk_40C9B4 = *(_DWORD *)lpAddress;
*((_BYTE *)&unk_40C9B4 + 4) = *((_BYTE *)lpAddress + 4);
byte_40C9BC = 0xE9u;
dword_40C9BD = (char *)hookWriteFile - (char *)lpAddress - 5;
return DoWriteProcessMemoryHook();
}
//WriteFile is inline hooked here
//The real check is here
int __stdcall hookWriteFile(HANDLE hFile, LPCVOID input, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
{
signed int v5; // ebx
v5 = check_real((char *)input, nNumberOfBytesToWrite);
DoWriteProcessMemoryUnhook();
WriteFile(hFile, input, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
if ( v5 )
*lpNumberOfBytesWritten = 1;
return 0;
}
signed int __cdecl check_real(char *input, signed int len)
{
char i; // al
char v3; // bl
char v4; // cl
int v5; // eax
i = 0;
if ( len > 0 )
{
do
{
if ( i == 18 )
{
input[18] ^= 0x13u;
}
else
{
if ( i % 2 ) // odd
v3 = input[i] - i;
else
v3 = input[i + 2];
input[i] = i ^ v3;
}
++i;
}
while ( i < len );
}
v4 = 0;
if ( len <= 0 )
return 1;
v5 = 0;
while ( aAjygkfm[v5] == input[v5] )
{
v5 = ++v4;
if ( v4 >= len )
return 1;
}
return 0;
}
It is not hard to solve
keys = [97, 106, 121, 103, 107, 70, 109, 46, 127, 95, 126, 45, 83, 86, 123, 56, 109, 76, 110]
flag = [ord('X')] * 19
for i in xrange(2,17,2):
flag[i] = keys[i - 2] ^ (i - 2)
for i in xrange(1,19,2):
flag[i] = (keys[i] ^ i) + i
flag[18] = keys[18] ^ 0x13
print "".join(map(chr,flag))
#Xlag{Ho0k_w1th_Fun}
#It seems that first byte is not limited
#but it should be flag{} anyway