Skip to content

Instantly share code, notes, and snippets.

@J4ckKn1ght
Last active December 21, 2019 17:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save J4ckKn1ght/47d84f0afe813227c32dbe410a0cb9ac to your computer and use it in GitHub Desktop.
Save J4ckKn1ght/47d84f0afe813227c32dbe410a0cb9ac to your computer and use it in GitHub Desktop.
from miasm.analysis.binary import Container
from miasm.analysis.machine import Machine
from miasm.analysis.simplifier import IRCFGSimplifierCommon
from miasm.core.locationdb import LocationDB
from miasm.expression.expression import ExprCond, ExprLoc, LocKey, ExprMem
from miasm.ir.ir import IRBlock, AssignBlock
from miasm.ir.symbexec import SymbolicExecutionEngine
# Init Binary
binary = "quarkslab.elf"
func_addr = 0x400550
cont = Container.from_stream(open(binary, 'rb'))
machine = Machine(cont.arch)
def add_ir_block(new_ircfg, state, loc_key):
new_assign_block = AssignBlock(state)
new_ir_block = IRBlock(loc_key, [new_assign_block])
new_ircfg.add_irblock(new_ir_block)
return new_ir_block
def symbolic_exec_at(ira, ircfg, loc_db, address, state, main_loc_keys):
symbolic_engine = SymbolicExecutionEngine(ira, state)
next_target = symbolic_engine.run_block_at(ircfg, address)
hit_loc_key = None
while not isinstance(next_target, ExprCond) and not isinstance(next_target, ExprMem):
if not isinstance(next_target, ExprLoc):
current_loc_key = get_loc_key_at(loc_db, int(next_target))
else:
current_loc_key = next_target.loc_key
if current_loc_key in main_loc_keys and hit_loc_key is None:
hit_loc_key = current_loc_key
next_target = symbolic_engine.run_block_at(ircfg, next_target, step=False)
return hit_loc_key, next_target, symbolic_engine.symbols, None
def get_address(loc_db, loc_key):
return loc_db.get_location_offset(loc_key)
def get_loc_key_at(loc_db, address):
return loc_db.get_offset_location(address)
# Disassembly, Lift
mdis = machine.dis_engine(cont.bin_stream, loc_db=cont.loc_db)
func_addr = func_addr
cfg = mdis.dis_multiblock(func_addr)
loc_db = cfg.loc_db
ira = machine.ira(loc_db)
ircfg = ira.new_ircfg_from_asmcfg(cfg)
# First simplify
common_simplifier = IRCFGSimplifierCommon(ira)
common_simplifier.simplify(ircfg, func_addr)
open('before_cfg.dot', 'w').write(ircfg.dot())
# Collect information
start_loc_key = get_loc_key_at(loc_db, func_addr)
dispatch_loc_key = cfg.successors(start_loc_key)[0]
pre_dispatch_loc_key = cfg.predecessors(dispatch_loc_key)
pre_dispatch_loc_key.remove(start_loc_key)
pre_dispatch_loc_key = pre_dispatch_loc_key[0]
main_loc_keys = cfg.predecessors(pre_dispatch_loc_key)
# Create new IRCFG
new_loc_db = LocationDB()
new_ira = machine.ira(new_loc_db)
new_ircfg = new_ira.new_ircfg()
num_loc_key = 0
map_ret_ir_block = {}
head = LocKey(num_loc_key)
# Start symbolic execute
to_do = [(func_addr, head, {}, None)]
num_loc_key += 1
while to_do:
next_target, loc_key, state, pre_block = to_do.pop()
hit_loc_key, next_target, state, ret_loc_key = symbolic_exec_at(ira, ircfg, loc_db, next_target, state,
main_loc_keys)
if isinstance(next_target, ExprCond):
new_loc_key1 = LocKey(num_loc_key)
new_loc_key2 = LocKey(num_loc_key + 1)
ir_dst = state[new_ircfg.IRDst]
new_cond = ExprCond(ir_dst.cond, ExprLoc(new_loc_key1, 64), ExprLoc(new_loc_key2, 64))
state[new_ircfg.IRDst] = new_cond
num_loc_key += 2
ir_block = add_ir_block(new_ircfg, state, loc_key)
state[new_ircfg.IRDst] = ir_dst
to_do.append((next_target.src1, new_loc_key1, state, ir_block))
to_do.append((next_target.src2, new_loc_key2, state, ir_block))
else:
add_ir_block(new_ircfg, state, loc_key)
common_simplifier = IRCFGSimplifierCommon(new_ira)
common_simplifier.simplify(new_ircfg, head)
open('final_cfg.dot', 'w').write(new_ircfg.dot())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment