Tags: re idapython emulation bruteforce ida 

Rating: 0

The binary reads the flag, then checks that `f[flag[i]](flag[i+1]) == enc_flag[i]`, where `enc_flag` is an array of integers and `f` is an array of 256 encrypted functions.

It is not a good idea to solve it with angr, so we decided to write an IDAPython script to solve it in static, with the help of Unicorn Engine:

```
import struct
import string

from unicorn import *
from unicorn.x86_const import *

def check_ea(ea):
if ea is None:
return ScreenEA()
return ea

def decr(ea=None):
ea = check_ea(ea)
enc_addr = Dword(ea)
size = Dword(ea + 4)
key = Qword(ea + 8)
for i in range(size):
enc = Byte(enc_addr + i)
PatchByte(enc_addr + i, (enc ^ (key >> ((i & 3) * 8))) & 0xFF)
MakeCode(enc_addr)
MakeFunction(enc_addr)

def decr_all(ea, n):
for i in range(n):
decr(ea + i * 16)

def emul(ea, size, arg):
stack = 0x7F000000
mu = Uc(UC_ARCH_X86, UC_MODE_32)
mu.mem_map(ea & 0xFFFFF000, 0x2000)
mu.mem_map(stack - 0x1000, 0x1000)
mu.mem_write(ea, GetManyBytes(ea, size - 1))
mu.mem_write(stack - 4, struct.pack('<i', arg))="" mu.reg_write(uc_x86_reg_esp,="" stack="" -="" 8)="" mu.emu_start(ea,="" ea="" +="" size="" -="" 1)="" return="" mu.reg_read(uc_x86_reg_eax)="" def="" solve():="" checkers_addr="0x0804C140" decr_all(checkers_addr,="" 256)="" checkers="[(Dword(checkers_addr" +="" i="" *="" 16),="" dword(checkers_addr="" +="" i="" *="" 16="" +="" 4))="" for="" i="" in="" range(256)]="" consts="CB00000000808B003B3D0000A8E50B002EDA000098010000C0830A00121C0E003D00000000698A0000AF89009D3A00004FFFFFFFDE000000701B00001EE70C008420000080F48A005301000002B80F00E6090000750E000054FFFFFFF41D0000E0430600FC09000063220000FC03F1FF005AFFFF3EEFFFFFDE0000004C2F0000920100003DD84E00720D00003C610000691D00009E0000001CD41000F30800001D1A5500370000004CFFFFFF0537000022371F00FD5B5B00E609000005070000B56F000099720000" .decode('hex')="" consts="[struct.unpack('&lt;I'," consts[i:i="" +="" 4])[0]="" for="" i="" in="" range(0,="" len(consts),="" 4)]="" alph="string.printable" for="" first_char="" in="" alph:="" prev="ord(first_char)" ans="[prev]" for="" const="" in="" consts:="" t="len(ans)" for="" c="" in="" alph:="" if="" emul(checkers[ans[-1]][0],="" checkers[ans[-1]][1],="" ord(c))="=" const:="" ans.append(ord(c))="" break="" if="" len(ans)="=" t:="" #="" letter="" not="" decrypted="" break="" if="" len(ans)=""> 1:
print '[*] ' + ''.join(map(chr, ans))

if __name__ == '__main__':
solve()
```

What's happening is decrypting all checkers (from `f` array), bruteforcing the first character and trying to decrypt all (by bruteforcing the character feeded to the checker, that is emulated). When executed the script gives the following output:

```
[*] 8t
[*] nT
[*] you are looking for this EKO{4ngr_d1dn't_like_th1s}
[*] Gg
```