#!/usr/bin/env python3 import sys binary = sys.argv[1] libs = sys.argv[2:] import angr add_options = { angr.options.LAZY_SOLVES, angr.options.SYMBOLIC_WRITE_ADDRESSES, angr.options.CONSERVATIVE_READ_STRATEGY, angr.options.CONSERVATIVE_WRITE_STRATEGY, angr.options.SYMBOL_FILL_UNCONSTRAINED_MEMORY, angr.options.SYMBOL_FILL_UNCONSTRAINED_REGISTERS, } remove_options = { angr.options.SIMPLIFY_CONSTRAINTS, angr.options.SIMPLIFY_EXPRS, angr.options.SIMPLIFY_MEMORY_READS, angr.options.SIMPLIFY_MEMORY_WRITES, angr.options.SIMPLIFY_REGISTER_READS, angr.options.SIMPLIFY_REGISTER_WRITES, angr.options.SIMPLIFY_RETS, } # ===== patch cpuid to enable avx2 # XXX: should share with unroll; in any case keep synchronized prevcpuid = angr.engines.vex.heavy.dirty.CORRECT_amd64g_dirtyhelper_CPUID_avx_and_cx16 def cpuid(state,_): eax = state.regs.rax[31:0] prevcpuid(state,_) # substitute some haswell cpuid data: state.registers.store('rax',0x000306c3,size=8,condition=(eax==1)) state.registers.store('rbx',0x04100800,size=8,condition=(eax==1)) state.registers.store('rcx',0x7ffafbff,size=8,condition=(eax==1)) state.registers.store('rdx',0xbfebfbff,size=8,condition=(eax==1)) state.registers.store('rax',0x00000000,size=8,condition=(eax==7)) state.registers.store('rbx',0x000027ab,size=8,condition=(eax==7)) state.registers.store('rcx',0x00000000,size=8,condition=(eax==7)) state.registers.store('rdx',0x9c000600,size=8,condition=(eax==7)) return None,[] angr.engines.vex.heavy.dirty.amd64g_dirtyhelper_CPUID_avx2 = cpuid # ===== main proj = angr.Project(binary,auto_load_libs=False,force_load_libs=libs) state = proj.factory.full_init_state(add_options=add_options,remove_options=remove_options) simgr = proj.factory.simgr(state) simgr.run() exits = simgr.deadended assert len(exits) == 1 for p in exits[0].posix.stdout.content: assert p[1].op == 'BVV' n = p[1].args[0] assert p[0].op == 'BVV' assert p[0].size() == 8*n data = p[0].args[0] sys.stdout.buffer.write(bytes(bytearray([255&(data>>(8*i)) for i in reversed(range(n))])))