mirror of
https://github.com/cea-sec/miasm
synced 2026-06-21 13:48:18 +00:00
167 lines
4.7 KiB
Python
167 lines
4.7 KiB
Python
import os, sys
|
|
from elfesteem import *
|
|
from miasm.tools.pe_helper import *
|
|
import inspect
|
|
from miasm.core import asmbloc
|
|
from miasm.core import parse_asm
|
|
from elfesteem import pe
|
|
from miasm.tools.to_c_helper import *
|
|
|
|
|
|
if len(sys.argv) < 2:
|
|
print "%s dllfile"%sys.argv[0]
|
|
sys.exit(0)
|
|
fname = sys.argv[1]
|
|
e = pe_init.PE(open(fname, 'rb').read())
|
|
in_str = bin_stream(e.virt)
|
|
|
|
# find gadget only in first section
|
|
section_code_name = e.SHList.shlist[0].name.strip("\x00")
|
|
s_code = e.getsectionbyname(section_code_name)
|
|
|
|
|
|
code_start = e.rva2virt(s_code.addr)
|
|
code_stop = e.rva2virt(s_code.addr+s_code.size)
|
|
|
|
|
|
print "run on", hex(code_start), hex(code_stop)
|
|
|
|
|
|
filename = os.environ.get('PYTHONSTARTUP')
|
|
if filename and os.path.isfile(filename):
|
|
execfile(filename)
|
|
|
|
|
|
def whoami():
|
|
return inspect.stack()[1][3]
|
|
|
|
|
|
|
|
def mem_read_wrap(evaluator, e):
|
|
return e
|
|
|
|
|
|
def mem_write_wrap(evaluator, dst, s, src, pool_out):
|
|
return ExprTop()
|
|
|
|
|
|
|
|
min_addr = code_start
|
|
max_addr = code_stop
|
|
|
|
print hex(min_addr), hex(max_addr)
|
|
arg1 = ExprId('ARG1', 32, True)
|
|
arg2 = ExprId('ARG2', 32, True)
|
|
ret1 = ExprId('RET1', 32, True)
|
|
|
|
data1 = ExprId('DATA1', 32, True)
|
|
data2 = ExprId('DATA2', 32, True)
|
|
data3 = ExprId('DATA3', 32, True)
|
|
data4 = ExprId('DATA4', 32, True)
|
|
data5 = ExprId('DATA5', 32, True)
|
|
data6 = ExprId('DATA6', 32, True)
|
|
data7 = ExprId('DATA7', 32, True)
|
|
data8 = ExprId('DATA8', 32, True)
|
|
data9 = ExprId('DATA9', 32, True)
|
|
data10 = ExprId('DATA10', 32, True)
|
|
|
|
machine = eval_abs({esp:init_esp, ebp:init_ebp, eax:init_eax, ebx:init_ebx, ecx:init_ecx, edx:init_edx, esi:init_esi, edi:init_edi,
|
|
cs:ExprInt(uint32(9)),
|
|
zf : ExprInt(uint32(0)), nf : ExprInt(uint32(0)), pf : ExprInt(uint32(0)),
|
|
of : ExprInt(uint32(0)), cf : ExprInt(uint32(0)), tf : ExprInt(uint32(0)),
|
|
i_f: ExprInt(uint32(1)), df : ExprInt(uint32(0)), af : ExprInt(uint32(0)),
|
|
iopl: ExprInt(uint32(0)), nt : ExprInt(uint32(0)), rf : ExprInt(uint32(0)),
|
|
vm : ExprInt(uint32(0)), ac : ExprInt(uint32(0)), vif: ExprInt(uint32(0)),
|
|
vip: ExprInt(uint32(0)), i_d: ExprInt(uint32(0)),tsc1: ExprInt(uint32(0)),
|
|
tsc2: ExprInt(uint32(0)),
|
|
dr7:ExprInt(uint32(0)),
|
|
cr0:init_cr0,
|
|
|
|
},
|
|
mem_read_wrap,
|
|
mem_write_wrap,
|
|
)
|
|
|
|
|
|
# add some info for example
|
|
machine.eval_instr(push(arg2))
|
|
machine.eval_instr(push(arg1))
|
|
machine.eval_instr(push(ret1))
|
|
machine.eval_instr(push(ebp))
|
|
machine.eval_instr(mov(ebp, esp))
|
|
machine.eval_instr(sub(esp, ExprInt(uint32(0x14))))
|
|
machine.eval_instr(mov(eax, ExprMem(ebp + ExprInt(uint32(8)))))
|
|
machine.eval_instr(mov(edx, ExprMem(eax + ExprInt(uint32(12)))))
|
|
machine.eval_instr(mov(eax, ExprMem(ebp + ExprInt(uint32(12)))))
|
|
machine.eval_instr(mov(ExprMem(esp), eax))
|
|
machine.eval_instr(push(ExprInt(uint32(0x1337beef))))
|
|
|
|
for k in machine.pool:
|
|
machine.pool[k] = expr_simp(machine.pool[k])
|
|
|
|
print dump_reg(machine.pool)
|
|
init_mem = dict(machine.pool)
|
|
|
|
|
|
for f_ad in xrange(min_addr, max_addr):
|
|
if f_ad %0x100 == 0:
|
|
print hex(f_ad)
|
|
machine.pool = dict(init_mem)
|
|
start_ad = f_ad
|
|
my_eip = ExprInt(uint32(f_ad))
|
|
cycles = 0
|
|
|
|
while True:
|
|
cycles += 1
|
|
# max 5 instructions chain
|
|
if cycles> 5:
|
|
break
|
|
|
|
#final check
|
|
if isinstance(my_eip, ExprCond):
|
|
my_eip = my_eip.src1
|
|
elif not isinstance(my_eip, ExprInt):
|
|
break
|
|
ad = int(my_eip.arg)
|
|
#if not e.is_in_virt_address(ad):
|
|
if not (min_addr < ad< max_addr):
|
|
break
|
|
in_str.offset = ad
|
|
|
|
l = x86_mn.dis(in_str)
|
|
# print hex(my_eip.arg), l
|
|
if not l:
|
|
break
|
|
|
|
args = []
|
|
my_eip.arg+=uint32(l.l)
|
|
try:
|
|
ex = get_instr_expr(l, my_eip, args)
|
|
except:
|
|
break
|
|
try:
|
|
my_eip, mem_dst = emul_full_expr(ex, l, my_eip, None, machine)
|
|
except:
|
|
break
|
|
|
|
for k in machine.pool:
|
|
machine.pool[k] = expr_simp(machine.pool[k])
|
|
|
|
if isinstance(my_eip, ExprCond):
|
|
continue
|
|
# we want eip controled by ARG* id or DATA
|
|
# here, crappy test on str (not clean expression filtering)
|
|
if not ("ARG" in str(my_eip) or "DATA" in str(my_eip)):
|
|
continue
|
|
|
|
# we want esp controled by ARG* id or DATA
|
|
my_esp = machine.pool[esp]
|
|
if not ("ARG" in str(my_esp) or "DATA" in str(my_esp)):
|
|
continue
|
|
|
|
# this should give stack pivot
|
|
print "#"*0x80
|
|
print 'constraint solved ad ', hex(start_ad)
|
|
print "eip", my_eip
|
|
print "esp", my_esp
|