diff options
Diffstat (limited to 'miasm/tools')
| -rw-r--r-- | miasm/tools/__init__.py | 18 | ||||
| -rw-r--r-- | miasm/tools/codenat.py | 181 | ||||
| -rwxr-xr-x | miasm/tools/emul_helper.py | 692 | ||||
| -rw-r--r-- | miasm/tools/emul_lib/__init__.py | 18 | ||||
| -rw-r--r-- | miasm/tools/emul_lib/libcodenat.c | 1639 | ||||
| -rw-r--r-- | miasm/tools/emul_lib/libcodenat.h | 566 | ||||
| -rw-r--r-- | miasm/tools/emul_lib/libcodenat_interface.c | 1579 | ||||
| -rw-r--r-- | miasm/tools/emul_lib/libcodenat_tcc.c | 152 | ||||
| -rw-r--r-- | miasm/tools/emul_lib/main.c | 43 | ||||
| -rw-r--r-- | miasm/tools/emul_lib/queue.h | 553 | ||||
| -rwxr-xr-x | miasm/tools/func_analyser.py | 485 | ||||
| -rwxr-xr-x | miasm/tools/hook_helper.py | 236 | ||||
| -rw-r--r-- | miasm/tools/modint.py | 256 | ||||
| -rw-r--r-- | miasm/tools/nux_api.py | 1113 | ||||
| -rw-r--r-- | miasm/tools/pe_helper.py | 743 | ||||
| -rw-r--r-- | miasm/tools/seh_helper.py | 736 | ||||
| -rw-r--r-- | miasm/tools/to_c_helper.py | 1374 | ||||
| -rw-r--r-- | miasm/tools/win_api.py | 3081 |
18 files changed, 0 insertions, 13465 deletions
diff --git a/miasm/tools/__init__.py b/miasm/tools/__init__.py deleted file mode 100644 index fbabaacf..00000000 --- a/miasm/tools/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python -# -# Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# diff --git a/miasm/tools/codenat.py b/miasm/tools/codenat.py deleted file mode 100644 index dc934e4c..00000000 --- a/miasm/tools/codenat.py +++ /dev/null @@ -1,181 +0,0 @@ -# -# Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -import os -import sys -from hashlib import md5 - -from ctypes import * -from miasm.tools.to_c_helper import * -from miasm.tools.emul_lib import libcodenat_interface - - -# interrupt with eip update after instr -EXCEPT_CODE_AUTOMOD = (1<<0) -EXCEPT_SOFT_BP = (1<<1) - -EXCEPT_BREAKPOINT_INTERN = (1<<2) - -EXCEPT_NUM_UDPT_EIP = (1<<5) -# interrupt with eip at instr -EXCEPT_UNK_MEM_AD = (1<<6) -EXCEPT_THROW_SEH = (1<<7) -EXCEPT_UNK_EIP = (1<<8) -EXCEPT_ACCESS_VIOL = (1<<9) -EXCEPT_INT_DIV_BY_ZERO = (1<<10) -EXCEPT_PRIV_INSN = (1<<11) -EXCEPT_ILLEGAL_INSN = (1<<12) - - - - - -EXCEPTION_BREAKPOINT = 0x80000003 -EXCEPTION_ACCESS_VIOLATION = 0xc0000005 -EXCEPTION_INT_DIVIDE_BY_ZERO = 0xc0000094 -EXCEPTION_PRIV_INSTRUCTION = 0xc0000096 -EXCEPTION_ILLEGAL_INSTRUCTION = 0xc000001d - - - - -PAGE_READ = 1 -PAGE_WRITE = 2 -PAGE_EXEC = 4 - -BREAKPOINT_READ = 1 -BREAKPOINT_WRITE = 2 - - - -class bloc_nat: - def __init__(self, offset = 0, b = None, module_c = None, c_source = None, log_mn = False, log_regs = False): - self.b = b - self.module_c = module_c - self.c_source = c_source - -blocs_nat = {} - -def gen_C_module(c_source): - - lib_name = 'emul_cache/out_'+md5(c_source).hexdigest() - lib_dir = os.path.dirname(os.path.realpath(__file__)) - lib_dir = os.path.join(lib_dir, 'emul_lib') - - a = None - try: - aa = os.stat(lib_name+'.so') - a = cdll.LoadLibrary('./%s.so'%lib_name) - except: - a = None - if a == None: - open(lib_name+'.c', 'w').write(c_source) - - gcc_opts = " -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes " - gcc_opts += " -fPIC -I/usr/include/python2.6 " - os.system('gcc -c '+gcc_opts + ' -L%s -lcodenat -lpython2.6 %s.c -o %s.o'%(lib_dir, lib_name, lib_name)) - - gcc_opts = ' -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions ' - gcc_opts += ' -L%s -lcodenat '%lib_dir - gcc_opts_end = ' -Wl,-rpath,%s '%lib_dir - os.system('gcc ' + gcc_opts + '%s.o -o %s.so '%(lib_name, lib_name) + gcc_opts_end) - - a = cdll.LoadLibrary('%s.so'%lib_name) - - return a - - -def del_bloc_in_range(known_blocs, ad1, ad2): - bloc_out = {} - for ad in known_blocs: - bn = known_blocs[ad] - # XXX no lines in bloc? - if not bn.b.lines: - continue - - if bn.b.lines[0].offset>=ad2 or bn.b.lines[-1].offset + bn.b.lines[-1].l <= ad1: - #bloc_out.append(b) - bloc_out[ad] = bn - else: - #print 'inv bloc', bn.b.label - pass - - return bloc_out - - - - -def vm_save_state(fname): - vmem = vm_get_all_memory() - return vmem - #XXX - - - - -libcntcc = None -def codenat_tcc_load(): - global libcntcc - from distutils.sysconfig import get_python_inc - import emul_lib.libcodenat_tcc as libcntcc - lib_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "emul_lib") - lib_path = os.path.join(lib_dir, 'libcodenat_tcc.so') - libcodenat_path = libcodenat_interface.__file__ - libdir = os.path.dirname(libcodenat_path) - - - # XXX HACK - # As debian, ubuntu, ... have moved some include files using arch directory, - # TCC doesn't know them, so we get the info from GCC - # For example /usr/include/x86_64-linux-gnu which contains limits.h - from subprocess import Popen, PIPE - p = Popen(["cc", "-Wp,-v", "-E", "-"], stdout = PIPE, stderr = PIPE, stdin = PIPE) - p.stdin.close() - include_path = p.stderr.read().split('\n') - include_path = [x[1:] for x in include_path if x.startswith(' /usr/include')] - include_path += [libdir, get_python_inc()] - - - include_path = ";".join(include_path) - libcntcc.tcc_set_emul_lib_path(include_path, libcodenat_path) - -def codenat_tcc_init(): - global libcntcc - if libcntcc == None: - codenat_tcc_load() - -def codenat_tcc_compil(func_name, func_code): - global libcntcc - c = libcntcc.tcc_compil(func_name, func_code) - return c - -def codenat_tcc_exec(a): - global libcntcc - oo = libcntcc.tcc_exec_bloc(a) - return oo - -def rr(): - pass - -class tcc_code(): - def __init__(self, c): - self.c = c - self.func = lambda :libcntcc.tcc_exec_bloc(self.c) - -def gen_C_module_tcc(f_name, c_source): - mcode = codenat_tcc_compil(f_name, c_source) - return tcc_code(mcode) diff --git a/miasm/tools/emul_helper.py b/miasm/tools/emul_helper.py deleted file mode 100755 index 488b8124..00000000 --- a/miasm/tools/emul_helper.py +++ /dev/null @@ -1,692 +0,0 @@ -#!/usr/bin/env python -# -# Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# - -from miasm.arch.ia32_sem import * -from miasm.expression.expression_helper import * -from miasm.core.memory_pool import * -from miasm.core import asmbloc -import StringIO -import zlib - -from miasm.expression.expression_eval_abstract import * - -log_emu_helper = logging.getLogger("emu.helper") -console_handler = logging.StreamHandler() -console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s")) -log_emu_helper.addHandler(console_handler) -log_emu_helper.setLevel(logging.WARN) - -def hexdump(a, offset = 0): - out ="" - for i,c in enumerate(a): - if i%0x10==0: - out+="\n%.8X "%(offset+i) - - out+="%.2X "%ord(c) - return out - - -def tohex(a): - - try: - a = int(a) - except: - return a - if a <0: - a = struct.pack('l', a) - else: - a = struct.pack('L', a) - a = struct.unpack('L', a)[0] - return hex(a) - - -jcc = ['jz', 'je', 'jnz', 'jp', 'jnp', 'jg', 'jge', 'ja', 'jae', 'jb', 'jbe', 'jl', 'jle', 'js', 'jns', 'jo', 'jno', 'loop', 'loopne', 'loope', 'jecxz'] - -def dump_pool(p): - log_emu_helper.error('/-------------\\') - for x in p: - log_emu_helper.error(str(x)+' '+tohex(str(p[x]))) - log_emu_helper.error('\\_____________/') - -def dump_reg(p): - out = " "*20 - for x in [eax, ebx, ecx, edx, esi, edi, esp, ebp, zf]: - if isinstance(p[x], ExprInt): - out+=str(x)+' %.8X '%int(p[x].arg) - else: - out+=str(x)+' %s '%p[x] - - return out - -def cmp_ptr(x, y): - r = expr_simp(x.arg-y.arg) - if not isinstance(r, ExprInt): - return 1 - if r.arg == 0: - return 0 - r = expr_simp(get_op_msb(r)) - if r == ExprInt(uint1(0)): - return 1 - else: - return -1 -def dump_mem(p): - out = [] - todo = [] - kk = p.keys() - kk.sort() - for x in kk: - if isinstance(x, ExprMem): - todo.append(x) - todo.sort(cmp=lambda x,y:cmp_ptr(x, y)) - for x in todo: - out.append('%s %s'%(str(x), str(p[x]))) - - return "\n".join(out) - -def mem_read(evaluator, env, src_address, mem_size): - if not isinstance(src_address, ExprInt): - dump_pool(evaluator.pool) - raise "cannot read", str(src_address) - src_address_l = int(src_address.arg) - try: - - if mem_size == 32: - ret = uint32(env.get_d(src_address_l)) - elif mem_size == 16: - ret = uint16(env.get_w(src_address_l)) - elif mem_size == 8: - ret = uint8(env.get_b(src_address_l)) - else: - raise 'unknown size read', str(src_address.nbytes) - log_emu_helper.debug("=>read @(%X)(%.8X)"%(src_address_l, int(ret))) - return ExprInt(ret) - except: - dump_pool(evaluator.pool) - raise ValueError('read bug at 0x%X'%int(src_address_l)) - -def mem_write(evaluator, env, mem_size, dst_address, src_val, pool_out = None): - if not isinstance(dst_address, ExprInt) or not isinstance(src_val, ExprInt): - dump_pool(evaluator.pool) - raise ValueError("cannot write %s %s"%(str(dst_address), str(src_val))) - dst_address_l = int(dst_address.arg) - src_val = src_val.arg - try: - log_emu_helper.debug("=>write @(%X)(%.8X)"%(dst_address_l, int(src_val))) - if mem_size == 32: - env.set_d(dst_address_l, src_val&0xffffffff) - elif mem_size == 16: - env.set_w(dst_address_l, src_val&0xffff) - elif mem_size == 8: - env.set_b(dst_address_l, src_val&0xff) - else: - raise 'unknown size write', str(dst_address.nbytes) - except: - dump_pool(evaluator.pool) - raise' write bug' -""" -###XXX for eval int -def get_instr_expr_args(name, modifs, mnemo_mode, args, my_eip): - for a in args: - if type(a) in [int, long]: - raise ValueError('int deprec in args') - - - if name in ['jmp']: - if isinstance(args[0], ExprInt): - print "X"*0x10, args[0] - arga = args[0].arg - if isinstance(arga, uint8): - arga = int8(arga) - e = mnemo_func[name](ExprOp('+', my_eip, ExprInt(uint32(arga)))) - else: - e = mnemo_func[name](*args) - elif name in jcc: - arga = args[0].arg - if isinstance(arga, uint8): - arga = int8(arga) - e = mnemo_func[name](my_eip, ExprOp('+', my_eip, ExprInt(uint32(arga)))) - elif name in ['call']: - if isinstance(args[0], ExprInt):# or is_imm(args[0]): - arga = args[0].arg - if isinstance(arga, uint8): - arga = int8(arga) - - e = mnemo_func[name](my_eip, ExprOp('+', my_eip, ExprInt(uint32(arga)))) - else: - e = mnemo_func[name](my_eip, args[0]) - else: - e = mnemo_func[name](*args) - return e -""" - - -#""" -###XXX for eval abs -def get_instr_expr_args(l, args, my_eip): - for a in args: - if type(a) in [int, long]: - raise ValueError('int deprec in args') - - info = l - if l.m.name in ['jmp']: - if isinstance(args[0], ExprInt): - e = mnemo_func[l.m.name](info, args[0]) - else: - e = mnemo_func[l.m.name](info, *args) - elif l.m.name in jcc: - e = mnemo_func[l.m.name](l, my_eip, args[0]) - elif l.m.name in ['call']: - e = mnemo_func[l.m.name](l, my_eip, args[0]) - else: - e = mnemo_func[l.m.name](l, *args) - return e -#""" - -###XXX for eval abs -def get_instr_expr(l, my_eip, args = None, segm_to_do = set()): - if args==None:args = [] - for x in l.arg: - args.append(dict_to_Expr(x, l.m.modifs, l.opmode, l.admode, segm_to_do)) - l.arg_expr = args - return get_instr_expr_args(l, args, my_eip) - - - - - -def emul_expr(machine, e, my_eip): - mem_dst = machine.eval_instr(e) - - if eip in machine.pool: - if isinstance(machine.pool[eip], ExprCond): - pass - my_eip = machine.eval_expr(eip, {}) - del machine.pool[eip] - return my_eip, mem_dst - -def emul_bloc(machine, bloc): - return emul_lines(machine, bloc.lines) - - - -def emul_lines(machine, lines): - my_eip = None - for l in lines: - my_eip = ExprInt(uint32(l.offset)) - - args = [] - my_eip.arg+=uint32(l.l) - ex = get_instr_expr(l, my_eip, args) - my_eip, mem_dst = emul_full_expr(ex, l, my_eip, None, machine) - - for k in machine.pool: - machine.pool[k] = expr_simp(machine.pool[k]) - - return my_eip - - - -def emul_imp_init(machine, libbase = 0xCCC00000, malloc_next_ad = 0xEEE00000): - #for loadlibrary & getprocaddress emul - machine.lib_bases = {} - machine.lib_bases_func_index = {} - machine.lib_base = libbase - machine.func_loaded = {} - - #for malloc & free emul - machine.malloc_next_ad = malloc_next_ad; - - -def emul_loadlibrary(machine, env): - my_esp = machine.eval_expr(machine.pool[esp], {}) - libname_ad = env.get_d(my_esp+4) - libname = "" - l = 0 - while True: - libname+=chr(env.get_b(libname_ad+l)) - l+=1 - if libname[-1]=='\x00': - break - - machine.lib_bases[machine.lib_base] = libname - machine.lib_bases_func_index[machine.lib_base] = machine.lib_base+1 - machine.eval_instr(mov(eax, ExprInt(uint32(machine.lib_base)))) - - machine.lib_base+=0x1000 - print "emul loadlib %X, %s"%(libname_ad, libname[:-1]) - log.info("emul loadlib %X, %s"%(libname_ad, libname)) - machine.eval_instr(ret(ExprInt(uint32(4)))) - my_eip = machine.eval_expr(machine.pool[eip], {}) - del machine.pool[eip] - return my_eip - -def emul_getprocaddress(machine, env): - my_esp = machine.eval_expr(machine.pool[esp], {}) - libbase_ad = env.get_d(my_esp+4) - funcname_ad = env.get_d(my_esp+8) - funcname = "" - l = 0 - while True: - funcname+=chr(env.get_b(funcname_ad+l)) - l+=1 - if funcname[-1]=='\x00': - break - - log.info("emul getprocaddress %X, %s"%(libbase_ad, funcname)) - print "emul getprocaddress %X, %s"%(libbase_ad, funcname[:-1]) - - if not libbase_ad in machine.lib_bases: - log.debug(machine.lib_bases) - raise 'unknown base lib! %s'%str(libbase_ad) - func_ad = machine.lib_bases_func_index[libbase_ad] - - machine.lib_bases_func_index[libbase_ad]+=1 - machine.eval_instr(mov(eax, ExprInt(uint32(func_ad)))) - - machine.func_loaded[func_ad] = funcname - - machine.eval_instr(ret(ExprInt(uint32(8)))) - my_eip = machine.eval_expr(machine.pool[eip], {}) - del machine.pool[eip] - return my_eip - -def hook_import_func(env, imported_func, start_address_hook = 0xAABB0000): - func_hook_ptr = {} - for f in imported_func: - env.set_d(f, start_address_hook) - func_hook_ptr[start_address_hook] = imported_func[f] - start_address_hook+=0x10000 - - return func_hook_ptr - -def dump_imp(machine): - - log_emu_helper.warn('_'*10) - for l in machine.lib_bases: - log_emu_helper.warn("%.8X %s"%(l, machine.lib_bases[l])) - - log_emu_helper.warn('_'*10) - for f in machine.func_loaded: - log_emu_helper.warn("%.8X %s"%(f, machine.func_loaded[f])) - - -def emul_malloc(machine, env): - my_esp = machine.get_reg(esp) - pool_type =env.get_d(my_esp+0x4) - alloc_size =env.get_d(my_esp+0x8) - tag =env.get_d(my_esp+0xc) - - machine.eval_instr(ret(ExprInt(uint32(0xc)))) - my_eip = machine.eval_expr(machine.pool[eip], {}) - del machine.pool[eip] - - ret_alloc_ad = machine.malloc_next_ad - m_data = mempool(machine.malloc_next_ad, machine.malloc_next_ad+alloc_size, 'RW', name = "malloc %.8X"%alloc_size) - machine.malloc_next_ad += ((alloc_size+0xFFF)&(~0xFFF)) - - log.warn('alloc(%X) tag %X poolt %X from %X esp %X ret %X:'%(int(alloc_size), int(tag), int(pool_type), int(my_eip), int(my_esp), int(machine.malloc_next_ad))) - machine.eval_instr(mov(eax, ExprInt(uint32(ret_alloc_ad)))) - - env.mems.append(m_data) - log.warn(str(env)) - return my_eip - -def emul_free(machine, env): - my_esp = machine.get_reg(esp) - address_free =env.get_d(my_esp+4) - - machine.eval_instr(ret(ExprInt(uint32(4)))) - my_eip = machine.eval_expr(machine.pool[eip], {}) - del machine.pool[eip] - - log.warn('free(%X) from %X esp %X:'%(int(address_free), int(my_eip), int(my_esp))) - - if address_free !=0: - m = env.get_mem_pool(address_free) - if not m: - raise 'cannot find freeing mem!' - env.mems.remove(m) - log.warn(str(env)) - return my_eip - - -def emul_pitfall(machine, env): - raise 'func not impl!' - - -def emul_heapcreate(machine, env): - my_esp = machine.get_reg(esp) - floptions =env.get_d(my_esp+4) - dwinitialsize =env.get_d(my_esp+8) - dwmaximumsize =env.get_d(my_esp+12) - - machine.eval_instr(ret(ExprInt(uint32(12)))) - my_eip = machine.eval_expr(machine.pool[eip], {}) - del machine.pool[eip] - - - log.warn('heapcreate(%X %X %X) from %X esp %X ret %X:'%(floptions, dwinitialsize, dwmaximumsize, int(my_eip), my_esp, 0xdeadcafe)) - machine.eval_instr(mov(eax, ExprInt(uint32(0xdeadcafe)))) - - return my_eip - -def emul_heapalloc(machine, env): - my_esp = machine.get_reg(esp) - hheap =env.get_d(my_esp+4) - dwflags =env.get_d(my_esp+8) - alloc_size =env.get_d(my_esp+12) - - machine.eval_instr(ret(ExprInt(uint32(12)))) - my_eip = machine.eval_expr(machine.pool[eip], {}) - del machine.pool[eip] - - ret_alloc_ad = machine.malloc_next_ad - m_data = mempool(machine.malloc_next_ad, machine.malloc_next_ad+alloc_size, 'RW', name = "heapalloc %.8X"%alloc_size) - machine.malloc_next_ad += ((alloc_size+0xFFF)&(~0xFFF)) - - log.warn('heapalloc(%X %X %X) from %X esp %X ret %X:'%(hheap, dwflags, alloc_size, int(my_eip), my_esp, machine.malloc_next_ad)) - machine.eval_instr(mov(eax, ExprInt(uint32(ret_alloc_ad)))) - - env.mems.append(m_data) - log.warn(str(env)) - return my_eip - -#VirtualProtect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect) -def emul_virtualprotect(machine, env): - my_esp = machine.eval_expr(machine.pool[esp], {}) - lpaddress = env.get_d(my_esp+4) - dwsize = env.get_d(my_esp+8) - flnewprotect = env.get_d(my_esp+12) - lpfloldprotect = env.get_d(my_esp+16) - - #XXX return 1?? - machine.eval_instr(mov(eax, ExprInt(uint32(1)))) - - log.info("emul virtualprotect %X, %X %X %X"%(lpaddress, dwsize, flnewprotect, lpfloldprotect)) - machine.eval_instr(ret(ExprInt(uint32(16)))) - #dump_pool(machine.pool) - my_eip = machine.eval_expr(machine.pool[eip], {}) - del machine.pool[eip] - return my_eip - -def emul_virtualalloc(machine, env): - my_esp = machine.get_reg(esp) - lpaddress =env.get_d(my_esp+4) - alloc_size =env.get_d(my_esp+8) - flallocationtype =env.get_d(my_esp+12) - flprotect =env.get_d(my_esp+16) - - machine.eval_instr(ret(ExprInt(uint32(16)))) - my_eip = machine.eval_expr(machine.pool[eip], {}) - del machine.pool[eip] - - ret_alloc_ad = machine.malloc_next_ad - m_data = mempool(machine.malloc_next_ad, machine.malloc_next_ad+alloc_size, 'RW', name = "virtualalloc %.8X"%alloc_size) - machine.malloc_next_ad += ((alloc_size+0xFFF)&(~0xFFF)) - - log.warn('virtualalloc(%X %X %X %X) from %X esp %X ret %X:'%(lpaddress, alloc_size, flallocationtype, flprotect, int(my_eip), my_esp, machine.malloc_next_ad)) - machine.eval_instr(mov(eax, ExprInt(uint32(ret_alloc_ad)))) - - env.mems.append(m_data) - log.warn(str(env)) - return my_eip - - -def emul_virtualfree(machine, env): - my_esp = machine.get_reg(esp) - address_free =env.get_d(my_esp+4) - dwsize =env.get_d(my_esp+8) - dwfreetype =env.get_d(my_esp+12) - - - - machine.eval_instr(ret(ExprInt(uint32(12)))) - my_eip = machine.eval_expr(machine.pool[eip], {}) - del machine.pool[eip] - - log.warn('virtualfree(%X %X %X) from %X esp %X:'%(address_free, dwsize, swfreetype, int(my_eip), my_esp)) - - if address_free !=0: - m = env.get_mem_pool(address_free) - if not m: - raise 'cannot find freeing mem!' - env.mems.remove(m) - log.warn(str(env)) - return my_eip - - - -def emul_getmodulehandlea(machine, env): - my_esp = machine.eval_expr(machine.pool[esp], {}) - libname_ad = env.get_d(my_esp+4) - libname = "" - l = 0 - while True: - libname+=chr(env.get_b(libname_ad+l)) - l+=1 - if libname[-1]=='\x00': - break - - - machine.eval_instr(ret(ExprInt(uint32(4)))) - my_eip = machine.eval_expr(machine.pool[eip], {}) - del machine.pool[eip] - - - log.info("emul loadlib (%X), %s from %X"%(libname_ad, libname, my_eip)) - - if False:#libname.startswith("kernel32.dll"): - machine.eval_instr(mov(eax, ExprInt(uint32(0x7C800000)))) - else: - machine.eval_instr(mov(eax, ExprInt(uint32(0x0)))) - log.warn("unknown lib: %s"%str(libname)) - - log.warn(str(env)) - - return my_eip - -def emul_kddisabledebugger(machine, env): - my_esp = machine.get_reg(esp) - - machine.eval_instr(ret()) - my_eip = machine.eval_expr(machine.pool[eip], {}) - del machine.pool[eip] - - - log.warn('emul_kddisabledebugger from %X esp %X '%(int(my_eip), int(my_esp))) - machine.eval_instr(mov(eax, ExprInt(uint32(0)))) - - log.warn(str(env)) - return my_eip - - - -def sav_machine(machine, env, my_eip, snap_fmt_name): - - print 'SAVE**************tsc: %.10d***************'%machine.pool[tsc1].arg - machine.pool[eip] = my_eip - env_s = StringIO.StringIO() - env.to_file(env_s) - env_s.flush() - fname = snap_fmt_name+".env" - open(fname%(machine.pool[tsc1].arg), 'wb').write(zlib.compress(env_s.getvalue(), 9)) - machine_s = StringIO.StringIO() - machine.to_file(machine_s) - machine_s.flush() - fname = snap_fmt_name+".machine" - open(fname%(machine.pool[tsc1].arg), 'wb').write(zlib.compress(machine_s.getvalue(), 9)) - del machine.pool[eip] - - -def load_machine(snap_fmt_name, step): - - fname = snap_fmt_name+".env" - env_s = StringIO.StringIO(zlib.decompress(open(fname%step, 'rb').read())) - env = mempool_manager.from_file(env_s) - fname = snap_fmt_name+".machine" - machine_s = StringIO.StringIO(zlib.decompress(open(fname%step, 'rb').read())) - machine = eval_int.from_file(machine_s, globals()) - my_eip = machine.pool[eip] - del machine.pool[eip] - print 'LOAD**************tsc: %.10X***************'%machine.pool[tsc1].arg - print "machine eip: %.8X"%int(my_eip.arg) - - return machine, env, my_eip - -def emul_full_expr(e, l, my_eip, env, machine): - if ((not 0xF2 in l.prefix) and (not 0xF3 in l.prefix)) or \ - not l.m.name[:-1] in ["ins", "outs", "movs", "lods", "stos", "cmps", "scas"]: - my_eip, mem_dst = emul_expr(machine, e, my_eip) - else: - #rep mnemo - #XXX HACK 16 bit - if 0x66 in l.prefix and l.m.name[-1]== "d": - raise "not impl 16 bit string" - zf_w = zf in reduce(lambda x,y:x+y, [list(x.get_w()) for x in e], []) - - while True: - - my_ecx = machine.eval_expr(machine.pool[ecx], {}) - if not isinstance(my_ecx, ExprInt):# in tab_int_size:#[int, long]: - raise "cannot eval counter....", str(machine.pool[ecx]) - if l.mnemo_mode== u16: - my_ecx.arg&=0xFFFF - if my_ecx.arg ==0: - break - - my_esi = machine.eval_expr(machine.pool[esi], {}) - my_edi = machine.eval_expr(machine.pool[edi], {}) - tmp,mem_dst = emul_expr(machine, e, my_eip) - - info = l.opmode, l.admode - machine.eval_instr(mov(info, ecx, ExprOp('-', my_ecx, ExprInt(uint32(1))))) - machine.eval_expr(machine.pool[ecx], {}) - - if zf_w : - my_zf = machine.eval_expr(machine.pool[zf], {}) - if 0xF3 in l.prefix and my_zf == 0: - break - if 0xF2 in l.prefix and my_zf == 1: - break - - machine.pool[tsc1].arg+=uint32(1) - - return my_eip, mem_dst - - -def guess_func_destack(all_bloc): - ret_destack = None - for b in all_bloc: - l = b.lines[-1] - if not l.m.name.startswith('ret'): - continue - if len(l.arg) == 0: - a = 0 - elif len(l.arg) ==1: - a = l.arg[0][x86_afs.imm] - else: - continue - if ret_destack!=None: - if a != ret_destack: - print 'found diff ret unstack', ret_destack, a - return None, None - else: - continue - ret_destack = a - - - if ret_destack !=None: - return True, ret_destack - - #try func wrapper - if len(all_bloc)!= 1: - return None, None - l = all_bloc[0].lines[-1] - if not l.m.name.startswith('jmp') or len(l.arg) !=1: - return None, None - - a = l.arg[0] - print hex(l.offset), a, type(a) - - if not x86_afs.imm in a or not x86_afs.ad in a or not a[x86_afs.ad]: - return None, None - - return False, a[x86_afs.imm] - - -def digest_allbloc_instr(all_bloc, segm_to_do = set()): - instrs = {} - """ - g = asmbloc.bloc2graph(all_bloc) - open("graph_b.txt" , "w").write(g) - """ - - #test duplicated blocs - unik_blobs = {} - for b in all_bloc: - if not b.label in unik_blobs: - unik_blobs[b.label] = [] - unik_blobs[b.label].append(b) - - for lbl, blcs in unik_blobs.items(): - if len(blcs) ==1: - continue - tmp = blcs.pop() - for b in blcs: - if str(tmp) != str(b): - print tmp - print b - raise ValueError('diff bloc in same label') - all_bloc.remove(b) - - for b in all_bloc: - for l in b.lines: - if l.offset in instrs: - log.warn(('zarb: dup instr', (hex(l.offset), str(l)))) - if str(instrs[l.offset][0]) != str(l): - raise ValueError('dup instr@ with different instr', (str(l), str(instrs[l.offset][0]))) - args = [] - ex = get_instr_expr(l, ExprInt(uint32(l.offset+l.l)), args, segm_to_do = segm_to_do) - - - instrs[l.offset] = (l, ex) - return instrs - - -def x86_machine(mem_read_wrap = None, mem_write_wrap = None): - 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 : init_zf, nf : init_nf, pf : init_pf, - of : init_of, cf : init_cf, tf : init_tf, - i_f: init_i_f, df : init_df, af : init_af, - iopl: init_iopl, nt : init_nt, rf : init_rf, - vm : init_vm, ac : init_ac, vif: init_vif, - vip: init_vip, i_d: init_i_d,tsc1: init_tsc1, - tsc2: init_tsc2, - dr7:ExprInt(uint32(0)), - cr0:init_cr0, - #my_ret_addr:my_ret_addri - - }, - mem_read_wrap, - mem_write_wrap, - - ) - return machine - diff --git a/miasm/tools/emul_lib/__init__.py b/miasm/tools/emul_lib/__init__.py deleted file mode 100644 index fbabaacf..00000000 --- a/miasm/tools/emul_lib/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python -# -# Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# diff --git a/miasm/tools/emul_lib/libcodenat.c b/miasm/tools/emul_lib/libcodenat.c deleted file mode 100644 index 2030c66a..00000000 --- a/miasm/tools/emul_lib/libcodenat.c +++ /dev/null @@ -1,1639 +0,0 @@ -/* -** Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License along -** with this program; if not, write to the Free Software Foundation, Inc., -** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -//#include <Python.h> - -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <string.h> - -#include <stdint.h> -#include <inttypes.h> -#include <math.h> - -#include "queue.h" -#include "libcodenat.h" - - - - - -struct memory_page_list_head memory_page_pool; -struct code_bloc_list_head code_bloc_pool; - -struct memory_breakpoint_info_head memory_breakpoint_pool; - -vm_cpu_t vmcpu; - -/****************memory manager**************/ - -unsigned int min_page_ad = 0x22000000; - -extern unsigned int *code_addr_tab; - - -unsigned int code_bloc_pool_ad_min; -unsigned int code_bloc_pool_ad_max; - -#define MAX_MEMORY_PAGE_POOL_TAB 0x100000 -#define MEMORY_PAGE_POOL_MASK_BIT 12 -#define PAGE_SIZE (1<<MEMORY_PAGE_POOL_MASK_BIT) -struct memory_page_node *memory_page_pool_tab[MAX_MEMORY_PAGE_POOL_TAB]; - - -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define MAX(a,b) (((a)>(b))?(a):(b)) - - -//#define DEBUG_MIASM_AUTOMOD_CODE - - - - - - - - -int is_mem_mapped(uint64_t ad) -{ - struct memory_page_node * mpn; - - mpn = memory_page_pool_tab[ad>>MEMORY_PAGE_POOL_MASK_BIT]; - if ( mpn && (mpn->ad <= ad) && (ad < mpn->ad + mpn->size)) - return 1; - return 0; -} - - -/* return the address base of the memory page - containing addr -*/ -uint64_t get_mem_base_addr(uint64_t ad, uint64_t *addr_base) -{ - struct memory_page_node * mpn; - - mpn = memory_page_pool_tab[ad>>MEMORY_PAGE_POOL_MASK_BIT]; - if ( mpn && (mpn->ad <= ad) && (ad < mpn->ad + mpn->size)){ - *addr_base = mpn->ad; - return 1; - } - return 0; -} - - -void dump_gpregs(void) -{ - printf("eip %.8X eax %.8X ebx %.8X ecx %.8X edx %.8X\n", - vmcpu.eip, vmcpu.eax, vmcpu.ebx, vmcpu.ecx, vmcpu.edx); - printf("esi %.8X edi %.8X esp %.8X ebp %.8X\nmy_tick %X\n", - vmcpu.esi, vmcpu.edi, vmcpu.esp, vmcpu.ebp, - vmcpu.my_tick); -} - -struct memory_page_node * get_memory_page_from_address(uint64_t ad) -{ - struct memory_page_node * mpn; -#if 1 - mpn = memory_page_pool_tab[ad>>MEMORY_PAGE_POOL_MASK_BIT]; - if ( mpn && (mpn->ad <= ad) && (ad < mpn->ad + mpn->size)) - return mpn; - - fprintf(stderr, "WARNING: address 0x%"PRIX64" is not mapped in virtual memory:\n", ad); - //dump_memory_page_pool(); - //dump_gpregs(); - //exit(-1); - vmcpu.vm_exception_flags |= EXCEPT_ACCESS_VIOL; - - return NULL; -#else - - //printf("search for page ad: %X\n", ad); - LIST_FOREACH(mpn, &memory_page_pool, next){ - if ((mpn->ad <= ad) && (ad < mpn->ad + mpn->size)) - return mpn; - } - fprintf(stderr, "address %"PRIX64" is not mapped in virtual memory \n", ad); - dump_memory_page_pool(); - dump_gpregs(); - //exit(-1); - vmcpu.vm_exception_flags |= EXCEPT_ACCESS_VIOL; - return NULL; -#endif -} - - - - -static inline uint64_t memory_page_read(unsigned int my_size, uint64_t ad) -{ - struct memory_page_node * mpn; - unsigned char * addr; - uint64_t ret = 0; - struct memory_breakpoint_info * b; - - - mpn = get_memory_page_from_address(ad); - if (!mpn) - return 0; - - if ((mpn->access & PAGE_READ) == 0){ - fprintf(stderr, "access to non readable page!! %"PRIX64"\n", ad); - vmcpu.vm_exception_flags |= EXCEPT_ACCESS_VIOL; - return 0; - } - - /* check read breakpoint*/ - LIST_FOREACH(b, &memory_breakpoint_pool, next){ - if ((b->access & BREAKPOINT_READ) == 0) - continue; - if (b->ad == ad) - vmcpu.vm_exception_flags |= EXCEPT_BREAKPOINT_INTERN; - } - - - addr = &((unsigned char*)mpn->ad_hp)[ad - mpn->ad]; - - /* read fits in a page */ - if (ad - mpn->ad + my_size/8 <= mpn->size){ - switch(my_size){ - case 8: - ret = *((unsigned char*)addr)&0xFF; - break; - case 16: - ret = *((unsigned short*)addr)&0xFFFF; - ret = Endian16_Swap(ret); - break; - case 32: - ret = *((unsigned int*)addr)&0xFFFFFFFF; - ret = Endian32_Swap(ret); - break; - case 64: - ret = *((uint64_t*)addr)&0xFFFFFFFFFFFFFFFFULL; - ret = Endian64_Swap(ret); - break; - default: - exit(0); - break; - } - } - /* read is multiple page wide */ - else{ - unsigned int new_size = my_size; - int index = 0; - fprintf(stderr, "read multiple page! %"PRIX64" %d\n", ad, new_size); - dump_memory_page_pool(); - while (new_size){ - mpn = get_memory_page_from_address(ad); - if (!mpn) - return 0; - addr = &((unsigned char*)mpn->ad_hp)[ad - mpn->ad]; - ret |= (*((unsigned char*)addr)&0xFF)<<(index); - index +=8; - new_size -= 8; - ad ++; - } - switch(my_size){ - case 8: - ret = ret; - break; - case 16: - ret = Endian16_Swap(ret); - break; - case 32: - ret = Endian32_Swap(ret); - break; - case 64: - ret = Endian64_Swap(ret); - break; - default: - exit(0); - break; - } - } - return ret; -} - -static inline void memory_page_write(unsigned int my_size, - uint64_t ad, uint64_t src) -{ - struct memory_page_node * mpn; - unsigned char * addr; - struct memory_breakpoint_info * b; - - mpn = get_memory_page_from_address(ad); - if (!mpn) - return; - - if ((mpn->access & PAGE_WRITE) == 0){ - fprintf(stderr, "access to non writable page!! %"PRIX64"\n", ad); - vmcpu.vm_exception_flags |= EXCEPT_ACCESS_VIOL; - return ; - } - - /* check read breakpoint*/ - LIST_FOREACH(b, &memory_breakpoint_pool, next){ - if ((b->access & BREAKPOINT_WRITE) == 0) - continue; - if (b->ad == ad) - vmcpu.vm_exception_flags |= EXCEPT_BREAKPOINT_INTERN; - } - - addr = &((unsigned char*)mpn->ad_hp)[ad - mpn->ad]; - - /* write fits in a page */ - if (ad - mpn->ad + my_size/8 <= mpn->size){ - switch(my_size){ - case 8: - *((unsigned char*)addr) = src&0xFF; - break; - case 16: - src = Endian16_Swap(src); - *((unsigned short*)addr) = src&0xFFFF; - break; - case 32: - src = Endian32_Swap(src); - *((unsigned int*)addr) = src&0xFFFFFFFF; - break; - case 64: - src = Endian64_Swap(src); - *((uint64_t*)addr) = src&0xFFFFFFFFFFFFFFFFULL; - break; - default: - exit(0); - break; - } - } - /* write is multiple page wide */ - else{ - fprintf(stderr, "write multiple page! %"PRIX64" %d\n", ad, my_size); - dump_memory_page_pool(); - switch(my_size){ - - case 8: - src = src; - break; - case 16: - src = Endian16_Swap(src); - break; - case 32: - src = Endian32_Swap(src); - break; - case 64: - src = Endian64_Swap(src); - break; - default: - exit(0); - break; - } - while (my_size){ - mpn = get_memory_page_from_address(ad); - if (!mpn) - return; - - addr = &((unsigned char*)mpn->ad_hp)[ad - mpn->ad]; - *((unsigned char*)addr) = src&0xFF; - my_size -= 8; - src >>=8; - ad ++; - } - } -} - - - -inline void check_write_code_bloc(unsigned int my_size, uint64_t addr) -{ - struct code_bloc_node * cbp; - vmcpu.vm_last_write_ad = addr; - vmcpu.vm_last_write_size = my_size; - - //if(vmcpu.my_tick> my_tick) - // printf("M_WRITE %2d %.8X %.8X\n", my_size, addr, src); - if (!(addr + my_size/8 <= code_bloc_pool_ad_min || - addr >=code_bloc_pool_ad_max)){ - LIST_FOREACH(cbp, &code_bloc_pool, next){ - if ((cbp->ad_start <= addr + my_size/8) && - (addr < cbp->ad_stop)){ -#ifdef DEBUG_MIASM_AUTOMOD_CODE - fprintf(stderr, "self modifying code %"PRIX64" %.8X", - addr, my_size); - fprintf(stderr, " from approx %X\n", vmcpu.eip); -#endif - vmcpu.vm_exception_flags |= EXCEPT_CODE_AUTOMOD; - break; - } - } - } -} - -void MEM_WRITE(unsigned int my_size, uint64_t addr, unsigned int src) -{ - struct code_bloc_node * cbp; - - vmcpu.vm_last_write_ad = addr; - vmcpu.vm_last_write_size = my_size; - - //if(vmcpu.my_tick> my_tick) - // printf("M_WRITE %2d %.8X %.8X\n", my_size, addr, src); - if (!(addr + my_size/8 <= code_bloc_pool_ad_min || - addr >=code_bloc_pool_ad_max)){ - LIST_FOREACH(cbp, &code_bloc_pool, next){ - if ((cbp->ad_start <= addr + my_size/8) && - (addr < cbp->ad_stop)){ -#ifdef DEBUG_MIASM_AUTOMOD_CODE - fprintf(stderr, "self modifying code %"PRIX64" %.8X", - addr, my_size); - fprintf(stderr, " from approx %X\n", vmcpu.eip); -#endif - vmcpu.vm_exception_flags |= EXCEPT_CODE_AUTOMOD; - break; - } - } - } - - memory_page_write(my_size, addr, src); -} - -void MEM_WRITE_08(uint64_t addr, unsigned char src) -{ - check_write_code_bloc(8, addr); - memory_page_write(8, addr, src); -} - -void MEM_WRITE_08_SEGM(uint16_t segm, uint64_t addr, unsigned char src) -{ - check_write_code_bloc(8, addr + vmcpu.segm_base[segm]); - memory_page_write(8, addr + vmcpu.segm_base[segm], src); -} - -void MEM_WRITE_16(uint64_t addr, unsigned short src) -{ - check_write_code_bloc(16, addr); - memory_page_write(16, addr, src); -} - -void MEM_WRITE_16_SEGM(uint16_t segm, uint64_t addr, unsigned short src) -{ - check_write_code_bloc(16, addr + vmcpu.segm_base[segm]); - memory_page_write(16, addr + vmcpu.segm_base[segm], src); -} - -void MEM_WRITE_32(uint64_t addr, unsigned int src) -{ - check_write_code_bloc(32, addr); - memory_page_write(32, addr, src); -} - -void MEM_WRITE_32_SEGM(uint16_t segm, uint64_t addr, unsigned int src) -{ - check_write_code_bloc(32, addr + vmcpu.segm_base[segm]); - memory_page_write(32, addr + vmcpu.segm_base[segm], src); -} - -void MEM_WRITE_64(uint64_t addr, uint64_t src) -{ - check_write_code_bloc(64, addr); - memory_page_write(64, addr, src); -} - -void MEM_WRITE_64_SEGM(uint16_t segm, uint64_t addr, uint64_t src) -{ - check_write_code_bloc(64, addr + vmcpu.segm_base[segm]); - memory_page_write(64, addr + vmcpu.segm_base[segm], src); -} - - -unsigned int MEM_LOOKUP(unsigned int my_size, uint64_t addr) -{ - unsigned int ret; - ret = memory_page_read(my_size, addr); - return ret; -} - -unsigned char MEM_LOOKUP_08(uint64_t addr) -{ - unsigned char ret; - ret = memory_page_read(8, addr); - return ret; -} - -unsigned char MEM_LOOKUP_08_SEGM(uint16_t segm, uint64_t addr) -{ - unsigned char ret; - ret = memory_page_read(8, addr + vmcpu.segm_base[segm]); - return ret; -} - -unsigned short MEM_LOOKUP_16(uint64_t addr) -{ - unsigned short ret; - ret = memory_page_read(16, addr); - return ret; -} - -unsigned short MEM_LOOKUP_16_SEGM(uint16_t segm, uint64_t addr) -{ - unsigned short ret; - ret = memory_page_read(16, addr + vmcpu.segm_base[segm]); - return ret; -} - -unsigned int MEM_LOOKUP_32(uint64_t addr) -{ - unsigned int ret; - ret = memory_page_read(32, addr); - return ret; -} - -unsigned int MEM_LOOKUP_32_SEGM(uint16_t segm, uint64_t addr) -{ - unsigned int ret; - ret = memory_page_read(32, addr + vmcpu.segm_base[segm]); - return ret; -} - -uint64_t MEM_LOOKUP_64(uint64_t addr) -{ - uint64_t ret; - ret = memory_page_read(64, addr); - return ret; -} - -uint64_t MEM_LOOKUP_64_SEGM(uint16_t segm, uint64_t addr) -{ - uint64_t ret; - ret = memory_page_read(64, addr + vmcpu.segm_base[segm]); - return ret; -} - -void vm_throw(unsigned long flags) -{ - vmcpu.vm_exception_flags |= flags; -} - -inline unsigned int parity(unsigned int a) -{ - unsigned int tmp, cpt; - - tmp = a&0xFF; - cpt = 1; - while (tmp!=0){ - cpt^=tmp&1; - tmp>>=1; - } - return cpt; -} - - -int shift_right_arith(unsigned int size, int a, unsigned int b) -{ - int i32_a; - short i16_a; - char i8_a; - switch(size){ - case 8: - i8_a = a; - return (i8_a >> b)&0xff; - case 16: - i16_a = a; - return (i16_a >> b)&0xffff; - case 32: - i32_a = a; - return (i32_a >> b)&0xffffffff; - default: - fprintf(stderr, "inv size in shift %d\n", size); - exit(0); - } -} -/* -int shift_right_arith_08(int a, unsigned int b) -{ - char i8_a; - i8_a = a; - return (i8_a >> b)&0xff; -} - -int shift_right_arith_16(int a, unsigned int b) -{ - short i16_a; - i16_a = a; - return (i16_a >> b)&0xffff; -} - -int shift_right_arith_32(int a, unsigned int b) -{ - int i32_a; - i32_a = a; - return (i32_a >> b)&0xffffffff; -} -*/ -unsigned int shift_right_logic(unsigned int size, - unsigned int a, unsigned int b) -{ - unsigned int u32_a; - unsigned short u16_a; - unsigned char u8_a; - switch(size){ - case 8: - u8_a = a; - return (u8_a >> b)&0xff; - case 16: - u16_a = a; - return (u16_a >> b)&0xffff; - case 32: - u32_a = a; - return (u32_a >> b)&0xffffffff; - default: - fprintf(stderr, "inv size in shift %d\n", size); - exit(0); - } -} -/* -int shift_right_logic_08(unsigned int a, unsigned int b) -{ - unsigned char u8_a; - u8_a = a; - return (u8_a >> b)&0xff; -} - -int shift_right_logic_16(unsigned int a, unsigned int b) -{ - unsigned short u16_a; - u16_a = a; - return (u16_a >> b)&0xffff; -} - -int shift_right_logic_32(unsigned int a, unsigned int b) -{ - unsigned int u32_a; - u32_a = a; - return (u32_a >> b)&0xffffffff; -} -*/ -int shift_left_logic(unsigned int size, unsigned int a, unsigned int b) -{ - switch(size){ - case 8: - return (a<<b)&0xff; - case 16: - return (a<<b)&0xffff; - case 32: - return (a<<b)&0xffffffff; - default: - fprintf(stderr, "inv size in shift %d\n", size); - exit(0); - } -} -/* -int shift_left_logic_O8(unsigned int a, unsigned int b) -{ - return (a<<b)&0xff; -} - -int shift_left_logic_16(unsigned int a, unsigned int b) -{ - return (a<<b)&0xffff; -} - -int shift_left_logic_32(unsigned int a, unsigned int b) -{ - return (a<<b)&0xffffffff; -} -*/ - -unsigned int mul_lo_op(unsigned int size, unsigned int a, unsigned int b) -{ - unsigned int mask; - - switch (size) { - case 8: mask = 0xff; break; - case 16: mask = 0xffff; break; - case 32: mask = 0xffffffff; break; - default: fprintf(stderr, "inv size in mul %d\n", size); exit(0); - } - - a &= mask; - b &= mask; - return ((int64_t)a * (int64_t) b) & mask; -} - -unsigned int mul_hi_op(unsigned int size, unsigned int a, unsigned int b) -{ - uint64_t res = 0; - unsigned int mask; - - switch (size) { - case 8: mask = 0xff; break; - case 16: mask = 0xffff; break; - case 32: mask = 0xffffffff; break; - default: fprintf(stderr, "inv size in mul %d\n", size); exit(0); - } - - a &= mask; - b &= mask; - res = ((uint64_t)a * (uint64_t)b); - return (res >> 32) & mask; -} - - -unsigned int imul_lo_op_08(char a, char b) -{ - return a*b; -} - -unsigned int imul_lo_op_16(short a, short b) -{ - return a*b; -} - -unsigned int imul_lo_op_32(int a, int b) -{ - return a*b; -} - -int imul_hi_op_08(char a, char b) -{ - int64_t res = 0; - res = a*b; - return res>>8; -} - -int imul_hi_op_16(short a, short b) -{ - int64_t res = 0; - res = a*b; - return res>>16; -} - -int imul_hi_op_32(int a, int b) -{ - int64_t res = 0; - res = (int64_t)a*(int64_t)b; - //printf("%x %x dd %"PRIx64"\n", a, b, res); - return res>>32ULL; -} - -unsigned int umul16_lo(unsigned short a, unsigned short b) -{ - return (a*b) & 0xffff; -} - -unsigned int umul16_hi(unsigned short a, unsigned short b) -{ - uint32_t c; - c = a*b; - return (c>>16) & 0xffff; -} - - - - -unsigned int div_op(unsigned int size, unsigned int a, unsigned int b, unsigned int c) -{ - int64_t num; - if (c == 0) - { - vmcpu.vm_exception_flags |= EXCEPT_INT_DIV_BY_ZERO; - return 0; - } - num = ((int64_t)a << size) + b; - num/=(int64_t)c; - return num; -} - -unsigned int rem_op(unsigned int size, unsigned int a, unsigned int b, unsigned int c) -{ - int64_t num; - - if (c == 0) - { - vmcpu.vm_exception_flags |= EXCEPT_INT_DIV_BY_ZERO; - return 0; - } - - num = ((int64_t)a << size) + b; - num = (int64_t)num-c*(num/c); - return num; -} - - -int rot_left(unsigned int size, unsigned int a, unsigned int b) -{ - unsigned int tmp; - - b = b&0x1F; - b %= size; - switch(size){ - case 8: - tmp = (a << b) | ((a&0xFF) >> (size-b)); - return tmp&0xff; - case 16: - tmp = (a << b) | ((a&0xFFFF) >> (size-b)); - return tmp&0xffff; - case 32: - tmp = (a << b) | ((a&0xFFFFFFFF) >> (size-b)); - return tmp&0xffffffff; - default: - fprintf(stderr, "inv size in rotleft %d\n", size); - exit(0); - } -} - -int rot_right(unsigned int size, unsigned int a, unsigned int b) -{ - unsigned int tmp; - - b = b&0x1F; - b %= size; - switch(size){ - case 8: - tmp = ((a&0xFF) >> b) | (a << (size-b)); - return tmp&0xff; - case 16: - tmp = ((a&0xFFFF) >> b) | (a << (size-b)); - return tmp&0xffff; - case 32: - tmp = ((a&0xFFFFFFFF) >> b) | (a << (size-b)); - return tmp&0xffffffff; - default: - fprintf(stderr, "inv size in rotleft %d\n", size); - exit(0); - } -} - - -int rcl_rez_op(unsigned int size, unsigned int a, unsigned int b, unsigned int cf) -{ - uint64_t tmp; - - - size++; - b %= size; - - if (b == 0) { - switch(size){ - case 8+1: - return a&0xff; - case 16+1: - return a&0xffff; - case 32+1: - return a&0xffffffff; - default: - fprintf(stderr, "inv size in rclleft %d\n", size); - exit(0); - } - } - - tmp = (a<<1) | cf; - b -=1; - switch(size){ - case 8+1: - tmp = (tmp << b) | ((tmp&0x1FF) >> (size-b)); - return tmp&0xff; - case 16+1: - tmp = (tmp << b) | ((tmp&0x1FFFF) >> (size-b)); - return tmp&0xffff; - case 32+1: - tmp = (tmp << b) | ((tmp&0x1FFFFFFFFULL) >> (size-b)); - return tmp&0xffffffff; - default: - fprintf(stderr, "inv size in rclleft %d\n", size); - exit(0); - } -} - -int rcr_rez_op(unsigned int size, unsigned int a, unsigned int b, unsigned int cf) -{ - return rcl_rez_op(size, a, size+1-b, cf); - -} - - -int rcl_cf_op(unsigned int size, unsigned int a, unsigned int b, unsigned int cf) -{ - uint64_t tmp; - - tmp = (cf<< size) | a; - - size++; - b %= size; - - switch(size){ - case 8+1: - tmp = (tmp << b) | ((tmp&0x1FF) >> (size-b)); - return (tmp>>8)&1; - case 16+1: - tmp = (tmp << b) | ((tmp&0x1FFFF) >> (size-b)); - return (tmp>>16)&1; - case 32+1: - tmp = (tmp << b) | ((tmp&0x1FFFFFFFFULL) >> (size-b)); - return (tmp>>32)&1; - default: - fprintf(stderr, "inv size in rclleft %d\n", size); - exit(0); - } -} - -int rcr_cf_op(unsigned int size, unsigned int a, unsigned int b, unsigned int cf) -{ - return rcl_cf_op(size, a, size+1-b, cf); -} -unsigned int my_bsr(unsigned int a, unsigned int b) -{ - int i; - - for (i=31; i>=0; i--){ - if (b & (1<<i)) - return i; - } - return a; -} - -unsigned int my_bsf(unsigned int a, unsigned int b) -{ - int i; - - for (i=0; i<32; i++){ - if (b & (1<<i)) - return i; - } - return a; -} - - -unsigned int my_imul08(unsigned int a, unsigned int b) -{ - char a08, b08; - short a16; - - a08 = a&0xFF; - b08 = b&0xFF; - a16 = a08*b08; - return (int)a16; -} - - - -unsigned int cpuid(unsigned int a, unsigned int reg_num) -{ - if (reg_num >3){ - fprintf(stderr, "not implemented cpuid reg %x\n", reg_num); - exit(-1); - } - - if (a == 0){ - switch(reg_num){ - case 0: - return 0xa; - case 1: - return 0x756E6547; - case 2: - return 0x6C65746E; - case 3: - return 0x49656E69; - } - } - - else if (a == 1){ - switch(reg_num){ - case 0: - //return 0x000006FB; - return 0x00020652; - case 1: - //return 0x02040800; - return 0x00000800; - case 2: - //return 0x0004E3BD; - return 0x00000209; - case 3: - //return 0xBFEBFBFF; - return 0x078bf9ff; - } - } - else{ - fprintf(stderr, "WARNING not implemented cpuid index %X!\n", a); - //exit(-1); - } - return 0; -} - -#define DEBUG_MIASM_DOUBLE - - -void dump_float(void) -{ - printf("%e\n", vmcpu.float_st0); - printf("%e\n", vmcpu.float_st1); - printf("%e\n", vmcpu.float_st2); - printf("%e\n", vmcpu.float_st3); - printf("%e\n", vmcpu.float_st4); - printf("%e\n", vmcpu.float_st5); - printf("%e\n", vmcpu.float_st6); - printf("%e\n", vmcpu.float_st7); - -} - -double mem_32_to_double(unsigned int m) -{ - float f; - double d; - - f = *((float*)&m); - d = f; -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%d float %e\n", m, d); -#endif - return d; -} - - -double mem_64_to_double(uint64_t m) -{ - double d; - d = *((double*)&m); -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%"PRId64" double %e\n", m, d); -#endif - return d; -} - -double int_16_to_double(unsigned int m) -{ - double d; - - d = (double)(m&0xffff); -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%d double %e\n", m, d); -#endif - return d; -} - -double int_32_to_double(unsigned int m) -{ - double d; - - d = (double)m; -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%d double %e\n", m, d); -#endif - return d; -} - -double int_64_to_double(uint64_t m) -{ - double d; - - d = (double)m; -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%"PRId64" double %e\n", m, d); -#endif - return d; -} - -int double_to_int_32(double d) -{ - int i; - - i = (int)d; -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%e int %d\n", d, i); -#endif - return i; -} - -double fadd(double a, double b) -{ - double c; - c = a + b; -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%e + %e -> %e\n", a, b, c); -#endif - return c; -} - -double fsub(double a, double b) -{ - double c; - c = a - b; -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%e - %e -> %e\n", a, b, c); -#endif - return c; -} - -double fmul(double a, double b) -{ - double c; - c = a * b; -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%e * %e -> %e\n", a, b, c); -#endif - return c; -} - -double fdiv(double a, double b) -{ - double c; - c = a / b; -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%e / %e -> %e\n", a, b, c); -#endif - return c; -} - -double ftan(double a) -{ - double b; - b = tan(a); -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%e tan %e\n", a, b); -#endif - return b; -} - -double frndint(double a) -{ - int64_t b; - double c; - b = (int64_t)a; - c = (double)b; -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%e double %e\n", a, c); -#endif - return c; -} - -double fsin(double a) -{ - double b; - b = sin(a); -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%e sin %e\n", a, b); -#endif - return b; -} - -double fcos(double a) -{ - double b; - b = cos(a); -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%e cos %e\n", a, b); -#endif - return b; -} - - -double fscale(double a, double b) -{ - double c; - c = a * exp2(trunc(b)); -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%e *exp2 %e -> %e\n", a, b, c); -#endif - return c; -} - -double f2xm1(double a) -{ - double b; - b = exp2(a)-1; -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%e exp2 -1 %e\n", a, b); -#endif - return b; -} - -double fsqrt(double a) -{ - double b; - b = sqrt(a); -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%e sqrt %e\n", a, b); -#endif - return b; -} - -double fabs(double a) -{ - double b; - b = abs(a); -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%e abs %e\n", a, b); -#endif - return b; -} - - - -unsigned int fcom_c0(double a, double b) -{ - if (a>=b) - return 0; - return 1; -} -unsigned int fcom_c1(double a, double b) -{ - //XXX - return 0; -} -unsigned int fcom_c2(double a, double b) -{ - return 0; -} -unsigned int fcom_c3(double a, double b) -{ - if (a==b) - return 1; - return 0; -} - - -unsigned int double_to_mem_32(double d) -{ - unsigned int m; - float f; - f = d; - m = *((unsigned int*)&f); -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%d %e\n", m, d); -#endif - return m; -} - -uint64_t double_to_mem_64(double d) -{ - uint64_t m; - m = *((uint64_t*)&d); -#ifdef DEBUG_MIASM_DOUBLE - dump_float(); - printf("%"PRId64" %e\n", m, d); -#endif - return m; -} - -struct memory_page_node * create_memory_page_node(uint64_t ad, unsigned int size, unsigned int access) -{ - struct memory_page_node * mpn; - void* p; - - mpn = malloc(sizeof(*mpn)); - if (!mpn){ - fprintf(stderr, "cannot alloc mpn\n"); - return NULL; - } - p = malloc(size); - if (!p){ - fprintf(stderr, "cannot alloc %d\n", size); - return NULL; - } - mpn->ad = ad; - mpn->size = size; - mpn->access = access; - mpn->ad_hp = p; - - return mpn; -} - - -struct code_bloc_node * create_code_bloc_node(uint64_t ad_start, uint64_t ad_stop) -{ - struct code_bloc_node * cbp; - - cbp = malloc(sizeof(*cbp)); - if (!cbp){ - fprintf(stderr, "cannot alloc cbp\n"); - exit(-1); - } - - cbp->ad_start = ad_start; - cbp->ad_stop = ad_stop; - - return cbp; -} - - -void add_code_bloc(struct code_bloc_node* cbp) -{ - LIST_INSERT_HEAD(&code_bloc_pool, cbp, next); - if (code_bloc_pool_ad_min> cbp->ad_start) - code_bloc_pool_ad_min = cbp->ad_start; - if (code_bloc_pool_ad_max< cbp->ad_stop) - code_bloc_pool_ad_max = cbp->ad_stop; -} - -void dump_code_bloc_pool(void) -{ - struct code_bloc_node * cbp; - - LIST_FOREACH(cbp, &code_bloc_pool, next){ - printf("ad start %"PRIX64" ad_stop %"PRIX64"\n", - cbp->ad_start, - cbp->ad_stop); - } -} - - -void init_memory_page_pool(void) -{ - unsigned int i; - LIST_INIT(&memory_page_pool); - for (i=0;i<MAX_MEMORY_PAGE_POOL_TAB; i++) - memory_page_pool_tab[i] = NULL; -} - -void init_code_bloc_pool(void) -{ - LIST_INIT(&code_bloc_pool); - code_bloc_pool_ad_min = 0xffffffff; - code_bloc_pool_ad_max = 0; -} - -void init_memory_breakpoint(void) -{ - LIST_INIT(&memory_breakpoint_pool); -} - - -void reset_memory_page_pool(void) -{ - struct memory_page_node * mpn; - unsigned int i; - - while (!LIST_EMPTY(&memory_page_pool)) { - mpn = LIST_FIRST(&memory_page_pool); - LIST_REMOVE(mpn, next); - free(mpn->ad_hp); - free(mpn); - } - for (i=0;i<MAX_MEMORY_PAGE_POOL_TAB; i++) - memory_page_pool_tab[i] = NULL; - -} - - -void reset_code_bloc_pool(void) -{ - struct code_bloc_node * cbp; - - - while (!LIST_EMPTY(&code_bloc_pool)) { - cbp = LIST_FIRST(&code_bloc_pool); - LIST_REMOVE(cbp, next); - free(cbp); - } - code_bloc_pool_ad_min = 0xffffffff; - code_bloc_pool_ad_max = 0; -} - - -void reset_memory_breakpoint(void) -{ - struct memory_breakpoint_info * mpn; - - while (!LIST_EMPTY(&memory_breakpoint_pool)) { - mpn = LIST_FIRST(&memory_breakpoint_pool); - LIST_REMOVE(mpn, next); - free(mpn); - } - -} - - -int is_mpn_in_tab(struct memory_page_node* mpn_a) -{ - unsigned int i; - for (i=mpn_a->ad >> MEMORY_PAGE_POOL_MASK_BIT; - i<(mpn_a->ad + mpn_a->size + PAGE_SIZE - 1)>>MEMORY_PAGE_POOL_MASK_BIT; - i++){ - if (memory_page_pool_tab[i] !=NULL){ - return 1; - } - } - - return 0; -} - -void insert_mpn_in_tab(struct memory_page_node* mpn_a) -{ - unsigned int i; - for (i=mpn_a->ad >> MEMORY_PAGE_POOL_MASK_BIT; - i<(mpn_a->ad + mpn_a->size + PAGE_SIZE - 1)>>MEMORY_PAGE_POOL_MASK_BIT; - i++){ - if (memory_page_pool_tab[i] !=NULL){ - fprintf(stderr, "known page in tab\n"); - exit(1); - } - memory_page_pool_tab[i] = mpn_a; - } - -} - -void add_memory_page(struct memory_page_node* mpn_a) -{ - struct memory_page_node * mpn; - struct memory_page_node * lmpn; - - if (LIST_EMPTY(&memory_page_pool)){ - LIST_INSERT_HEAD(&memory_page_pool, mpn_a, next); - insert_mpn_in_tab(mpn_a); - return; - } - LIST_FOREACH(mpn, &memory_page_pool, next){ - lmpn = mpn; - if (mpn->ad < mpn_a->ad) - continue; - LIST_INSERT_BEFORE(mpn, mpn_a, next); - insert_mpn_in_tab(mpn_a); - return; - } - LIST_INSERT_AFTER(lmpn, mpn_a, next); - insert_mpn_in_tab(mpn_a); - -} - -void dump_memory_page_pool() -{ - struct memory_page_node * mpn; - - LIST_FOREACH(mpn, &memory_page_pool, next){ - printf("ad %"PRIX64" size %.8X %c%c%c hpad %p\n", - mpn->ad, - mpn->size, - mpn->access & PAGE_READ? 'R':'_', - mpn->access & PAGE_WRITE? 'W':'_', - mpn->access & PAGE_EXEC? 'X':'_', - mpn->ad_hp - ); - } -} - -void dump_memory_breakpoint_pool(void) -{ - struct memory_breakpoint_info * mpn; - - LIST_FOREACH(mpn, &memory_breakpoint_pool, next){ - printf("ad %"PRIX64" access %.8X\n", - mpn->ad, - mpn->access - ); - } -} - - -void add_memory_breakpoint(uint64_t ad, unsigned int access) -{ - struct memory_breakpoint_info * mpn_a; - mpn_a = malloc(sizeof(*mpn_a)); - if (!mpn_a) { - printf("cannot alloc\n"); - exit(0); - } - mpn_a->ad = ad; - mpn_a->access = access; - - LIST_INSERT_HEAD(&memory_breakpoint_pool, mpn_a, next); - -} - -void remove_memory_breakpoint(uint64_t ad, unsigned int access) -{ - struct memory_breakpoint_info * mpn; - - LIST_FOREACH(mpn, &memory_breakpoint_pool, next){ - if (mpn->ad == ad && mpn->access == access) - LIST_REMOVE(mpn, next); - } - -} - - - - - -unsigned int get_memory_page_max_address(void) -{ - struct memory_page_node * mpn; - uint64_t ad = 0; - - LIST_FOREACH(mpn, &memory_page_pool, next){ - if (ad < mpn->ad + mpn->size) - ad = mpn->ad + mpn->size; - } - return ad; -} - -unsigned int get_memory_page_max_user_address(void) -{ - struct memory_page_node * mpn; - uint64_t ad = 0; - - LIST_FOREACH(mpn, &memory_page_pool, next){ - if (ad < mpn->ad + mpn->size && - mpn->ad + mpn->size < 0x80000000) - ad = mpn->ad + mpn->size; - } - return ad; -} - - -unsigned int get_memory_page_next(unsigned int n_ad) -{ - struct memory_page_node * mpn; - uint64_t ad = 0; - - LIST_FOREACH(mpn, &memory_page_pool, next){ - if (mpn->ad < n_ad) - continue; - - if (ad == 0 || mpn->ad <ad) - ad = mpn->ad; - } - return ad; -} - - - -unsigned int get_memory_page_from_min_ad(unsigned int size) -{ - struct memory_page_node * mpn; - unsigned int c_ad ; - unsigned int min_ad = min_page_ad; - int end = 0; - /* first, find free min ad */ - while (!end){ - end = 1; - LIST_FOREACH(mpn, &memory_page_pool, next){ - c_ad = (mpn->ad + mpn->size+0x1000)&0xfffff000; - if (c_ad <= min_ad) - continue; - if (mpn->ad <= min_ad){ - min_ad = c_ad; - end = 0; - break; - } - if (mpn->ad - min_ad < size){ - min_ad = c_ad; - end = 0; - break; - } - } - } - return min_ad; - } - - - - -/********************************************/ - -void hexdump(char* m, unsigned int l) -{ - int i, j, last; - last = 0; - for (i=0;i<l;i++){ - if (!(i%0x10) && i){ - last = i; - printf(" "); - for (j=-0x10;j<0;j++){ - if (isprint(m[i+j])){ - printf("%c", m[i+j]); - } - else{ - printf("."); - } - } - printf("\n"); - } - printf("%.2X ", m[i]&0xFF); - } - l-=last; - if (l){ - for (j=i;j<last+0x10;j++) - printf(" "); - printf(" "); - for (j = 0;l;j++){ - if (isprint(m[last+j])){ - printf("%c", m[last+j]); - } - else{ - printf("."); - } - l--; - } - } - printf("\n"); - -} - - - - - -void _vm_init_regs() -{ - vmcpu.eax = vmcpu.ebx = vmcpu.ecx = vmcpu.edx = 0; - vmcpu.esi = vmcpu.edi = vmcpu.esp = vmcpu.ebp = 0; - vmcpu.zf = vmcpu.nf = vmcpu.pf = vmcpu.of = 0; - vmcpu.cf = vmcpu.af = vmcpu.df = 0; - vmcpu.eax_new = vmcpu.ebx_new = vmcpu.ecx_new = vmcpu.edx_new = 0; - vmcpu.esi_new = vmcpu.edi_new = vmcpu.esp_new = vmcpu.ebp_new = 0; - vmcpu.zf_new = vmcpu.nf_new = vmcpu.pf_new = vmcpu.of_new = 0; - vmcpu.cf_new = vmcpu.af_new = vmcpu.df_new = 0; - vmcpu.esp = 0; - vmcpu.tsc1 = 0x22222222; - vmcpu.tsc2 = 0x11111111; - - vmcpu.i_f = 1; -} - - -unsigned int _get_memory_page_max_address_py(void) -{ - unsigned int ret; - ret = get_memory_page_max_address(); - return ret; -} - -unsigned int _get_memory_page_max_user_address_py(void) -{ - unsigned int ret; - ret = get_memory_page_max_user_address(); - return ret; -} - -unsigned int _get_memory_page_from_min_ad_py(unsigned int size) -{ - unsigned int ret; - ret = get_memory_page_from_min_ad(size); - return ret; -} - -unsigned int access_segment(unsigned int d) -{ - // XXX TODO - printf("access segment %X\n", d); - return 0; -} -unsigned int access_segment_ok(unsigned int d) -{ - // XXX TODO - printf("access segment ok %X\n", d); - return 0; -} - -unsigned int load_segment_limit(unsigned int d) -{ - // XXX TODO - printf("load segment limit %X\n", d); - return 0; -} -unsigned int load_segment_limit_ok(unsigned int d) -{ - // XXX TODO - printf("load segment limit ok %X\n", d); - return 0; -} - -unsigned int load_tr_segment_selector(unsigned int d) -{ - // XXX TODO - return 0; -} - - -//#include "libcodenat_interface.c" diff --git a/miasm/tools/emul_lib/libcodenat.h b/miasm/tools/emul_lib/libcodenat.h deleted file mode 100644 index b7c0360b..00000000 --- a/miasm/tools/emul_lib/libcodenat.h +++ /dev/null @@ -1,566 +0,0 @@ -/* -** Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License along -** with this program; if not, write to the Free Software Foundation, Inc., -** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -#ifndef CODENAT_H -#define CODENAT_H - - -#if __BYTE_ORDER == __BIG_ENDIAN -#define Endian16_Swap(value) \ - ((((uint16_t)((value) & 0x00FF)) << 8) | \ - (((uint16_t)((value) & 0xFF00)) >> 8)) - -#define Endian32_Swap(value) \ - ((((uint32_t)((value) & 0x000000FF)) << 24) | \ - (((uint32_t)((value) & 0x0000FF00)) << 8) | \ - (((uint32_t)((value) & 0x00FF0000)) >> 8) | \ - (((uint32_t)((value) & 0xFF000000)) >> 24)) - -#define Endian64_Swap(value) \ - (((((uint64_t)value)<<56) & 0xFF00000000000000ULL) | \ - ((((uint64_t)value)<<40) & 0x00FF000000000000ULL) | \ - ((((uint64_t)value)<<24) & 0x0000FF0000000000ULL) | \ - ((((uint64_t)value)<< 8) & 0x000000FF00000000ULL) | \ - ((((uint64_t)value)>> 8) & 0x00000000FF000000ULL) | \ - ((((uint64_t)value)>>24) & 0x0000000000FF0000ULL) | \ - ((((uint64_t)value)>>40) & 0x000000000000FF00ULL) | \ - ((((uint64_t)value)>>56) & 0x00000000000000FFULL)) -#else -#define Endian16_Swap(value) (value) - -#define Endian32_Swap(value) (value) - -#define Endian64_Swap(value) (value) -#endif - - - - -LIST_HEAD(memory_page_list_head, memory_page_node); -LIST_HEAD(code_bloc_list_head, code_bloc_node); - -LIST_HEAD(memory_breakpoint_info_head, memory_breakpoint_info); - - -#define BREAKPOINT_READ 1 -#define BREAKPOINT_WRITE 2 - - -typedef struct { - unsigned int eax; - unsigned int ebx; - unsigned int ecx; - unsigned int edx; - unsigned int esi; - unsigned int edi; - unsigned int esp; - unsigned int ebp; - unsigned int eip; - - unsigned int zf; - unsigned int nf; - unsigned int pf; - unsigned int of; - unsigned int cf; - unsigned int af; - unsigned int df; - - unsigned int eax_new; - unsigned int ebx_new; - unsigned int ecx_new; - unsigned int edx_new; - unsigned int esi_new; - unsigned int edi_new; - unsigned int esp_new; - unsigned int ebp_new; - unsigned int eip_new; - - unsigned int zf_new; - unsigned int nf_new; - unsigned int pf_new; - unsigned int of_new; - unsigned int cf_new; - unsigned int af_new; - unsigned int df_new; - - unsigned int tf; - unsigned int i_f; - unsigned int iopl_f; - unsigned int nt; - unsigned int rf; - unsigned int vm; - unsigned int ac; - unsigned int vif; - unsigned int vip; - unsigned int i_d; - unsigned int tf_new; - unsigned int i_f_new; - unsigned int iopl_f_new; - unsigned int nt_new; - unsigned int rf_new; - unsigned int vm_new; - unsigned int ac_new; - unsigned int vif_new; - unsigned int vip_new; - unsigned int i_d_new; - - unsigned int my_tick; - - unsigned int cond; - - unsigned int vm_exception_flags; - unsigned int vm_exception_flags_new; - unsigned int vm_last_write_ad; - unsigned int vm_last_write_size ; - - - - double float_st0; - double float_st1; - double float_st2; - double float_st3; - double float_st4; - double float_st5; - double float_st6; - double float_st7; - - double float_st0_new; - double float_st1_new; - double float_st2_new; - double float_st3_new; - double float_st4_new; - double float_st5_new; - double float_st6_new; - double float_st7_new; - - unsigned int float_c0; - unsigned int float_c1; - unsigned int float_c2; - unsigned int float_c3; - - unsigned int float_c0_new; - unsigned int float_c1_new; - unsigned int float_c2_new; - unsigned int float_c3_new; - - unsigned int float_stack_ptr; - unsigned int float_stack_ptr_new; - - unsigned int reg_float_control; - unsigned int reg_float_control_new; - - unsigned int reg_float_eip; - unsigned int reg_float_eip_new; - unsigned int reg_float_cs; - unsigned int reg_float_cs_new; - unsigned int reg_float_address; - unsigned int reg_float_address_new; - unsigned int reg_float_ds; - unsigned int reg_float_ds_new; - - - unsigned int tsc1; - unsigned int tsc2; - - unsigned int tsc1_new; - unsigned int tsc2_new; - - - uint16_t es; - uint16_t cs; - uint16_t ss; - uint16_t ds; - uint16_t fs; - uint16_t gs; - - uint16_t es_new; - uint16_t cs_new; - uint16_t ss_new; - uint16_t ds_new; - uint16_t fs_new; - uint16_t gs_new; - - unsigned int cr0; - unsigned int cr0_new; - - unsigned int cr3; - unsigned int cr3_new; - - uint8_t pfmem08_0; - uint8_t pfmem08_1; - uint8_t pfmem08_2; - uint8_t pfmem08_3; - uint8_t pfmem08_4; - uint8_t pfmem08_5; - uint8_t pfmem08_6; - uint8_t pfmem08_7; - - uint16_t pfmem16_0; - uint16_t pfmem16_1; - uint16_t pfmem16_2; - uint16_t pfmem16_3; - uint16_t pfmem16_4; - uint16_t pfmem16_5; - uint16_t pfmem16_6; - uint16_t pfmem16_7; - - uint32_t pfmem32_0; - uint32_t pfmem32_1; - uint32_t pfmem32_2; - uint32_t pfmem32_3; - uint32_t pfmem32_4; - uint32_t pfmem32_5; - uint32_t pfmem32_6; - uint32_t pfmem32_7; - - uint64_t pfmem64_0; - uint64_t pfmem64_1; - uint64_t pfmem64_2; - uint64_t pfmem64_3; - uint64_t pfmem64_4; - uint64_t pfmem64_5; - uint64_t pfmem64_6; - uint64_t pfmem64_7; - - - uint64_t mm0; - uint64_t mm1; - uint64_t mm2; - uint64_t mm3; - uint64_t mm4; - uint64_t mm5; - uint64_t mm6; - uint64_t mm7; - - uint64_t mm0_new; - uint64_t mm1_new; - uint64_t mm2_new; - uint64_t mm3_new; - uint64_t mm4_new; - uint64_t mm5_new; - uint64_t mm6_new; - uint64_t mm7_new; - - uint32_t segm_base[0x10000]; - -}vm_cpu_t; - - -extern vm_cpu_t vmcpu; - -typedef struct _memory_page{ -}memory_page; - -struct memory_page_node { - uint64_t ad; - unsigned int size; - unsigned int access; - void* ad_hp; - //memory_page *mp; - LIST_ENTRY(memory_page_node) next; -}; - - - -struct code_bloc_node { - uint64_t ad_start; - uint64_t ad_stop; - uint64_t ad_code; - LIST_ENTRY(code_bloc_node) next; -}; - - -struct memory_breakpoint_info { - uint64_t ad; - unsigned int access; - LIST_ENTRY(memory_breakpoint_info) next; -}; - - -#define PAGE_READ 1 -#define PAGE_WRITE 2 -#define PAGE_EXEC 4 - - -//memory_page* create_memory_page(uint64_t ad, unsigned int size); - -//PyObject* _vm_get_exception(unsigned int xcpt); - -// interrupt with eip update after instr -#define EXCEPT_CODE_AUTOMOD (1<<0) -#define EXCEPT_SOFT_BP (1<<1) - -#define EXCEPT_BREAKPOINT_INTERN (1<<2) - -#define EXCEPT_NUM_UDPT_EIP (1<<5) -// interrupt with eip at instr -#define EXCEPT_UNK_MEM_AD (1<<6) -#define EXCEPT_THROW_SEH (1<<7) -#define EXCEPT_UNK_EIP (1<<8) -#define EXCEPT_ACCESS_VIOL (1<<9) -#define EXCEPT_INT_DIV_BY_ZERO (1<<10) -#define EXCEPT_PRIV_INSN (1<<11) -#define EXCEPT_ILLEGAL_INSN (1<<12) - -void dump_gpregs(void); -int is_mem_mapped(uint64_t ad); -uint64_t get_mem_base_addr(uint64_t addr, uint64_t *addr_base); -void MEM_WRITE(unsigned int my_size, uint64_t addr, unsigned int src); -unsigned int MEM_LOOKUP(unsigned int my_size, uint64_t addr); - - -void MEM_WRITE_08(uint64_t addr, unsigned char src); -void MEM_WRITE_16(uint64_t addr, unsigned short src); -void MEM_WRITE_32(uint64_t addr, unsigned int src); -void MEM_WRITE_64(uint64_t addr, uint64_t src); - -void MEM_WRITE_08_SEGM(uint16_t segm, uint64_t addr, unsigned char src); -void MEM_WRITE_16_SEGM(uint16_t segm, uint64_t addr, unsigned short src); -void MEM_WRITE_32_SEGM(uint16_t segm, uint64_t addr, unsigned int src); -void MEM_WRITE_64_SEGM(uint16_t segm, uint64_t addr, uint64_t src); - - -unsigned char MEM_LOOKUP_08(uint64_t addr); -unsigned short MEM_LOOKUP_16(uint64_t addr); -unsigned int MEM_LOOKUP_32(uint64_t addr); -uint64_t MEM_LOOKUP_64(uint64_t addr); - - -unsigned char MEM_LOOKUP_08_SEGM(uint16_t segm, uint64_t addr); -unsigned short MEM_LOOKUP_16_SEGM(uint16_t segm, uint64_t addr); -unsigned int MEM_LOOKUP_32_SEGM(uint16_t segm, uint64_t addr); -uint64_t MEM_LOOKUP_64_SEGM(uint16_t segm, uint64_t addr); - - - - -void MEM_WRITE_08_PASSTHROUGH(uint64_t addr, unsigned char src); -void MEM_WRITE_16_PASSTHROUGH(uint64_t addr, unsigned short src); -void MEM_WRITE_32_PASSTHROUGH(uint64_t addr, unsigned int src); -void MEM_WRITE_64_PASSTHROUGH(uint64_t addr, uint64_t src); -unsigned char MEM_LOOKUP_08_PASSTHROUGH(uint64_t addr); -unsigned short MEM_LOOKUP_16_PASSTHROUGH(uint64_t addr); -unsigned int MEM_LOOKUP_32_PASSTHROUGH(uint64_t addr); -uint64_t MEM_LOOKUP_64_PASSTHROUGH(uint64_t addr); - - -inline unsigned int parity(unsigned int a); -unsigned int my_imul08(unsigned int a, unsigned int b); - -void vm_throw(unsigned long flags); -int shift_right_arith(unsigned int size, int a, unsigned int b); -unsigned int shift_right_logic(unsigned int size, unsigned int a, unsigned int b); -int shift_left_logic(unsigned int size, unsigned int a, unsigned int b); -/* -int shift_left_logic_08(unsigned int a, unsigned int b); -int shift_left_logic_16(unsigned int a, unsigned int b); -int shift_left_logic_32(unsigned int a, unsigned int b); -*/ -unsigned int mul_lo_op(unsigned int size, unsigned int a, unsigned int b); -unsigned int mul_hi_op(unsigned int size, unsigned int a, unsigned int b); -unsigned int imul_lo_op_08(char a, char b); -unsigned int imul_lo_op_16(short a, short b); -unsigned int imul_lo_op_32(int a, int b); -int imul_hi_op_08(char a, char b); -int imul_hi_op_16(short a, short b); -int imul_hi_op_32(int a, int b); - - -unsigned int umul16_lo(unsigned short a, unsigned short b); -unsigned int umul16_hi(unsigned short a, unsigned short b); - - -unsigned int div_op(unsigned int size, unsigned int a, unsigned int b, unsigned int c); -unsigned int rem_op(unsigned int size, unsigned int a, unsigned int b, unsigned int c); -int rot_left(unsigned int size, unsigned int a, unsigned int b); -int rot_right(unsigned int size, unsigned int a, unsigned int b); -int rcl_rez_op(unsigned int size, unsigned int a, unsigned int b, unsigned int cf); -int rcl_cf_op(unsigned int size, unsigned int a, unsigned int b, unsigned int cf); -void _vm_init_regs(void); - - -//PyObject* _vm_push_uint32_t(PyObject *item); -//PyObject* _vm_pop_uint32_t(void); -////PyObject* _vm_put_str(PyObject *item); -//PyObject* _vm_set_mem(PyObject *item, PyObject *item_str); -//PyObject* _vm_set_mem_access(PyObject *addr, PyObject *access); -//PyObject* _vm_get_str(PyObject *item, PyObject *item_len); -//PyObject* _vm_add_memory_page(PyObject *item, PyObject *access, PyObject *item_str); -//PyObject* _vm_add_code_bloc(PyObject *item1, PyObject *item2);//, PyObject *item3); -//PyObject* _call_pyfunc_from_globals(char* funcname); -//PyObject* _call_pyfunc_from_eip(void); -// -//PyObject* call_pyfunc_from_globals(char* funcname); -// -//PyObject* _vm_get_gpreg(void); - -typedef struct _reg_dict{ - char* name; - unsigned int* ptr; -} reg_dict; - -typedef struct _reg_segm_dict{ - char* name; - uint16_t* ptr; -} reg_segm_dict; - -typedef struct _reg_float_dict{ - char* name; - void* ptr; -} reg_float_dict; - -extern reg_dict gpreg_dict[]; -//PyObject* _vm_set_gpreg(PyObject *dict); - - -void hexdump(char* m, unsigned int l); - -struct code_bloc_node * create_code_bloc_node(uint64_t ad_start, uint64_t ad_stop); -void add_code_bloc(struct code_bloc_node* cbp); - -struct memory_page_node * create_memory_page_node(uint64_t ad, unsigned int size, unsigned int access);//memory_page* mp); -void init_memory_page_pool(void); -void init_code_bloc_pool(void); -void reset_memory_page_pool(void); -void reset_code_bloc_pool(void); -void dump_code_bloc_pool(void); - - -void init_memory_breakpoint(void); -void reset_memory_breakpoint(void); -void add_memory_breakpoint(uint64_t ad, unsigned int access); -void remove_memory_breakpoint(uint64_t ad, unsigned int access); - - -void add_memory_page(struct memory_page_node* mpn); - -void dump_memory_page_pool(void); -void dump_memory_breakpoint_pool(void); -//PyObject* _vm_get_all_memory(void); - - - - -/********************************************/ - -//PyObject* _vm_get_cpu_state(void); -//PyObject* _vm_set_cpu_state(PyObject * s_cpustate); - - -//void memory_page_write(unsigned int my_size, uint64_t ad, unsigned int src); -//unsigned int memory_page_read(unsigned int my_size, uint64_t ad); -unsigned int get_memory_page_max_address(void); -unsigned int get_memory_page_max_user_address(void); - - -int is_mpn_in_tab(struct memory_page_node* mpn_a); - - -void _func_free(void); -void _func_alloc(void); -unsigned int _get_memory_page_max_address_py(void); -unsigned int _get_memory_page_max_user_address_py(void); -unsigned int _get_memory_page_from_min_ad_py(unsigned int size); - -void _func_malloc_memory_page(void); -void _func_free_memory_page(void); -void _func_virtualalloc_memory_page(void); -void _func_virtualfree_memory_page(void); -void _func_loadlib_fake(void); -void _func_getproc_fake(void); - - -void func_free(void); -void func_alloc(void); -unsigned int get_memory_page_max_address_py(void); -unsigned int get_memory_page_max_user_address_py(void); -unsigned int get_memory_page_from_min_ad_py(unsigned int size); -struct memory_page_node * get_memory_page_from_address(uint64_t ad); -void func_malloc_memory_page(void); -void func_free_memory_page(void); -void func_virtualalloc_memory_page(void); -void func_virtualfree_memory_page(void); -void func_loadlib_fake(void); -void func_getproc_fake(void); - - -//PyObject* _vm_exec_bloc(PyObject* my_eip, PyObject* known_blocs); - -unsigned int cpuid(unsigned int a, unsigned int reg_num); -double int2double(unsigned int m); -//PyObject* _vm_exec_blocs(PyObject* my_eip); - -double fadd(double a, double b); -double fsub(double a, double b); -double fmul(double a, double b); -double fdiv(double a, double b); -double ftan(double a); -double frndint(double a); -double fsin(double a); -double fcos(double a); -double fscale(double a, double b); -double f2xm1(double a); -double fsqrt(double a); -double fabs(double a); -unsigned int fcom_c0(double a, double b); -unsigned int fcom_c1(double a, double b); -unsigned int fcom_c2(double a, double b); -unsigned int fcom_c3(double a, double b); - - - -double mem_32_to_double(unsigned int m); -double mem_64_to_double(uint64_t m); -double int_16_to_double(unsigned int m); -double int_32_to_double(unsigned int m); -double int_64_to_double(uint64_t m); -int double_to_int_32(double d); -double fadd(double a, double b); -unsigned int double_to_mem_32(double d); -uint64_t double_to_mem_64(double d); - -unsigned int access_segment(unsigned int d); -unsigned int access_segment_ok(unsigned int d); - -unsigned int load_segment_limit(unsigned int d); -unsigned int load_segment_limit_ok(unsigned int d); - -unsigned int load_tr_segment_selector(unsigned int d); - -#define shift_right_arith_08(a, b)\ - ((((char)(a)) >> ((int)(b)&0x1f))&0xff) -#define shift_right_arith_16(a, b)\ - ((((short)(a)) >> ((int)(b)&0x1f))&0xffff) -#define shift_right_arith_32(a, b)\ - ((((int)(a)) >> ((int)(b)&0x1f))&0xffffffff) - - -#define shift_right_logic_08(a, b)\ - ((((unsigned char)(a)) >> ((unsigned int)(b)&0x1f))&0xff) -#define shift_right_logic_16(a, b)\ - ((((unsigned short)(a)) >> ((unsigned int)(b)&0x1f))&0xffff) -#define shift_right_logic_32(a, b)\ - ((((unsigned int)(a)) >> ((unsigned int)(b)&0x1f))&0xffffffff) - -#define shift_left_logic_08(a, b)\ - (((a)<<((b)&0x1f))&0xff) -#define shift_left_logic_16(a, b)\ - (((a)<<((b)&0x1f))&0xffff) -#define shift_left_logic_32(a, b)\ - (((a)<<((b)&0x1f))&0xffffffff) - -#endif diff --git a/miasm/tools/emul_lib/libcodenat_interface.c b/miasm/tools/emul_lib/libcodenat_interface.c deleted file mode 100644 index a0eeb4b3..00000000 --- a/miasm/tools/emul_lib/libcodenat_interface.c +++ /dev/null @@ -1,1579 +0,0 @@ -/* -** Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License along -** with this program; if not, write to the Free Software Foundation, Inc., -** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -#include <Python.h> -#include "queue.h" -#include "libcodenat.h" - -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define MAX(a,b) (((a)>(b))?(a):(b)) - -extern struct memory_page_list_head memory_page_pool; -extern struct code_bloc_list_head code_bloc_pool; - -#define RAISE(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return p;} - -PyObject* _vm_get_exception(unsigned int xcpt) -{ - PyObject*p; - - if (!xcpt) - p = NULL; - else if (xcpt & EXCEPT_CODE_AUTOMOD) - p = PyErr_Format( PyExc_RuntimeError, "EXCEPT_CODE_AUTOMOD" ); - else if (xcpt & EXCEPT_UNK_EIP) - p = PyErr_Format( PyExc_RuntimeError, "EXCEPT_UNK_EIP" ); - else if (xcpt & EXCEPT_UNK_MEM_AD) - p = PyErr_Format( PyExc_RuntimeError, "EXCEPT_UNK_MEM_AD" ); - - else p = PyErr_Format( PyExc_RuntimeError, "EXCEPT_UNKNOWN" ); - return p; -} - -PyObject* _vm_get_all_memory(void) -{ - struct memory_page_node * mpn; - PyObject *dict; - PyObject *dict2; - - PyObject *o; - - dict = PyDict_New(); - - LIST_FOREACH(mpn, &memory_page_pool, next){ - - dict2 = PyDict_New(); - - o = PyString_FromStringAndSize(mpn->ad_hp, mpn->size); - PyDict_SetItemString(dict2, "data", o); - Py_DECREF(o); - - o = PyInt_FromLong((long)mpn->size); - PyDict_SetItemString(dict2, "size", o); - Py_DECREF(o); - - o = PyInt_FromLong((long)mpn->access); - PyDict_SetItemString(dict2, "access", o); - Py_DECREF(o); - - o = PyInt_FromLong((long)mpn->ad); - PyDict_SetItem(dict, o, dict2); - Py_DECREF(o); - Py_DECREF(dict2); - } - return dict; -} - - - -PyObject* _vm_is_mem_mapped(PyObject* item) -{ - unsigned int page_addr; - unsigned int ret; - if (PyInt_Check(item)){ - page_addr = (unsigned int)PyInt_AsLong(item); - } - else if (PyLong_Check(item)){ - page_addr = (unsigned int)PyInt_AsUnsignedLongLongMask(item); - } - else{ - RAISE(PyExc_TypeError,"arg1 must be int"); - } - - ret = is_mem_mapped(page_addr); - return PyInt_FromLong((long)ret); - -} - -PyObject* vm_is_mem_mapped(PyObject* self, PyObject* args) -{ - PyObject *addr; - PyObject *p; - - if (!PyArg_ParseTuple(args, "O", &addr)) - return NULL; - p = _vm_is_mem_mapped(addr); - return p; -} - - -PyObject* _vm_get_mem_base_addr(PyObject* item) -{ - unsigned int page_addr; - uint64_t addr_base; - unsigned int ret; - if (PyInt_Check(item)){ - page_addr = (unsigned int)PyInt_AsLong(item); - } - else if (PyLong_Check(item)){ - page_addr = (unsigned int)PyInt_AsUnsignedLongLongMask(item); - } - else{ - RAISE(PyExc_TypeError,"arg1 must be int"); - } - - ret = get_mem_base_addr(page_addr, &addr_base); - if (ret == 0){ - Py_INCREF(Py_None); - return Py_None; - } - return PyInt_FromLong((long)addr_base); -} - - -PyObject* vm_get_mem_base_addr(PyObject* self, PyObject* args) -{ - PyObject *addr; - PyObject *p; - - if (!PyArg_ParseTuple(args, "O", &addr)) - return NULL; - p = _vm_get_mem_base_addr(addr); - return p; -} - - -PyObject* _vm_get_gpreg(void) -{ - PyObject *dict = PyDict_New(); - PyObject *o; - - o = PyInt_FromLong((long)vmcpu.eax); - PyDict_SetItemString(dict, "eax", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.ebx); - PyDict_SetItemString(dict, "ebx", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.ecx); - PyDict_SetItemString(dict, "ecx", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.edx); - PyDict_SetItemString(dict, "edx", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.esi); - PyDict_SetItemString(dict, "esi", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.edi); - PyDict_SetItemString(dict, "edi", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.esp); - PyDict_SetItemString(dict, "esp", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.ebp); - PyDict_SetItemString(dict, "ebp", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.eip); - PyDict_SetItemString(dict, "eip", o); - Py_DECREF(o); - - - o = PyInt_FromLong((long)vmcpu.zf); - PyDict_SetItemString(dict, "zf", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.nf); - PyDict_SetItemString(dict, "nf", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.pf); - PyDict_SetItemString(dict, "pf", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.of); - PyDict_SetItemString(dict, "of", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.cf); - PyDict_SetItemString(dict, "cf", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.af); - PyDict_SetItemString(dict, "af", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.df); - PyDict_SetItemString(dict, "df", o); - Py_DECREF(o); - - - - return dict; -} - - -reg_dict gpreg_dict[] = { {.name = "eax", .ptr = &(vmcpu.eax)}, - {.name = "ebx", .ptr = &(vmcpu.ebx)}, - {.name = "ecx", .ptr = &(vmcpu.ecx)}, - {.name = "edx", .ptr = &(vmcpu.edx)}, - {.name = "esi", .ptr = &(vmcpu.esi)}, - {.name = "edi", .ptr = &(vmcpu.edi)}, - {.name = "esp", .ptr = &(vmcpu.esp)}, - {.name = "ebp", .ptr = &(vmcpu.ebp)}, - {.name = "eip", .ptr = &(vmcpu.eip)}, - - {.name = "zf", .ptr = &(vmcpu.zf)}, - {.name = "nf", .ptr = &(vmcpu.nf)}, - {.name = "pf", .ptr = &(vmcpu.pf)}, - {.name = "of", .ptr = &(vmcpu.of)}, - {.name = "cf", .ptr = &(vmcpu.cf)}, - {.name = "af", .ptr = &(vmcpu.af)}, - {.name = "df", .ptr = &(vmcpu.df)}, - - -}; - - - - -PyObject* _vm_set_gpreg(PyObject *dict) -{ - PyObject *d_key, *d_value = NULL; - Py_ssize_t pos = 0; - unsigned int val; - unsigned int i, found; - - if(!PyDict_Check(dict)) - RAISE(PyExc_TypeError, "arg must be dict"); - while(PyDict_Next(dict, &pos, &d_key, &d_value)){ - if(!PyString_Check(d_key)) - RAISE(PyExc_TypeError, "key must be str"); - - if (PyInt_Check(d_value)){ - val = (unsigned int)PyInt_AsLong(d_value); - } - else if (PyLong_Check(d_value)){ - val = (unsigned int)PyInt_AsUnsignedLongLongMask(d_value); - } - else{ - RAISE(PyExc_TypeError,"value must be int"); - } - - found = 0; - for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){ - if (strcmp(PyString_AsString(d_key), gpreg_dict[i].name)) - continue; - *(gpreg_dict[i].ptr) = val; - found = 1; - break; - } - - if (found) - continue; - fprintf(stderr, "unkown key: %s\n", PyString_AsString(d_key)); - RAISE(PyExc_ValueError, "unkown reg"); - } - return NULL; -} - - - - - - - - - - - - - - - -PyObject* _vm_get_segm(void) -{ - PyObject *dict = PyDict_New(); - PyObject *o; - - o = PyInt_FromLong((long)vmcpu.es); - PyDict_SetItemString(dict, "es", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.cs); - PyDict_SetItemString(dict, "cs", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.ss); - PyDict_SetItemString(dict, "ss", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.ds); - PyDict_SetItemString(dict, "ds", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.fs); - PyDict_SetItemString(dict, "fs", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.gs); - PyDict_SetItemString(dict, "gs", o); - Py_DECREF(o); - - - - return dict; -} - - -reg_segm_dict segm_dict[] = { {.name = "es", .ptr = &(vmcpu.es)}, - {.name = "cs", .ptr = &(vmcpu.cs)}, - {.name = "ss", .ptr = &(vmcpu.ss)}, - {.name = "ds", .ptr = &(vmcpu.ds)}, - {.name = "fs", .ptr = &(vmcpu.fs)}, - {.name = "gs", .ptr = &(vmcpu.gs)}, - - -}; - - - - -PyObject* _vm_set_segm(PyObject *dict) -{ - PyObject *d_key, *d_value = NULL; - Py_ssize_t pos = 0; - unsigned int val; - unsigned int i, found; - - if(!PyDict_Check(dict)) - RAISE(PyExc_TypeError, "arg must be dict"); - while(PyDict_Next(dict, &pos, &d_key, &d_value)){ - if(!PyString_Check(d_key)) - RAISE(PyExc_TypeError, "key must be str"); - - if (PyInt_Check(d_value)){ - val = (unsigned int)PyInt_AsLong(d_value); - } - else if (PyLong_Check(d_value)){ - val = (unsigned int)PyInt_AsUnsignedLongLongMask(d_value); - } - else{ - RAISE(PyExc_TypeError,"value must be int"); - } - - found = 0; - for (i=0; i < sizeof(segm_dict)/sizeof(reg_dict); i++){ - if (strcmp(PyString_AsString(d_key), segm_dict[i].name)) - continue; - *(segm_dict[i].ptr) = val; - found = 1; - break; - } - - if (found) - continue; - fprintf(stderr, "unkown key: %s\n", PyString_AsString(d_key)); - RAISE(PyExc_ValueError, "unkown reg"); - } - return NULL; -} - - - - - - -PyObject* _vm_get_float(void) -{ - PyObject *dict = PyDict_New(); - PyObject *o; - - o = PyFloat_FromDouble((double)vmcpu.float_st0); - PyDict_SetItemString(dict, "st0", o); - Py_DECREF(o); - o = PyFloat_FromDouble((double)vmcpu.float_st1); - PyDict_SetItemString(dict, "st1", o); - Py_DECREF(o); - o = PyFloat_FromDouble((double)vmcpu.float_st2); - PyDict_SetItemString(dict, "st2", o); - Py_DECREF(o); - o = PyFloat_FromDouble((double)vmcpu.float_st3); - PyDict_SetItemString(dict, "st3", o); - Py_DECREF(o); - o = PyFloat_FromDouble((double)vmcpu.float_st4); - PyDict_SetItemString(dict, "st4", o); - Py_DECREF(o); - o = PyFloat_FromDouble((double)vmcpu.float_st5); - PyDict_SetItemString(dict, "st5", o); - Py_DECREF(o); - o = PyFloat_FromDouble((double)vmcpu.float_st6); - PyDict_SetItemString(dict, "st6", o); - Py_DECREF(o); - o = PyFloat_FromDouble((double)vmcpu.float_st7); - PyDict_SetItemString(dict, "st7", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.float_stack_ptr); - PyDict_SetItemString(dict, "stack_ptr", o); - Py_DECREF(o); - o = PyInt_FromLong((long)vmcpu.reg_float_control); - PyDict_SetItemString(dict, "float_control", o); - Py_DECREF(o); - return dict; -} - -reg_float_dict float_dict[] = { {.name = "st0", .ptr = &(vmcpu.float_st0)}, - {.name = "st1", .ptr = &(vmcpu.float_st1)}, - {.name = "st2", .ptr = &(vmcpu.float_st2)}, - {.name = "st3", .ptr = &(vmcpu.float_st3)}, - {.name = "st4", .ptr = &(vmcpu.float_st4)}, - {.name = "st5", .ptr = &(vmcpu.float_st5)}, - {.name = "st6", .ptr = &(vmcpu.float_st6)}, - {.name = "st7", .ptr = &(vmcpu.float_st7)}, - {.name = "stack_ptr", .ptr = &(vmcpu.float_stack_ptr)}, - {.name = "float_control", .ptr = &(vmcpu.reg_float_control)}, -}; - -PyObject* _vm_set_float(PyObject *dict) -{ - PyObject *d_key, *d_value = NULL; - Py_ssize_t pos = 0; - double d; - unsigned int i, found; - - if(!PyDict_Check(dict)) - RAISE(PyExc_TypeError, "arg must be dict"); - while(PyDict_Next(dict, &pos, &d_key, &d_value)){ - if(!PyString_Check(d_key)) - RAISE(PyExc_TypeError, "key must be str"); - - if (PyInt_Check(d_value)){ - d = (double)PyInt_AsLong(d_value); - } - else if (PyLong_Check(d_value)){ - d = (double)PyInt_AsUnsignedLongLongMask(d_value); - } - else if (PyFloat_Check(d_value)){ - d = PyFloat_AsDouble(d_value); - } - else{ - RAISE(PyExc_TypeError,"value must be int/long/float"); - } - - found = 0; - for (i=0; i < sizeof(float_dict)/sizeof(reg_float_dict); i++){ - if (strcmp(PyString_AsString(d_key), float_dict[i].name)) - continue; - if (!strncmp(float_dict[i].name, "st", 2)) - *((double*)float_dict[i].ptr) = d; - else - *((uint32_t*)float_dict[i].ptr) = (uint32_t)d; - found = 1; - break; - } - - if (found) - continue; - fprintf(stderr, "unkown key: %s\n", PyString_AsString(d_key)); - RAISE(PyExc_ValueError, "unkown reg"); - } - return NULL; -} - - -PyObject* _vm_add_memory_page(PyObject *item, PyObject *access, PyObject *item_str) -{ - unsigned int buf_size; - char* buf_data; - Py_ssize_t length; - int ret = 0x1337beef; - unsigned int page_addr; - unsigned int page_access; - - struct memory_page_node * mpn; - - if (PyInt_Check(item)){ - page_addr = (unsigned int)PyInt_AsLong(item); - } - else if (PyLong_Check(item)){ - page_addr = (unsigned int)PyInt_AsUnsignedLongLongMask(item); - } - else{ - RAISE(PyExc_TypeError,"arg1 must be int"); - } - - - - if (PyInt_Check(access)){ - page_access = (unsigned int)PyInt_AsLong(access); - } - else if (PyLong_Check(item)){ - page_access = (unsigned int)PyInt_AsUnsignedLongLongMask(access); - } - else{ - RAISE(PyExc_TypeError,"arg2 must be int"); - } - - - - if(!PyString_Check(item_str)) - RAISE(PyExc_TypeError,"arg must be str"); - - buf_size = PyString_Size(item_str); - PyString_AsStringAndSize(item_str, &buf_data, &length); - - - mpn = create_memory_page_node(page_addr, buf_size, page_access); - if (mpn == NULL) - RAISE(PyExc_TypeError,"cannot create page"); - if (is_mpn_in_tab(mpn)) - RAISE(PyExc_TypeError,"known page in memory"); - - memcpy(mpn->ad_hp, buf_data, buf_size); - add_memory_page(mpn); - - return PyInt_FromLong((long)ret); -} - -PyObject* _call_pyfunc_from_globals(char* funcname) -{ - PyObject *mod, *func, *rslt, *globals, *func_globals; - - fprintf(stderr, "getting pyfunc %s\n", funcname); - mod = PyEval_GetBuiltins(); - - if (!mod) { - fprintf(stderr, "cannot find module\n"); - exit(0); - } - - func_globals = PyDict_GetItemString(mod, "globals"); - if (!func_globals) { - fprintf(stderr, "cannot find function globals\n"); - exit(0); - } - - if (!PyCallable_Check (func_globals)) { - fprintf(stderr, "function not callable\n"); - exit(0); - } - - globals = PyObject_CallObject (func_globals, NULL); - if (!globals) { - fprintf(stderr, "cannot get globals\n"); - exit(0); - } - - func = PyDict_GetItemString (globals, funcname); - if (!func) { - fprintf(stderr, "cannot find function %s\n", funcname); - exit(0); - } - - if (!PyCallable_Check (func)) { - fprintf(stderr, "function not callable\n"); - exit(0); - } - - rslt = PyObject_CallObject (func, NULL); - return rslt; -} - - - -PyObject* _call_pyfunc_from_eip(void) -{ - PyObject *mod, *func, *rslt, *globals, *func_globals; - char funcname[0x100]; - - fprintf(stderr, "getting pybloc %X\n", vmcpu.eip); - sprintf(funcname, "bloc_%.8X", vmcpu.eip); - fprintf(stderr, "bloc name %s\n", funcname); - - mod = PyEval_GetBuiltins(); - - if (!mod) { - fprintf(stderr, "cannot find module\n"); - exit(0); - } - func_globals = PyDict_GetItemString(mod, "globals"); - if (!func_globals) { - fprintf(stderr, "cannot find function globals\n"); - exit(0); - } - if (!PyCallable_Check (func_globals)) { - fprintf(stderr, "function not callable\n"); - exit(0); - } - globals = PyObject_CallObject (func_globals, NULL); - if (!globals) { - fprintf(stderr, "cannot get globals\n"); - exit(0); - } - - - func = PyDict_GetItemString (globals, funcname); - if (!func) { - fprintf(stderr, "cannot find function %s\n", funcname); - exit(0); - } - if (!PyCallable_Check (func)) { - fprintf(stderr, "function not callable\n"); - exit(0); - } - rslt = PyObject_CallObject (func, NULL); - return rslt; -} - -PyObject* _vm_get_cpu_state(void) -{ - PyObject * o; - o = PyString_FromStringAndSize((char*)&vmcpu, sizeof(vmcpu)); - return o; -} - -PyObject* _vm_set_cpu_state(char* buf, int buf_size) -{ - memcpy(&vmcpu, buf, sizeof(vmcpu)); - return PyInt_FromLong((long)0); - -} - - -PyObject* _vm_push_uint32_t(int val) -{ - vmcpu.esp-=4; - MEM_WRITE(32, vmcpu.esp, val); - - return PyInt_FromLong((long)vmcpu.esp); -} - - -PyObject* _vm_pop_uint32_t(void) -{ - unsigned int val; - - val = MEM_LOOKUP(32, vmcpu.esp); - vmcpu.esp+=4; - - return PyInt_FromLong((long)val);; -} - -PyObject* _vm_push_uint16_t(int val) -{ - vmcpu.esp-=2; - MEM_WRITE(16, vmcpu.esp, val); - - return PyInt_FromLong((long)vmcpu.esp); -} - - -PyObject* _vm_pop_uint16_t(void) -{ - unsigned int val; - - val = MEM_LOOKUP(16, vmcpu.esp); - vmcpu.esp+=2; - - return PyInt_FromLong((long)val);; -} - - -PyObject* _vm_set_mem(PyObject *addr, PyObject *item_str) -{ - unsigned int buf_size; - char* buf_data; - Py_ssize_t length; - int ret = 0x1337; - unsigned int val; - unsigned int l; - - struct memory_page_node * mpn; - - if (PyInt_Check(addr)){ - val = (unsigned int)PyInt_AsLong(addr); - } - else if (PyLong_Check(addr)){ - val = (unsigned int)PyInt_AsUnsignedLongLongMask(addr); - } - else{ - RAISE(PyExc_TypeError,"arg1 must be int"); - } - - if(!PyString_Check(item_str)) - RAISE(PyExc_TypeError,"arg must be str"); - - buf_size = PyString_Size(item_str); - PyString_AsStringAndSize(item_str, &buf_data, &length); - - /* read is multiple page wide */ - while (buf_size){ - mpn = get_memory_page_from_address(val); - if (!mpn){ - PyErr_SetString(PyExc_RuntimeError, "cannot find address"); - return 0; - } - l = MIN(buf_size, mpn->size - (val-mpn->ad)); - memcpy(mpn->ad_hp + (val-mpn->ad), buf_data, l); - buf_data += l; - val += l; - buf_size -= l; - } - - return PyInt_FromLong((long)ret); -} - - -PyObject* _vm_set_mem_access(PyObject *addr, PyObject *access) -{ - int ret = 0x1337beef; - unsigned int page_addr; - unsigned int page_access; - - struct memory_page_node * mpn; - - if (PyInt_Check(addr)){ - page_addr = (unsigned int)PyInt_AsLong(addr); - } - else if (PyLong_Check(addr)){ - page_addr = (unsigned int)PyInt_AsUnsignedLongLongMask(addr); - } - else{ - RAISE(PyExc_TypeError,"arg1 must be int"); - } - - if (PyInt_Check(access)){ - page_access = (unsigned int)PyInt_AsLong(access); - } - else if (PyLong_Check(access)){ - page_access = (unsigned int)PyInt_AsUnsignedLongLongMask(access); - } - else{ - RAISE(PyExc_TypeError,"arg2 must be int"); - } - - mpn = get_memory_page_from_address(page_addr); - mpn->access = page_access; - return PyInt_FromLong((long)ret); -} - - -PyObject* _vm_get_str(PyObject *addr, PyObject *item_len) -{ - unsigned int buf_addr; - unsigned int buf_len; - PyObject *obj_out; - struct memory_page_node * mpn; - char* buf_out; - char * addr_tmp; - char* addr_out; - int off; - unsigned int l; - unsigned int my_size; - - if (PyInt_Check(addr)){ - buf_addr = (unsigned int)PyInt_AsLong(addr); - } - else if (PyLong_Check(addr)){ - buf_addr = (unsigned int)PyInt_AsUnsignedLongLongMask(addr); - } - else{ - RAISE(PyExc_TypeError,"arg1 must be int"); - } - if (PyInt_Check(item_len)){ - buf_len = (unsigned int)PyInt_AsLong(item_len); - } - else if (PyLong_Check(item_len)){ - buf_len = (unsigned int)PyInt_AsUnsignedLongLongMask(item_len); - } - else{ - RAISE(PyExc_TypeError,"arg must be int"); - } - - my_size = buf_len; - buf_out = malloc(buf_len); - if (!buf_out){ - fprintf(stderr, "cannot alloc read\n"); - exit(-1); - } - - addr_out = buf_out; - - /* read is multiple page wide */ - while (my_size){ - mpn = get_memory_page_from_address(buf_addr); - if (!mpn){ - PyErr_SetString(PyExc_RuntimeError, "cannot find address"); - return 0; - } - - - off = buf_addr - mpn->ad; - addr_tmp = &((char*)mpn->ad_hp)[off]; - - l = MIN(my_size, mpn->size - off); - memcpy(addr_out, addr_tmp, l); - my_size -= l; - addr_out +=l; - buf_addr +=l; - } - - obj_out = PyString_FromStringAndSize(buf_out, buf_len); - free(buf_out); - return obj_out; -} - -PyObject * _vm_add_memory_breakpoint(PyObject* ad, PyObject* access) -{ - - uint64_t b_ad; - unsigned int b_access; - - if (PyInt_Check(ad)){ - b_ad = (unsigned int)PyInt_AsLong(ad); - } - else if (PyLong_Check(ad)){ - b_ad = (unsigned int)PyInt_AsUnsignedLongLongMask(ad); - } - else{ - RAISE(PyExc_TypeError,"arg1 must be int"); - } - - if (PyInt_Check(access)){ - b_access = (unsigned int)PyInt_AsLong(access); - } - else if (PyLong_Check(access)){ - b_access = (unsigned int)PyInt_AsUnsignedLongLongMask(access); - } - else{ - RAISE(PyExc_TypeError,"arg1 must be int"); - } - add_memory_breakpoint(b_ad, b_access); - Py_INCREF(Py_None); - return Py_None; - -} - -PyObject * _vm_remove_memory_breakpoint(PyObject* ad, PyObject* access) -{ - - uint64_t b_ad; - unsigned int b_access; - - if (PyInt_Check(ad)){ - b_ad = (unsigned int)PyInt_AsLong(ad); - } - else if (PyLong_Check(ad)){ - b_ad = (unsigned int)PyInt_AsUnsignedLongLongMask(ad); - } - else{ - RAISE(PyExc_TypeError,"arg1 must be int"); - } - - if (PyInt_Check(access)){ - b_access = (unsigned int)PyInt_AsLong(access); - } - else if (PyLong_Check(access)){ - b_access = (unsigned int)PyInt_AsUnsignedLongLongMask(access); - } - else{ - RAISE(PyExc_TypeError,"arg1 must be int"); - } - remove_memory_breakpoint(b_ad, b_access); - Py_INCREF(Py_None); - return Py_None; -} - -PyObject * dump_gpregs_py(PyObject* self, PyObject* args) -{ - dump_gpregs(); - Py_INCREF(Py_None); - return Py_None; -} - -PyObject* vm_get_last_write_ad(PyObject* self, PyObject* args) -{ - return PyInt_FromLong((long)vmcpu.vm_last_write_ad); -} - -PyObject* vm_get_last_write_size(PyObject* self, PyObject* args) -{ - return PyInt_FromLong((long)vmcpu.vm_last_write_size); -} - - -PyObject* vm_reset_exception(PyObject* self, PyObject* args) -{ - vmcpu.vm_exception_flags = 0; - Py_INCREF(Py_None); - return Py_None; -} - -PyObject* vm_get_exception(PyObject* self, PyObject* args) -{ - return PyInt_FromLong((long)vmcpu.vm_exception_flags); -} - -PyObject * vm_init_regs(PyObject* self, PyObject* args) -{ - _vm_init_regs(); - Py_INCREF(Py_None); - return Py_None; -} - -PyObject* vm_push_uint32_t(PyObject* self, PyObject *args) -{ - PyObject* p; - int item; - if (!PyArg_ParseTuple(args, "I", &item)) - return NULL; - p = _vm_push_uint32_t(item); - return p; -} - - -PyObject* vm_pop_uint32_t(PyObject* self, PyObject* args) -{ - PyObject* p; - p = _vm_pop_uint32_t(); - return p; -} - -PyObject* vm_push_uint16_t(PyObject* self, PyObject *args) -{ - PyObject* p; - int item; - if (!PyArg_ParseTuple(args, "I", &item)) - return NULL; - p = _vm_push_uint16_t(item); - return p; -} - - -PyObject* vm_pop_uint16_t(PyObject* self, PyObject* args) -{ - PyObject* p; - p = _vm_pop_uint16_t(); - return p; -} - -PyObject* vm_set_mem(PyObject* self, PyObject* args) -{ - PyObject* p; - PyObject *addr; - PyObject *item_str; - if (!PyArg_ParseTuple(args, "OO", &addr, &item_str)) - return NULL; - - p = _vm_set_mem(addr, item_str); - return p; -} - -PyObject* vm_set_mem_access(PyObject* self, PyObject* args) -{ - PyObject* p; - PyObject *addr; - PyObject *access; - if (!PyArg_ParseTuple(args, "OO", &addr, &access)) - return NULL; - - p = _vm_set_mem_access(addr, access); - return p; -} - - -PyObject* vm_get_str(PyObject* self, PyObject* args) -{ - PyObject* p; - PyObject *item; - PyObject *item_len; - if (!PyArg_ParseTuple(args, "OO", &item, &item_len)) - return NULL; - - p = _vm_get_str(item, item_len); - return p; -} - - -PyObject* vm_get_gpreg(PyObject* self, PyObject* args) -{ - PyObject* p; - p = _vm_get_gpreg(); - return p; -} - -PyObject* vm_set_gpreg(PyObject *self, PyObject *args) -{ - PyObject* dict; - if (!PyArg_ParseTuple(args, "O", &dict)) - return NULL; - _vm_set_gpreg(dict); - Py_INCREF(Py_None); - return Py_None; -} - - -PyObject* vm_get_segm(PyObject* self, PyObject* args) -{ - PyObject* p; - p = _vm_get_segm(); - return p; -} - -PyObject* vm_set_segm(PyObject *self, PyObject *args) -{ - PyObject* dict; - if (!PyArg_ParseTuple(args, "O", &dict)) - return NULL; - _vm_set_segm(dict); - Py_INCREF(Py_None); - return Py_None; -} - -PyObject* vm_get_float(PyObject* self, PyObject* args) -{ - PyObject* p; - p = _vm_get_float(); - return p; -} - -PyObject* vm_set_float(PyObject *self, PyObject *args) -{ - PyObject* dict; - if (!PyArg_ParseTuple(args, "O", &dict)) - return NULL; - _vm_set_float(dict); - Py_INCREF(Py_None); - return Py_None; - -} - -PyObject* init_memory_page_pool_py(PyObject* self, PyObject* args) -{ - init_memory_page_pool(); - Py_INCREF(Py_None); - return Py_None; -} - -PyObject* init_code_bloc_pool_py(PyObject* self, PyObject* args) -{ - init_code_bloc_pool(); - Py_INCREF(Py_None); - return Py_None; - -} - -PyObject* init_memory_breakpoint_py(PyObject* self, PyObject* args) -{ - init_memory_breakpoint(); - Py_INCREF(Py_None); - return Py_None; - -} - -PyObject* reset_memory_breakpoint_py(PyObject* self, PyObject* args) -{ - reset_memory_breakpoint(); - Py_INCREF(Py_None); - return Py_None; - -} - - -PyObject* vm_add_memory_page(PyObject* self, PyObject* args) -{ - PyObject *item; - PyObject *access; - PyObject *item_str; - PyObject* p; - if (!PyArg_ParseTuple(args, "OOO", &item, &access, &item_str)) - return NULL; - p = _vm_add_memory_page(item, access, item_str); - return p; -} - -PyObject* vm_add_memory_breakpoint(PyObject* self, PyObject* args) -{ - PyObject *ad; - PyObject *access; - if (!PyArg_ParseTuple(args, "OO", &ad, &access)) - return NULL; - _vm_add_memory_breakpoint(ad, access); - Py_INCREF(Py_None); - return Py_None; -} - -PyObject* vm_remove_memory_breakpoint(PyObject* self, PyObject* args) -{ - PyObject *ad; - PyObject *access; - if (!PyArg_ParseTuple(args, "OO", &ad, &access)) - return NULL; - _vm_remove_memory_breakpoint(ad, access); - Py_INCREF(Py_None); - return Py_None; -} - - - -PyObject* dump_memory_page_pool_py(PyObject* self, PyObject* args) -{ - dump_memory_page_pool(); - Py_INCREF(Py_None); - return Py_None; -} - -PyObject* dump_memory_breakpoint_py(PyObject* self, PyObject* args) -{ - dump_memory_breakpoint_pool(); - Py_INCREF(Py_None); - return Py_None; -} - -PyObject* vm_get_all_memory(PyObject* self, PyObject* args) -{ - PyObject *o; - o = _vm_get_all_memory(); - return o; -} - - -PyObject* reset_memory_page_pool_py(PyObject* self, PyObject* args) -{ - reset_memory_page_pool(); - Py_INCREF(Py_None); - return Py_None; - -} - -PyObject* reset_code_bloc_pool_py(PyObject* self, PyObject* args) -{ - reset_code_bloc_pool(); - Py_INCREF(Py_None); - return Py_None; - -} - - -PyObject* call_pyfunc_from_globals(PyObject* self, PyObject* args) -{ - PyObject* p; - char* funcname; - if (!PyArg_ParseTuple(args, "s", &funcname)) - return NULL; - - p = _call_pyfunc_from_globals(funcname); - return p; -} - - -PyObject* _vm_add_code_bloc(PyObject* self, PyObject* args) -{ - PyObject *item1; - PyObject *item2; - int ret = 0x1337beef; - unsigned int ad_start, ad_stop, ad_code = 0; - - struct code_bloc_node * cbp; - - if (!PyArg_ParseTuple(args, "OO", &item1, &item2)) - return NULL; - - - if (PyInt_Check(item1)){ - ad_start = (unsigned int)PyInt_AsLong(item1); - } - else if (PyLong_Check(item1)){ - ad_start = (unsigned int)PyInt_AsUnsignedLongLongMask(item1); - } - else{ - RAISE(PyExc_TypeError,"arg1 must be int"); - } - - if (PyInt_Check(item2)){ - ad_stop = (unsigned int)PyInt_AsLong(item2); - } - else if (PyLong_Check(item2)){ - ad_stop = (unsigned int)PyInt_AsUnsignedLongLongMask(item2); - } - else{ - RAISE(PyExc_TypeError,"arg2 must be int"); - } - - cbp = create_code_bloc_node(ad_start, ad_stop); - cbp->ad_start = ad_start; - cbp->ad_stop = ad_stop; - cbp->ad_code = ad_code; - add_code_bloc(cbp); - return PyInt_FromLong((long)ret); -} - - -PyObject* vm_add_code_bloc(PyObject *item1, PyObject *item2) -{ - PyObject* p; - p = _vm_add_code_bloc(item1, item2); - return p; -} - -PyObject* dump_code_bloc_pool_py(void) -{ - dump_code_bloc_pool(); - Py_INCREF(Py_None); - return Py_None; - -} - - - -PyObject* vm_get_cpu_state(PyObject* self, PyObject* args) -{ - PyObject* o; - o = _vm_get_cpu_state(); - return o; -} - -PyObject* vm_set_cpu_state(PyObject* self, PyObject* args) -{ - PyObject *o; - char* buf; - int buf_size; - - if (!PyArg_ParseTuple(args, "s#", &buf, &buf_size)) - RAISE(PyExc_TypeError,"arg must be str"); - - o = _vm_set_cpu_state(buf, buf_size); - return o; -} - - - -unsigned int get_memory_page_max_address_py(void) -{ - unsigned int ret; - ret = _get_memory_page_max_address_py(); - return ret; -} - -PyObject * vm_get_memory_page_max_address(PyObject* self, PyObject* args) -{ - PyObject* v; - unsigned int tmp; - - tmp = get_memory_page_max_address_py(); - v = PyInt_FromLong((long)tmp); - return v; -} - -unsigned int get_memory_page_max_user_address_py(void) -{ - unsigned int ret; - ret = _get_memory_page_max_user_address_py(); - return ret; -} - - -unsigned int get_memory_page_from_min_ad_py(unsigned int size) -{ - unsigned int ret; - ret = _get_memory_page_from_min_ad_py(size); - return ret; - -} - - -PyObject* vm_get_segm_base(PyObject* self, PyObject* args) -{ - PyObject *item1; - unsigned int segm_num; - PyObject* v; - - if (!PyArg_ParseTuple(args, "O", &item1)) - return NULL; - if (PyInt_Check(item1)){ - segm_num = (unsigned int)PyInt_AsLong(item1); - } - else if (PyLong_Check(item1)){ - segm_num = (unsigned int)PyInt_AsUnsignedLongLongMask(item1); - } - else{ - RAISE(PyExc_TypeError,"arg1 must be int"); - } - v = PyInt_FromLong((long)vmcpu.segm_base[segm_num]); - return v; -} - -PyObject* vm_set_segm_base(PyObject* self, PyObject* args) -{ - PyObject *item1, *item2; - unsigned int segm_num, segm_base; - - if (!PyArg_ParseTuple(args, "OO", &item1, &item2)) - return NULL; - if (PyInt_Check(item1)){ - segm_num = (unsigned int)PyInt_AsLong(item1); - } - else if (PyLong_Check(item1)){ - segm_num = (unsigned int)PyInt_AsUnsignedLongLongMask(item1); - } - else{ - RAISE(PyExc_TypeError,"arg1 must be int"); - } - if (PyInt_Check(item2)){ - segm_base = (unsigned int)PyInt_AsLong(item2); - } - else if (PyLong_Check(item2)){ - segm_base = (unsigned int)PyInt_AsUnsignedLongLongMask(item2); - } - else{ - RAISE(PyExc_TypeError,"arg2 must be int"); - } - vmcpu.segm_base[segm_num] = segm_base; - - Py_INCREF(Py_None); - return Py_None; -} - - - -PyObject* _vm_exec_blocs(PyObject* self, PyObject* args) -{ - PyObject* b; - PyObject* module; - PyObject* func; - PyObject* meip; - unsigned long tmp; - - PyObject* my_eip; - PyObject* known_blocs; - PyObject* e; - - if (!PyArg_ParseTuple(args, "OO", &my_eip, &known_blocs)) - return NULL; - - if(!PyDict_Check(known_blocs)) - RAISE(PyExc_TypeError, "arg must be dict"); - - if (PyInt_Check(my_eip)){ - tmp = (unsigned long)PyInt_AsLong(my_eip); - } - else if (PyLong_Check(my_eip)){ - tmp = (unsigned long)PyInt_AsUnsignedLongLongMask(my_eip); - } - else{ - RAISE(PyExc_TypeError,"arg1 must be int"); - } - meip = PyLong_FromUnsignedLong((unsigned long)tmp); - while (1){ - b = PyDict_GetItem(known_blocs, meip); - if (b == NULL) - return meip; - - module = PyObject_GetAttrString(b, "module_c"); - if (module == NULL){ - fprintf(stderr, "assert eip module_c in pyobject\n"); - exit(0); - } - func = PyObject_GetAttrString(module, "func"); - if (func == NULL){ - fprintf(stderr, "assert func module_c in pyobject\n"); - exit(0); - } - - Py_DECREF(module); - if (!PyCallable_Check (func)) { - fprintf(stderr, "function not callable\n"); - exit(0); - } - Py_DECREF(meip); - meip = PyObject_CallObject (func, NULL); - - Py_DECREF(func); - e = PyErr_Occurred (); - if (e){ - fprintf(stderr, "exception\n"); - return meip; - } - - if (vmcpu.vm_exception_flags) - return meip; - - } -} - - -PyObject* vm_exec_blocs(PyObject* self, PyObject* args) -{ - PyObject* my_eip; - my_eip = _vm_exec_blocs(self, args); - return my_eip; -} - - - -PyObject* vm_exec_bloc(PyObject* self, PyObject* args) -{ - PyObject* b; - PyObject* module; - PyObject* func; - PyObject* meip; - unsigned int tmp; - - PyObject* my_eip; - PyObject* known_blocs; - PyObject* e; - - if (!PyArg_ParseTuple(args, "OO", &my_eip, &known_blocs)) - return NULL; - - - if (PyInt_Check(my_eip)){ - tmp = (unsigned int)PyInt_AsLong(my_eip); - } - else if (PyLong_Check(my_eip)){ - tmp = (unsigned int)PyInt_AsUnsignedLongLongMask(my_eip); - } - else{ - RAISE(PyExc_TypeError,"arg1 must be int"); - } - - meip = PyInt_FromLong((long)tmp); - b = PyDict_GetItem(known_blocs, my_eip); - if (b == NULL) - return meip; - module = PyObject_GetAttrString(b, "module_c"); - if (module == NULL) - return meip; - func = PyObject_GetAttrString(module, "func"); - if (func == NULL) - return meip; - Py_DECREF(module); - if (!PyCallable_Check (func)) { - fprintf(stderr, "function not callable\n"); - exit(0); - } - Py_DECREF(meip); - meip = PyObject_CallObject (func, NULL); - - Py_DECREF(func); - e = PyErr_Occurred (); - if (e){ - fprintf(stderr, "exception\n"); - return meip; - } - - return meip; -} - -static PyObject *CodenatError; - - -static PyMethodDef CodenatMethods[] = { - {"vm_init_regs", vm_init_regs, METH_VARARGS, - "init regs vm."}, - {"vm_push_uint32_t", vm_push_uint32_t, METH_VARARGS, - "push on vm stack"}, - {"dump_gpregs_py", dump_gpregs_py, METH_VARARGS, - "x"}, - - - {"vm_push_uint32_t", vm_push_uint32_t, METH_VARARGS, - "x"}, - {"vm_pop_uint32_t",vm_pop_uint32_t, METH_VARARGS, - "X"}, - {"vm_push_uint16_t", vm_push_uint16_t, METH_VARARGS, - "x"}, - {"vm_pop_uint16_t",vm_pop_uint16_t, METH_VARARGS, - "X"}, - {"vm_get_gpreg", vm_get_gpreg, METH_VARARGS, - "X"}, - {"vm_set_gpreg",vm_set_gpreg, METH_VARARGS, - "X"}, - {"vm_get_segm", vm_get_segm, METH_VARARGS, - "X"}, - {"vm_set_segm",vm_set_segm, METH_VARARGS, - "X"}, - {"vm_get_float", vm_get_float, METH_VARARGS, - "X"}, - {"vm_set_float",vm_set_float, METH_VARARGS, - "X"}, - {"vm_init_regs",vm_init_regs, METH_VARARGS, - "X"}, - {"dump_gpregs_py", dump_gpregs_py, METH_VARARGS, - "X"}, - - {"init_memory_page_pool_py", init_memory_page_pool_py, METH_VARARGS, - "X"}, - {"init_memory_breakpoint_py", init_memory_breakpoint_py, METH_VARARGS, - "X"}, - {"init_code_bloc_pool_py",init_code_bloc_pool_py, METH_VARARGS, - "X"}, - {"vm_set_mem_access", vm_set_mem_access, METH_VARARGS, - "X"}, - {"vm_set_mem", vm_set_mem, METH_VARARGS, - "X"}, - {"vm_add_code_bloc",vm_add_code_bloc, METH_VARARGS, - "X"}, - {"vm_exec_bloc",vm_exec_bloc, METH_VARARGS, - "X"}, - {"vm_exec_blocs",vm_exec_blocs, METH_VARARGS, - "X"}, - {"vm_get_str", vm_get_str, METH_VARARGS, - "X"}, - {"vm_add_memory_page",vm_add_memory_page, METH_VARARGS, - "X"}, - {"vm_add_memory_breakpoint",vm_add_memory_breakpoint, METH_VARARGS, - "X"}, - {"vm_remove_memory_breakpoint",vm_remove_memory_breakpoint, METH_VARARGS, - "X"}, - {"vm_reset_exception", vm_reset_exception, METH_VARARGS, - "X"}, - {"dump_memory_page_pool_py", dump_memory_page_pool_py, METH_VARARGS, - "X"}, - {"dump_memory_breakpoint_py", dump_memory_breakpoint_py, METH_VARARGS, - "X"}, - {"vm_get_all_memory",vm_get_all_memory, METH_VARARGS, - "X"}, - {"reset_memory_page_pool_py", reset_memory_page_pool_py, METH_VARARGS, - "X"}, - {"reset_memory_breakpoint_py", reset_memory_breakpoint_py, METH_VARARGS, - "X"}, - {"reset_code_bloc_pool_py", reset_code_bloc_pool_py, METH_VARARGS, - "X"}, - {"call_pyfunc_from_globals",call_pyfunc_from_globals, METH_VARARGS, - "X"}, - - {"vm_get_exception",vm_get_exception, METH_VARARGS, - "X"}, - {"vm_get_exception",vm_get_exception, METH_VARARGS, - "X"}, - {"vm_get_last_write_ad", vm_get_last_write_ad, METH_VARARGS, - "X"}, - {"vm_get_last_write_size",vm_get_last_write_size, METH_VARARGS, - "X"}, - {"vm_get_memory_page_max_address",vm_get_memory_page_max_address, METH_VARARGS, - "X"}, - {"vm_get_cpu_state",vm_get_cpu_state, METH_VARARGS, - "X"}, - {"vm_set_cpu_state",vm_set_cpu_state, METH_VARARGS, - "X"}, - {"vm_get_segm_base",vm_get_segm_base, METH_VARARGS, - "X"}, - {"vm_set_segm_base",vm_set_segm_base, METH_VARARGS, - "X"}, - - {"vm_is_mem_mapped",vm_is_mem_mapped, METH_VARARGS, - "X"}, - {"vm_get_mem_base_addr",vm_get_mem_base_addr, METH_VARARGS, - "X"}, - - {NULL, NULL, 0, NULL} /* Sentinel */ - -}; - - -PyMODINIT_FUNC -initlibcodenat_interface(void) -{ - PyObject *m; - - m = Py_InitModule("libcodenat_interface", CodenatMethods); - if (m == NULL) - return; - - CodenatError = PyErr_NewException("codenat.error", NULL, NULL); - Py_INCREF(CodenatError); - PyModule_AddObject(m, "error", CodenatError); -} - diff --git a/miasm/tools/emul_lib/libcodenat_tcc.c b/miasm/tools/emul_lib/libcodenat_tcc.c deleted file mode 100644 index c9bc1187..00000000 --- a/miasm/tools/emul_lib/libcodenat_tcc.c +++ /dev/null @@ -1,152 +0,0 @@ -/* -** Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License along -** with this program; if not, write to the Free Software Foundation, Inc., -** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -#include <Python.h> - -#include <inttypes.h> -#include <libtcc.h> - - - -/* tcc global state */ -TCCState *tcc_state = NULL; - - -int include_path_array_count = 0; -char **include_path_array = NULL; - -char *libcodenat_path = NULL; - -PyObject* tcc_set_emul_lib_path(PyObject* self, PyObject* args) -{ - char* include_path_arg; - char* libcodenat_path_arg; - - char* str1, * str2; - - if (!PyArg_ParseTuple(args, "ss", - &include_path_arg, - &libcodenat_path_arg)) - return NULL; - - if (include_path_array) - free(include_path_array); - - str2 = strdup(include_path_arg); - while (str2){ - str1 = strsep(&str2, ";"); - if (str1){ - include_path_array_count ++; - include_path_array = realloc(include_path_array, - include_path_array_count * sizeof(char*)); - include_path_array[include_path_array_count-1] = strdup(str1); - printf("adding include file: %s\n", str1); - } - } - - libcodenat_path = (char*)malloc(strlen(libcodenat_path_arg)+1); - strcpy(libcodenat_path, libcodenat_path_arg); - return Py_None; -} - -void tcc_init_state(void) -{ - int i; - tcc_state = tcc_new(); - if (!tcc_state) { - fprintf(stderr, "Impossible de creer un contexte TCC\n"); - exit(1); - } - tcc_set_output_type(tcc_state, TCC_OUTPUT_MEMORY); - - tcc_add_file(tcc_state, libcodenat_path); - for (i=0;i<include_path_array_count; i++){ - tcc_add_include_path(tcc_state, include_path_array[i]); - } -} - - - - -PyObject* tcc_exec_bloc(PyObject* self, PyObject* args) -{ - uint64_t (*func)(void); - - unsigned long ret; - if (!PyArg_ParseTuple(args, "l", &func)) - return NULL; - ret = func(); - return PyLong_FromUnsignedLong(ret); -} - -PyObject* tcc_compil(PyObject* self, PyObject* args) -{ - char* func_name; - char* func_code; - int (*entry)(void); - - if (!PyArg_ParseTuple(args, "ss", &func_name, &func_code)) - return NULL; - - tcc_init_state(); - if (tcc_compile_string(tcc_state, func_code) != 0) { - fprintf(stderr, "Erreur de compilation !\n"); - fprintf(stderr, "%s\n", func_code); - exit(0); - } - /* XXX use tinycc devel with -fPIC patch in makefile */ - if (tcc_relocate(tcc_state,TCC_RELOCATE_AUTO) < 0) - exit(0); - entry = tcc_get_symbol(tcc_state, func_name); - if (!entry){ - fprintf(stderr, "Erreur de symbole !\n"); - fprintf(stderr, "%s\n", func_name); - exit(0); - } - - return PyInt_FromLong((long)entry); - -} - - -static PyObject *TccError; - - -static PyMethodDef TccMethods[] = { - {"tcc_set_emul_lib_path", tcc_set_emul_lib_path, METH_VARARGS, - "init tcc path"}, - {"tcc_exec_bloc", tcc_exec_bloc, METH_VARARGS, - "tcc exec bloc"}, - {"tcc_compil", tcc_compil, METH_VARARGS, - "tcc compil"}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -PyMODINIT_FUNC -initlibcodenat_tcc(void) -{ - PyObject *m; - - m = Py_InitModule("libcodenat_tcc", TccMethods); - if (m == NULL) - return; - - TccError = PyErr_NewException("tcc.error", NULL, NULL); - Py_INCREF(TccError); - PyModule_AddObject(m, "error", TccError); -} - diff --git a/miasm/tools/emul_lib/main.c b/miasm/tools/emul_lib/main.c deleted file mode 100644 index e088191d..00000000 --- a/miasm/tools/emul_lib/main.c +++ /dev/null @@ -1,43 +0,0 @@ -/* -** Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License along -** with this program; if not, write to the Free Software Foundation, Inc., -** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ -#include <Python.h> -#include "queue.h" -#include "libcodenat.h" -int main() -{ - memory_page* mp; - struct memory_page_node * mpn; - - init_memory_page_pool(); - dump_memory_page_pool(); - - - mp = create_memory_page(0x1000, 0x10); - mpn = create_memory_page_node(mp); - add_memory_page(mpn); - - dump_memory_page_pool(); - - - mp = create_memory_page(0x2000, 0x10); - mpn = create_memory_page_node(mp); - add_memory_page(mpn); - dump_memory_page_pool(); - - return 0; -} diff --git a/miasm/tools/emul_lib/queue.h b/miasm/tools/emul_lib/queue.h deleted file mode 100644 index 0caf72fb..00000000 --- a/miasm/tools/emul_lib/queue.h +++ /dev/null @@ -1,553 +0,0 @@ -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - * $FreeBSD$ - */ - -#ifndef _SYS_QUEUE_H_ -#define _SYS_QUEUE_H_ - -//#include <sys/cdefs.h> - -/* - * This file defines four types of data structures: singly-linked lists, - * singly-linked tail queues, lists and tail queues. - * - * A singly-linked list is headed by a single forward pointer. The elements - * are singly linked for minimum space and pointer manipulation overhead at - * the expense of O(n) removal for arbitrary elements. New elements can be - * added to the list after an existing element or at the head of the list. - * Elements being removed from the head of the list should use the explicit - * macro for this purpose for optimum efficiency. A singly-linked list may - * only be traversed in the forward direction. Singly-linked lists are ideal - * for applications with large datasets and few or no removals or for - * implementing a LIFO queue. - * - * A singly-linked tail queue is headed by a pair of pointers, one to the - * head of the list and the other to the tail of the list. The elements are - * singly linked for minimum space and pointer manipulation overhead at the - * expense of O(n) removal for arbitrary elements. New elements can be added - * to the list after an existing element, at the head of the list, or at the - * end of the list. Elements being removed from the head of the tail queue - * should use the explicit macro for this purpose for optimum efficiency. - * A singly-linked tail queue may only be traversed in the forward direction. - * Singly-linked tail queues are ideal for applications with large datasets - * and few or no removals or for implementing a FIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * For details on the use of these macros, see the queue(3) manual page. - * - * - * SLIST LIST STAILQ TAILQ - * _HEAD + + + + - * _HEAD_INITIALIZER + + + + - * _ENTRY + + + + - * _INIT + + + + - * _EMPTY + + + + - * _FIRST + + + + - * _NEXT + + + + - * _PREV - - - + - * _LAST - - + + - * _FOREACH + + + + - * _FOREACH_SAFE + + + + - * _FOREACH_REVERSE - - - + - * _FOREACH_REVERSE_SAFE - - - + - * _INSERT_HEAD + + + + - * _INSERT_BEFORE - + - + - * _INSERT_AFTER + + + + - * _INSERT_TAIL - - + + - * _CONCAT - - + + - * _REMOVE_HEAD + - + - - * _REMOVE + + + + - * - */ -#define QUEUE_MACRO_DEBUG 0 -#if QUEUE_MACRO_DEBUG -/* Store the last 2 places the queue element or head was altered */ -struct qm_trace { - char * lastfile; - int lastline; - char * prevfile; - int prevline; -}; - -#define TRACEBUF struct qm_trace trace; -#define TRASHIT(x) do {(x) = (void *)-1;} while (0) - -#define QMD_TRACE_HEAD(head) do { \ - (head)->trace.prevline = (head)->trace.lastline; \ - (head)->trace.prevfile = (head)->trace.lastfile; \ - (head)->trace.lastline = __LINE__; \ - (head)->trace.lastfile = __FILE__; \ -} while (0) - -#define QMD_TRACE_ELEM(elem) do { \ - (elem)->trace.prevline = (elem)->trace.lastline; \ - (elem)->trace.prevfile = (elem)->trace.lastfile; \ - (elem)->trace.lastline = __LINE__; \ - (elem)->trace.lastfile = __FILE__; \ -} while (0) - -#else -#define QMD_TRACE_ELEM(elem) -#define QMD_TRACE_HEAD(head) -#define TRACEBUF -#define TRASHIT(x) -#endif /* QUEUE_MACRO_DEBUG */ - -/* - * Singly-linked List declarations. - */ -#define SLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ -} - -#define SLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define SLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ -} - -/* - * Singly-linked List functions. - */ -#define SLIST_EMPTY(head) ((head)->slh_first == NULL) - -#define SLIST_FIRST(head) ((head)->slh_first) - -#define SLIST_FOREACH(var, head, field) \ - for ((var) = SLIST_FIRST((head)); \ - (var); \ - (var) = SLIST_NEXT((var), field)) - -#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = SLIST_FIRST((head)); \ - (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ - for ((varp) = &SLIST_FIRST((head)); \ - ((var) = *(varp)) != NULL; \ - (varp) = &SLIST_NEXT((var), field)) - -#define SLIST_INIT(head) do { \ - SLIST_FIRST((head)) = NULL; \ -} while (0) - -#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ - SLIST_NEXT((slistelm), field) = (elm); \ -} while (0) - -#define SLIST_INSERT_HEAD(head, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ - SLIST_FIRST((head)) = (elm); \ -} while (0) - -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) - -#define SLIST_REMOVE(head, elm, type, field) do { \ - if (SLIST_FIRST((head)) == (elm)) { \ - SLIST_REMOVE_HEAD((head), field); \ - } \ - else { \ - struct type *curelm = SLIST_FIRST((head)); \ - while (SLIST_NEXT(curelm, field) != (elm)) \ - curelm = SLIST_NEXT(curelm, field); \ - SLIST_NEXT(curelm, field) = \ - SLIST_NEXT(SLIST_NEXT(curelm, field), field); \ - } \ -} while (0) - -#define SLIST_REMOVE_HEAD(head, field) do { \ - SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ -} while (0) - -/* - * Singly-linked Tail queue declarations. - */ -#define STAILQ_HEAD(name, type) \ -struct name { \ - struct type *stqh_first;/* first element */ \ - struct type **stqh_last;/* addr of last next element */ \ -} - -#define STAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).stqh_first } - -#define STAILQ_ENTRY(type) \ -struct { \ - struct type *stqe_next; /* next element */ \ -} - -/* - * Singly-linked Tail queue functions. - */ -#define STAILQ_CONCAT(head1, head2) do { \ - if (!STAILQ_EMPTY((head2))) { \ - *(head1)->stqh_last = (head2)->stqh_first; \ - (head1)->stqh_last = (head2)->stqh_last; \ - STAILQ_INIT((head2)); \ - } \ -} while (0) - -#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) - -#define STAILQ_FIRST(head) ((head)->stqh_first) - -#define STAILQ_FOREACH(var, head, field) \ - for((var) = STAILQ_FIRST((head)); \ - (var); \ - (var) = STAILQ_NEXT((var), field)) - - -#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = STAILQ_FIRST((head)); \ - (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define STAILQ_INIT(head) do { \ - STAILQ_FIRST((head)) = NULL; \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ -} while (0) - -#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_NEXT((tqelm), field) = (elm); \ -} while (0) - -#define STAILQ_INSERT_HEAD(head, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_FIRST((head)) = (elm); \ -} while (0) - -#define STAILQ_INSERT_TAIL(head, elm, field) do { \ - STAILQ_NEXT((elm), field) = NULL; \ - *(head)->stqh_last = (elm); \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ -} while (0) - -#define STAILQ_LAST(head, type, field) \ - (STAILQ_EMPTY((head)) ? \ - NULL : \ - ((struct type *) \ - ((char *)((head)->stqh_last) - __offsetof(struct type, field)))) - -#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) - -#define STAILQ_REMOVE(head, elm, type, field) do { \ - if (STAILQ_FIRST((head)) == (elm)) { \ - STAILQ_REMOVE_HEAD((head), field); \ - } \ - else { \ - struct type *curelm = STAILQ_FIRST((head)); \ - while (STAILQ_NEXT(curelm, field) != (elm)) \ - curelm = STAILQ_NEXT(curelm, field); \ - if ((STAILQ_NEXT(curelm, field) = \ - STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\ - (head)->stqh_last = &STAILQ_NEXT((curelm), field);\ - } \ -} while (0) - -#define STAILQ_REMOVE_HEAD(head, field) do { \ - if ((STAILQ_FIRST((head)) = \ - STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ -} while (0) - -#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ - if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ -} while (0) - -/* - * List declarations. - */ -#define LIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define LIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define LIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List functions. - */ - -#define LIST_EMPTY(head) ((head)->lh_first == NULL) - -#define LIST_FIRST(head) ((head)->lh_first) - -#define LIST_FOREACH(var, head, field) \ - for ((var) = LIST_FIRST((head)); \ - (var); \ - (var) = LIST_NEXT((var), field)) - -#define LIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = LIST_FIRST((head)); \ - (var) && ((tvar) = LIST_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define LIST_INIT(head) do { \ - LIST_FIRST((head)) = NULL; \ -} while (0) - -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ - if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ - LIST_NEXT((listelm), field)->field.le_prev = \ - &LIST_NEXT((elm), field); \ - LIST_NEXT((listelm), field) = (elm); \ - (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ -} while (0) - -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - LIST_NEXT((elm), field) = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ -} while (0) - -#define LIST_INSERT_HEAD(head, elm, field) do { \ - if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ - LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ - LIST_FIRST((head)) = (elm); \ - (elm)->field.le_prev = &LIST_FIRST((head)); \ -} while (0) - -#define LIST_NEXT(elm, field) ((elm)->field.le_next) - -#define LIST_REMOVE(elm, field) do { \ - if (LIST_NEXT((elm), field) != NULL) \ - LIST_NEXT((elm), field)->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = LIST_NEXT((elm), field); \ -} while (0) - -/* - * Tail queue declarations. - */ -#define TAILQ_HEAD(name, type) \ -struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ - TRACEBUF \ -} - -#define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } - -#define TAILQ_ENTRY(type) \ -struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ - TRACEBUF \ -} - -/* - * Tail queue functions. - */ -#define TAILQ_CONCAT(head1, head2, field) do { \ - if (!TAILQ_EMPTY(head2)) { \ - *(head1)->tqh_last = (head2)->tqh_first; \ - (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ - (head1)->tqh_last = (head2)->tqh_last; \ - TAILQ_INIT((head2)); \ - QMD_TRACE_HEAD(head); \ - QMD_TRACE_HEAD(head2); \ - } \ -} while (0) - -#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) - -#define TAILQ_FIRST(head) ((head)->tqh_first) - -#define TAILQ_FOREACH(var, head, field) \ - for ((var) = TAILQ_FIRST((head)); \ - (var); \ - (var) = TAILQ_NEXT((var), field)) - -#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = TAILQ_FIRST((head)); \ - (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ - for ((var) = TAILQ_LAST((head), headname); \ - (var); \ - (var) = TAILQ_PREV((var), headname, field)) - -#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ - for ((var) = TAILQ_LAST((head), headname); \ - (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ - (var) = (tvar)) - -#define TAILQ_INIT(head) do { \ - TAILQ_FIRST((head)) = NULL; \ - (head)->tqh_last = &TAILQ_FIRST((head)); \ - QMD_TRACE_HEAD(head); \ -} while (0) - -#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ - &TAILQ_NEXT((elm), field); \ - else { \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - QMD_TRACE_HEAD(head); \ - } \ - TAILQ_NEXT((listelm), field) = (elm); \ - (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ - QMD_TRACE_ELEM(&(elm)->field); \ - QMD_TRACE_ELEM(&listelm->field); \ -} while (0) - -#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - TAILQ_NEXT((elm), field) = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ - QMD_TRACE_ELEM(&(elm)->field); \ - QMD_TRACE_ELEM(&listelm->field); \ -} while (0) - -#define TAILQ_INSERT_HEAD(head, elm, field) do { \ - if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ - TAILQ_FIRST((head))->field.tqe_prev = \ - &TAILQ_NEXT((elm), field); \ - else \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - TAILQ_FIRST((head)) = (elm); \ - (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ - QMD_TRACE_HEAD(head); \ - QMD_TRACE_ELEM(&(elm)->field); \ -} while (0) - -#define TAILQ_INSERT_TAIL(head, elm, field) do { \ - TAILQ_NEXT((elm), field) = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - QMD_TRACE_HEAD(head); \ - QMD_TRACE_ELEM(&(elm)->field); \ -} while (0) - -#define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) - -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) - -#define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) - -#define TAILQ_REMOVE(head, elm, field) do { \ - if ((TAILQ_NEXT((elm), field)) != NULL) \ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else { \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - QMD_TRACE_HEAD(head); \ - } \ - *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ - TRASHIT((elm)->field.tqe_next); \ - TRASHIT((elm)->field.tqe_prev); \ - QMD_TRACE_ELEM(&(elm)->field); \ -} while (0) - - -#ifdef _KERNEL - -/* - * XXX insque() and remque() are an old way of handling certain queues. - * They bogusly assumes that all queue heads look alike. - */ - -struct quehead { - struct quehead *qh_link; - struct quehead *qh_rlink; -}; - -#if defined(__GNUC__) || defined(__INTEL_COMPILER) - -static __inline void -insque(void *a, void *b) -{ - struct quehead *element = (struct quehead *)a, - *head = (struct quehead *)b; - - element->qh_link = head->qh_link; - element->qh_rlink = head; - head->qh_link = element; - element->qh_link->qh_rlink = element; -} - -static __inline void -remque(void *a) -{ - struct quehead *element = (struct quehead *)a; - - element->qh_link->qh_rlink = element->qh_rlink; - element->qh_rlink->qh_link = element->qh_link; - element->qh_rlink = 0; -} - -#else /* !(__GNUC__ || __INTEL_COMPILER) */ - -void insque(void *a, void *b); -void remque(void *a); - -#endif /* __GNUC__ || __INTEL_COMPILER */ - -#endif /* _KERNEL */ - -#endif /* !_SYS_QUEUE_H_ */ diff --git a/miasm/tools/func_analyser.py b/miasm/tools/func_analyser.py deleted file mode 100755 index 2b801358..00000000 --- a/miasm/tools/func_analyser.py +++ /dev/null @@ -1,485 +0,0 @@ -#!/usr/bin/env python -# -# Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -from x86_escape import opcode_factory, bin_stream, instr_dis -from asmbloc import * -from parse_asm import * -import shlex -from ia32_sem import * -from copy import copy -import pefile -import pprint - - -class imp_func: - def __init__(self, address, name, name_dll, unstack=None): - self.address = address - self.name = name - self.dllname = name_dll - self.unstack = unstack - def __str__(self): - return hex(self.address)+' '+str(self.name)+' '+str(self.dllname)+' '+str(self.unstack) - -x86mnemo = opcode_factory() - -fname = "calc.exe" -f = open(fname, 'rb') -pe = pefile.PE(fname) - -pool_import_func = {} -print "read import" -if hasattr(pe, "DIRECTORY_ENTRY_IMPORT"): - for entry in pe.DIRECTORY_ENTRY_IMPORT: - #print entry.dll - for imp in entry.imports: - #print '\t', hex(imp.address), imp.name - pool_import_func[imp.address] = imp_func(imp.address, imp.name, entry.dll) - -dll_pe_cache = {} -dll_rep = "dlls/" -def init_dll_cache(dllname): - global dll_pe_cache - print "read %s"%dllname - pe = pefile.PE(dll_rep+dllname) - dll_pe_cache[dllname] = pe - print 'read ok' - - -def read_dll_export(dll_name, func_name): - global dll_pe_cache - fname = dll_name.lower() - print "read export", fname - - if not fname in dll_pe_cache: - print 'not loaded dll' - init_dll_cache(fname) - - pe = dll_pe_cache[fname] - """ - pe = pefile.PE(fname) - """ - f_tmp = open(dll_rep+fname, 'rb') - - if not hasattr(pe, "DIRECTORY_ENTRY_EXPORT"): - return None - - dict_export = dict([(exp.name, exp) for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols]) - if not func_name in dict_export: - return None - - offset = pe.get_offset_from_rva(dict_export[func_name].address) - print "offset", hex(offset) - in_str_tmp = bin_stream(f_tmp, offset) - symbol_pool_tmp = asm_symbol_pool() - all_bloc_tmp = dis_bloc_all(x86mnemo, in_str_tmp, in_str_tmp.offset, [], symbol_pool_tmp, follow_call = False) - ret = quick_ret_analyse(offset, all_bloc_tmp) - - return ret - - - -print "disasm bin follow " -#0x366 -#0x2F0 -#0x3B0 - -#open file -start_dis = 0x9F09#0xB50 -in_str = bin_stream(f, start_dis) - -#disasm binary -job_done = [] -symbol_pool = asm_symbol_pool() -all_bloc = dis_bloc_all(x86mnemo, in_str, in_str.offset, job_done, symbol_pool, follow_call = False) -print "symbols:" -print symbol_pool - -g = bloc2graph(all_bloc) -open("graph.txt" , "w").write(g) - -jcc = ['jz', 'je', 'jnz', 'jp', 'jnp', 'jg', 'jge', 'ja', 'jae', 'jb', 'jbe', 'jl', 'jle', 'js', 'jns', 'loop'] - -eax_i = ExprId('eax_i') -ebx_i = ExprId('ebx_i') -ecx_i = ExprId('ecx_i') -edx_i = ExprId('edx_i') -esi_i = ExprId('esi_i') -edi_i = ExprId('edi_i') -esp_i = ExprId('esp_i') -ebp_i = ExprId('ebp_i') - -MEM_GLOB = ExprId('MEM_GLOB') - -def dump_pool(p): - print '/-------------\\' - for x in p: - print x, p[x] - print '\\_____________/' - - -def hook_mem_read(evaluator, src): - evaluator.log.warn('mem read %s'%str(src)) - src_address = evaluator.eval_expr(src.arg, {}) - src_address = evaluator.simp_full_exp(src_address) - src_address = evaluator.simp_expr_arith_final(src_address) - - print 'test read',src_address, evaluator.simp_expr_arith_final(src_address) - dump_pool(evaluator.pool[MEM_GLOB]) - - - if not str(src_address) in evaluator.pool[MEM_GLOB]: - evaluator.log.warning('unkown read address:%s'%src_address) - return ExprMem(src_address, size = src.size) - return evaluator.pool[MEM_GLOB][str(src_address)] - - -def hook_mem_write(evaluator, dst, src, pool_out): - evaluator.log.warn("mem write: %s %s"%(str(dst), str(src))) - - dst_address = evaluator.eval_expr(dst.arg, {}) - dst_address = evaluator.simp_full_exp(dst_address) - dst_address = evaluator.simp_expr_arith_final(dst_address) - print 'test write',dst_address, evaluator.simp_expr_arith_final(dst_address) - - evaluator.pool[MEM_GLOB][str(dst_address)] = src - dump_pool(evaluator.pool[MEM_GLOB]) - - - - -#set unkown stack for all blocks -for b in all_bloc: - b.eval_start,b.eval_stop = None, None - for l in b.lines: - l.arg_lookup = None - l.stack_h_after = None - - - -#first bloc start at 0 -#esp_init_arg= 0x1000 -evaluator = eval_int({esp:esp_i, ebp:ebp_i, eax:eax_i, ebx:ebx_i, ecx:ecx_i, edx:edx_i, esi:esi_i, edi:edi_i, - cs:9, - zf : 0, - nf : 0, - pf : 0, - of : 0, - cf : 0, - tf : 0, - i_f: 0, - df : 0, - af : 0, - iopl: 3, - nt : 0, - rf : 0, - vm : 0, - ac : 0, - vif: 0, - vip: 0, - i_d: 0, - MEM_GLOB:{}, - }, - hook_mem_read, - hook_mem_write - ) -args_func = [] -#for i in xrange(3, 0, -1): - #args_func.append(ExprId('arg_%d'%i)) - - #evaluator.eval_instr(push(args_func[-1])) -evaluator.eval_instr(push('ret_addr')) -esp_init= evaluator.pool[esp] - -all_bloc[0].eval_start = evaluator - -def quick_ret_analyse(offset, all_bloc_arg): - #first, try to find ret and look for unstack arg. - for b in all_bloc_arg: - l = b.lines[-1] - if l.m.name == 'ret': - args = [dict_to_Expr(x, l.m.modifs) for x in l.arg] - if len(args) == 0: - return 0 - else: - #exprint - return args[0].arg - #no ret found means special func - #try evaluation to ret and look at esp decal - #hack stack decal - return None - -def is_func_wrapper(ad, pool_import_func = {}): - x86mnemo = opcode_factory() - in_str_tmp = bin_stream(f, ad.offset) - instr = x86mnemo.dis(in_str_tmp) - print 'i'*80 - print instr - if instr.m.name in ['jmp'] and is_address(instr.arg[0]): - return True - - return False - -#is simply import call? -def is_import_call(offset, eval_arg, symbol_pool, pool_import_func = {}): - evaluator_tmp = eval_int(dict([(x,copy(eval_arg.pool[x])) for x in eval_arg.pool]), hook_mem_read, hook_mem_write) - in_str_tmp = bin_stream(f, offset) - - #eval only jmp/call until eip load - ad_done = {} - while True: - if offset in ad_done: - return False, None - ad_done[offset] = True - l = x86mnemo.dis(in_str_tmp) - if not l.m.name in ['call', 'jmp']: - return False, None - - args = [dict_to_Expr(x, l.m.modifs) for x in l.arg] - if l.m.name in ['call']: - if is_imm(l.arg[0]): - e = mnemo_func[l.m.name](ExprInt(in_str_tmp.offset), ExprOp('+', in_str.offset, args[0]) ) - else: - e = mnemo_func[l.m.name](ExprInt(in_str_tmp.offset), args[0]) - else: - e = mnemo_func[l.m.name](*args) - - evaluator_tmp.eval_instr(e) - if eip in evaluator_tmp.pool: - n_eip = evaluator_tmp.pool[eip] - if type(n_eip) in [int, long]: - offset = n_eip - continue - if not isinstance(n_eip, ExprMem): - return False, None - ad = evaluator_tmp.eval_expr(n_eip.arg, {}) - - if not type(ad) in [int, long]: - return False, None - if not ad in pool_import_func: - return False, None - - unstack = None - print "import func spotted:", str(pool_import_func[ad]) - #if pool_import_func[ad].name in known_func: - - print pool_import_func[ad].name - dll_name = pool_import_func[ad].dllname - func_name = pool_import_func[ad].name - unstack = read_dll_export(dll_name, func_name) - print "result:",unstack - #unstack = known_func[pool_import_func[ad].name].unstack - - return True, unstack - iiiopop - #offset = in_str_tmp.offset - - - -def stack_h(b, symbol_pool, pool_import_func = {}): - evaluator_tmp = eval_int(dict([(x,copy(b.eval_start.pool[x])) for x in b.eval_start.pool]), hook_mem_read, hook_mem_write) - #if b.lines[0].offset == 0x9FCE: - # fds - for m in b.lines: - #m.stack_h = evaluator_tmp.pool[esp] - m.stack_h = evaluator.simp_expr_arith_final(evaluator_tmp.pool[esp]) - print hex(m.offset), m.stack_h, str(m) - - - if m.m.name in ['call']: - - """ - #hack call next code - if m.offset+m.l == s.offset: - evaluator_tmp.pool[esp]-=4 - return evaluator_tmp - """ - ret, unstack = is_import_call(m.offset, evaluator_tmp, symbol_pool, pool_import_func) - if unstack!=None: - evaluator_tmp.pool[esp]=evaluator_tmp.eval_expr(ExprOp('+', evaluator_tmp.pool[esp], unstack), {}) - return evaluator_tmp - if ret: - return None - - if not has_symb(m.arg[0]): - return None - dst = m.arg[0][x86_afs.symb].keys() - if len(dst)!=1: - return None - s = symbol_pool.getby_name(dst[0]) - if not s: - return None - - - if is_func_wrapper(s): - return evaluator_tmp - - - in_str_tmp = bin_stream(f, s.offset) - - job_done_tmp = [] - symbol_pool_tmp = asm_symbol_pool() - all_bloc_tmp = dis_bloc_all(x86mnemo, in_str_tmp, in_str_tmp.offset, job_done_tmp, symbol_pool_tmp, follow_call = False) - ret = quick_ret_analyse(s.offset, all_bloc_tmp) - #decal not found - if ret == None: - return ret - #decal is expr - if isinstance(ret, Expr): - #print ret - e = evaluator_tmp.eval_expr(ret, {}) - if type(e) in [int, long]: - print "eval esp oki!", e - ret = e - else: - return None - - #decal found int - if type(ret) in [int, long]: - evaluator_tmp.pool[esp]=evaluator_tmp.eval_expr(ExprOp('+', evaluator_tmp.pool[esp], ret), {}) - return evaluator_tmp - - - if m.m.name in jcc: - continue - - args = [dict_to_Expr(x, m.m.modifs) for x in m.arg] - - e = mnemo_func[m.m.name](*args) - - print "exprs:" - for x in e: - print x - evaluator_tmp.eval_instr(e) - if eip in evaluator_tmp.pool: - print evaluator_tmp.pool[eip] - ret = evaluator_tmp.eval_expr(eip, {}) - if ret == 'ret_addr': - m.stack_h_after = evaluator.simp_expr_arith_final(evaluator_tmp.pool[esp]) - - - return evaluator_tmp - - -def get_expr_diff(evaluator, a, b): - if evaluator == None: - return None - a_e = evaluator.simp_expr_arith_final(evaluator.eval_expr(a, {esp_i:0})) - b_e = evaluator.simp_expr_arith_final(evaluator.eval_expr(b, {esp_i:0})) - if not type(a_e) in [int, long] or not type(b_e) in [int, long]: - return None - return b_e-a_e - - - - - -def resolve_func(all_bloc_arg, symbol_pool, pool_import_func): - all_bloc_dict = dict([(b.label,b) for b in all_bloc_arg]) - while True: - fini = True - for b in all_bloc_arg: - force_stack_h = False - #if one son is known, inform his brothers - if b.eval_stop == None: - for next in b.bto: - if next.label in all_bloc_dict and all_bloc_dict[next.label].eval_start!=None: - b.eval_stop = all_bloc_dict[next.label].eval_start - force_stack_h = True - - for x in b.bto: - if x.label in all_bloc_dict and all_bloc_dict[x.label].eval_start==None: - all_bloc_dict[x.label].eval_start = all_bloc_dict[next.label].eval_start - fini = False - - if b.eval_start == None and b.eval_stop != None: - #try to find stack decal and inform start - print "tttt", hex(b.lines[0].offset) - - b.eval_start = b.eval_stop - tmp = stack_h(b, symbol_pool, pool_import_func) - print '_____',tmp - - decal = get_expr_diff(tmp, tmp.eval_expr(esp, {}),b.eval_stop.eval_expr(esp, {})) - - if decal == None: - b.eval_start = None - fdsfsd - for l in b.lines: - l.stack_h = None - continue - tmp.pool[esp] = ExprOp('+', b.eval_stop.pool[esp] ,decal) - b.eval_start = tmp - print 'decal found ', b.label, decal - fini = False - - if b.eval_start == None: - continue - - if b.eval_stop != None and not force_stack_h: - continue - - - print '*****eval:', b.label, b.eval_start.eval_expr(esp, {}) - b.eval_stop = stack_h(b, symbol_pool, pool_import_func) - if b.eval_stop == None: - continue - print 'propag:', b.label, b.eval_stop.eval_expr(esp, {}) - for next in b.bto: - if next.label in all_bloc_dict: - print next - all_bloc_dict[next.label].eval_start = b.eval_stop - fini = False - - if fini: - break - - lines = reduce(lambda x,y:x+y.lines, all_bloc_arg, []) - return None - - - -print '_'*10 -print resolve_func(all_bloc, symbol_pool, pool_import_func) -print 'result:' -for b in all_bloc: - #print b - if not b.eval_stop or not b.eval_start: - print b.label, 'unresolved bloc' - continue - - #print b.label, esp_init-b.eval_start.pool[esp] - #if eip in b.eval_stop.pool: - # print 'end at:', b.eval_stop.pool[eip], esp_init-b.eval_stop.pool[esp] - -lines = reduce(lambda x,y:x+y.lines, all_bloc, []) -lines = [(l.offset, l) for l in lines] -lines.sort() -for o, l in lines: - if not 'stack_h' in l.__dict__: - l.stack_h = None - print "%-20s"%str(l.stack_h), "%-20s"%str(l.stack_h_after), l - #print "%-5s"%str(l.stack_h) - #print l.arg - -""" -for b in all_bloc: - for l in b.lines: - if not 'stack_h' in l.__dict__: - l.stack_h = None - print l.stack_h, l -""" diff --git a/miasm/tools/hook_helper.py b/miasm/tools/hook_helper.py deleted file mode 100755 index da740e02..00000000 --- a/miasm/tools/hook_helper.py +++ /dev/null @@ -1,236 +0,0 @@ -#!/usr/bin/env python -# -# Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -from miasm.tools.pe_helper import * -from elfesteem import * -from miasm.core import bin_stream -from miasm.arch.ia32_sem import * -from miasm.core import asmbloc -from miasm.core import parse_asm -import re -import sys - - -class hooks(): - def name2str(self, n): - return "str_%s"%n - - def __init__(self, in_str, symbol_pool, gen_data_log_code = True): - self.in_str = in_str - self.all_bloc = [[]] - self.symbol_pool = symbol_pool - if gen_data_log_code: - self.all_bloc, self.symbol_pool = parse_asm.parse_txt(x86mnemo,''' - - f_name: - .string "out.txt" - f_handle: - .long 0x0 - my_critic_sec: - .long 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - write_ret: - .long 0xDEADBEEF - mtick: - .long 0xdeadbeef - - - log_name_data_len: - push ebp - mov ebp, esp - pushad - - - - mov eax, [f_handle] - test eax, eax - jnz write_file_2 - ;; create log file - push 0 - push 0x80 - push 4 - push 0 - push 1 - push 4 - lea ebx, [f_name] - push ebx - call [CreateFileA] - mov [f_handle], eax - - ;; create lock - push my_critic_sec - call [InitializeCriticalSection] - - write_file_2: - ;; lock - push my_critic_sec - call [EnterCriticalSection] - - - ;; write log name - push [ebp+8] - call [lstrlenA] - inc eax - - push 0 - lea ebx, [write_ret] - push ebx - push eax - push [ebp+8] - push [f_handle] - call [WriteFile] - - - ;; write tickcount - call [GetTickCount] - mov [mtick], eax - push 0 - lea ebx, [write_ret] - push ebx - push 4 - lea ebx, [mtick] - push ebx - push [f_handle] - call [WriteFile] - - - ;; write data size - push 0 - lea ebx, [write_ret] - push ebx - push 4 - lea ebx, [ebp+0x10] - push ebx - push [f_handle] - call [WriteFile] - - - ;;write data - push 0 - lea ebx, [write_ret] - push ebx - push [ebp+0x10] - push [ebp+0xc] - push [f_handle] - call [WriteFile] - - ;; unlock - push my_critic_sec - call [LeaveCriticalSection] - - - popad - mov esp, ebp - pop ebp - ret 0xc - - ''', symbol_pool = symbol_pool) - - - def add_hook(self, hook_ad, args_to_hook = {}, vars_decl = [], func_code = "", post_hook = ""): - wrapper_name = "wrapper_%.8X"%hook_ad - wrapper_log_name = "wrapper_log_%.8X"%hook_ad - patch_name = "patch_%.8X"%hook_ad - patch_end_name = "patch_end_%.8X"%hook_ad - - log_name = "log_%.8X"%hook_ad - - string_decl = [] - to_hook = args_to_hook.keys() - to_hook.sort() - - for s in to_hook: - if s.endswith('DONT_LOG'): - continue - string_decl.append('%s:\n.string "%s"'%(self.name2str(s), s)) - string_decl = "\n".join(string_decl) - - - lines, total_bytes = asmbloc.steal_bytes(self.in_str, x86_mn, hook_ad, 5) - erased_asm = "\n".join([str(l) for l in lines]) - print 'stolen lines' - print erased_asm - - self.symbol_pool.getby_name_create(patch_name).offset = hook_ad - self.symbol_pool.getby_name_create(patch_end_name).offset = hook_ad+total_bytes - - - asm_s = ''' -%s: - call %s -'''%(wrapper_name, wrapper_log_name)+erased_asm+"\n"+post_hook+"\n"+''' - jmp %s'''%(patch_end_name)+''' -%s: - ;;int 3 - pushad - pushfd - '''%wrapper_log_name - - for s in to_hook[::-1]: - asm_s += args_to_hook[s][1] - asm_s +=''' - call %s - popfd - popad - ret -'''%(log_name)+string_decl+'\n'+'\n'.join(vars_decl)+''' -%s: - push ebp - mov ebp, esp - -'''%(log_name) - asm_s += func_code +'\n' - - for i, c in enumerate(to_hook): - len_howto, arg_asm = args_to_hook[c] - if type(len_howto) in [int, long]: - asm_s += ''' - push %d - '''%(len_howto) - elif isinstance(len_howto, str): - asm_s += len_howto - - if not c.endswith('DONT_LOG'): - asm_s += ''' - push [ebp+%d] - push %s - call log_name_data_len - '''%(8+4*i, self.name2str(c)) - - - asm_s +=""" - pop ebp - ret %d - - """%(len(to_hook)*4) - - asm_s +=""" - %s: - jmp %s - %s: - .split - """%(patch_name, wrapper_name, patch_end_name) - - #print asm_s - - all_bloc, self.symbol_pool = parse_asm.parse_txt(x86mnemo,asm_s, symbol_pool = self.symbol_pool) - self.all_bloc[0] += all_bloc[0] - return log_name - - - - diff --git a/miasm/tools/modint.py b/miasm/tools/modint.py deleted file mode 100644 index b1e5f0f6..00000000 --- a/miasm/tools/modint.py +++ /dev/null @@ -1,256 +0,0 @@ -import os - -class moduint(object): - def __init__(self, arg): - if isinstance(arg, moduint): - arg = arg.arg - self.arg = arg%self.__class__.limit - assert(self.arg >= 0 and self.arg < self.__class__.limit) - def __repr__(self): - return self.__class__.__name__+'('+hex(self.arg)+')' - def __hash__(self): - return hash(self.arg) - @classmethod - def maxcast(c1, c2): - c2 = c2.__class__ - if c1.size > c2.size: - return c1 - else: - return c2 - def __cmp__(self, y): - if isinstance(y, moduint): - return cmp(self.arg, y.arg) - else: - return cmp(self.arg, y) - def __add__(self, y): - if isinstance(y, moduint): - cls = self.maxcast(y) - return cls(self.arg + y.arg) - else: - return self.__class__(self.arg + y) - def __and__(self, y): - if isinstance(y, moduint): - cls = self.maxcast(y) - return cls(self.arg & y.arg) - else: - return self.__class__(self.arg & y) - def __div__(self, y): - if isinstance(y, moduint): - cls = self.maxcast(y) - return cls(self.arg / y.arg) - else: - return self.__class__(self.arg / y) - def __int__(self): - return int(self.arg) - def __long__(self): - return long(self.arg) - def __invert__(self): - return self.__class__(~self.arg) - def __lshift__(self, y): - if isinstance(y, moduint): - cls = self.maxcast(y) - return cls(self.arg << y.arg) - else: - return self.__class__(self.arg << y) - def __mod__(self, y): - if isinstance(y, moduint): - cls = self.maxcast(y) - return cls(self.arg % y.arg) - else: - return self.__class__(self.arg % y) - def __mul__(self, y): - if isinstance(y, moduint): - cls = self.maxcast(y) - return cls(self.arg * y.arg) - else: - return self.__class__(self.arg * y) - def __neg__(self): - return self.__class__(-self.arg) - def __or__(self, y): - if isinstance(y, moduint): - cls = self.maxcast(y) - return cls(self.arg | y.arg) - else: - return self.__class__(self.arg | y) - def __radd__(self, y): - return self.__add__(y) - def __rand__(self, y): - return self.__and__(y) - def __rdiv__(self, y): - if isinstance(y, moduint): - cls = self.maxcast(y) - return cls(y.arg / self.arg) - else: - return self.__class__(y / self.arg) - def __rlshift__(self, y): - if isinstance(y, moduint): - cls = self.maxcast(y) - return cls(y.arg << self.arg) - else: - return self.__class__(y << self.arg) - def __rmod__(self, y): - if isinstance(y, moduint): - cls = self.maxcast(y) - return cls(y.arg % self.arg ) - else: - return self.__class__(y % self.arg) - def __rmul__(self, y): - return self.__mul__(y) - def __ror__(self, y): - return self.__or__(y) - def __rrshift__(self, y): - if isinstance(y, moduint): - cls = self.maxcast(y) - return cls(y.arg >> self.arg ) - else: - return self.__class__(y >> self.arg) - def __rshift__(self, y): - if isinstance(y, moduint): - cls = self.maxcast(y) - return cls(self.arg >> y.arg) - else: - return self.__class__(self.arg >> y) - def __rsub__(self, y): - if isinstance(y, moduint): - cls = self.maxcast(y) - return cls(y.arg - self.arg) - else: - return self.__class__(y - self.arg) - def __rxor__(self, y): - return self.__xor__(y) - def __sub__(self, y): - if isinstance(y, moduint): - cls = self.maxcast(y) - return cls(self.arg - y.arg) - else: - return self.__class__(self.arg - y) - def __xor__(self, y): - if isinstance(y, moduint): - cls = self.maxcast(y) - return cls(self.arg ^ y.arg) - else: - return self.__class__(self.arg ^ y) - def __hex__(self): - return hex(self.arg) - def __abs__(self): - return abs(self.arg) - def __rpow__(self, v): - return v**self.arg - def __pow__(self, v): - return self.__class__(self.arg**v) - -class modint(moduint): - def __init__(self, arg): - if isinstance(arg, moduint): - arg = arg.arg - a = arg%self.__class__.limit - if a >= self.__class__.limit/2: - a -= self.__class__.limit - self.arg = a - assert(self.arg >= -self.__class__.limit/2 and self.arg < self.__class__.limit) - - -class uint1(moduint): - size = 1 - limit = 1<<size - -class uint8(moduint): - size = 8 - limit = 1<<size - -class uint16(moduint): - size = 16 - limit = 1<<size - -class uint32(moduint): - size = 32 - limit = 1<<size - -class uint64(moduint): - size = 64 - limit = 1<<size - -class uint128(moduint): - size = 128 - limit = 1<<size - -class int8(modint): - size = 8 - limit = 1<<size - -class int16(modint): - size = 16 - limit = 1<<size - -class int32(modint): - size = 32 - limit = 1<<size - -class int64(modint): - size = 64 - limit = 1<<size - -class int128(modint): - size = 128 - limit = 1<<size - - - -if __name__ == "__main__": - a = uint8(0x42) - b = uint8(0xFF) - c = uint8(0x4) - - d = uint1(0) - e = uint1(1) - - f = uint8(0x1) - - - print a, b, c - print a+b, a+c, b+c - print a == a, a == b, a == 0x42, a == 0x78 - print a != b, a != a - print d, e - print d+e, d+d, e+e, e+e+e, e+0x11 - - assert(f == 1) - assert(f+1 == 2) - assert(2 == f+1) - assert(f+0xff==0) - assert(f&0==0) - assert(f&0xff==f) - assert(0xff&f==f) - assert(f/1==f) - assert(1/f==f) - assert(int(f)==1) - assert(long(f)==1) - assert(~f==0xfe) - assert(f<<1==2) - assert(f<<8==0) - assert(1<<f==2) - assert(0x80<<f==0) - assert(f%2==f) - assert(f%1==0) - assert(2%f==0) - assert(f*2==2) - assert(2*f==2) - assert(f*f==1) - assert(f*uint8(0x80)==0x80) - assert(-f==0xff) - assert(f|f==f) - assert(f|0==f) - assert(2|f==3) - assert(f>>0==f) - assert(f>>1==0) - assert(0x10>>f==0x8) - assert(0x100>>f==0x80) # XXXX - assert(0x1000>>f==0x0) # XXXX - assert(f^f==0) - assert(f^0==f) - assert(0^f==f) - assert(1^f==0) - - print e+c, c+e, c-e, e-c - print 1000*a - print hex(a) diff --git a/miasm/tools/nux_api.py b/miasm/tools/nux_api.py deleted file mode 100644 index 569a0f3b..00000000 --- a/miasm/tools/nux_api.py +++ /dev/null @@ -1,1113 +0,0 @@ -# -# Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -from to_c_helper import * -import struct -import inspect -import socket -import time -import random -import os -import sys -import string - -ctime_str = None -def fd_generator(): - i = 0 - while True: - yield i - i+=1 - -fd_gen = fd_generator() -fd_stdin = fd_gen.next() -fd_stout = fd_gen.next() - - -socket_pool = {} -def get_str_ansi(ad_str, max_l = None): - l = 0 - tmp = ad_str - while vm_get_str(tmp, 1) != "\x00": - tmp +=1 - l+=1 - if max_l and l > max_l: - break - return vm_get_str(ad_str, l) - -def get_dw_stack(offset): - esp = vm_get_gpreg()['esp'] - return updw(vm_get_str(esp+offset, 4)) - - -def whoami(): - return inspect.stack()[1][3] - - -def xxx___libc_start_main(): - ret_ad = vm_pop_uint32_t() - arg_1 = get_dw_stack(0) - arg_2 = get_dw_stack(4) - arg_3 = get_dw_stack(4) - arg_4 = get_dw_stack(8) - arg_5 = get_dw_stack(0xc) - arg_6 = get_dw_stack(0x10) - arg_7 = get_dw_stack(0x14) - arg_8 = get_dw_stack(0x18) - - print whoami(), hex(ret_ad), hex(arg_1), hex(arg_2), hex(arg_3), hex(arg_4), hex(arg_5), hex(arg_6), hex(arg_7), hex(arg_8) - regs = vm_get_gpreg() - regs['eip'] = arg_1 # main - # TODO XXX should push argc, argv here - vm_set_gpreg(regs) - - vm_push_uint32_t(0x1337beef) - - - -def xxx_memset(): - ret_ad = vm_pop_uint32_t() - arg_addr = get_dw_stack(0) - arg_c = get_dw_stack(4) - arg_size = get_dw_stack(8) - - print whoami(), hex(ret_ad), '(', hex(arg_addr), arg_c, arg_size, ')' - vm_set_mem(arg_addr, chr(arg_c)*arg_size) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = arg_addr - vm_set_gpreg(regs) - -def xxx_memcpy(): - ret_ad = vm_pop_uint32_t() - dst = get_dw_stack(0) - src = get_dw_stack(4) - size = get_dw_stack(8) - - print whoami(), hex(ret_ad), '(', hex(dst), hex(src), hex(size), ')' - - s = vm_get_str(src, size) - vm_set_mem(dst, s) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = dst - vm_set_gpreg(regs) - -def xxx_memcmp(): - ret_ad = vm_pop_uint32_t() - s1 = get_dw_stack(0) - s2 = get_dw_stack(4) - size = get_dw_stack(8) - - print whoami(), hex(ret_ad), '(', hex(s1), hex(s2), hex(size), ')' - - s1s = vm_get_str(s1, size) - s2s = vm_get_str(s2, size) - print repr(s1s) - print repr(s2s) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = cmp(s1s, s2s) - vm_set_gpreg(regs) - - -def xxx_printf(): - ret_ad = vm_pop_uint32_t() - fmt_p = get_dw_stack(0) - fmt_s = get_str_ansi(fmt_p) - - print whoami(), hex(ret_ad), '(', repr(fmt_s), ')' - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def xxx_socket(): - ret_ad = vm_pop_uint32_t() - arg_domain = get_dw_stack(0) - arg_type = get_dw_stack(4) - arg_proto = get_dw_stack(8) - - print whoami(), hex(ret_ad), '(', arg_domain, arg_type, arg_proto,')' - fd = fd_gen.next() - regs = vm_get_gpreg() - regs['eip'] = ret_ad - #regs['eax'] = fd - # XXX DANGEROUS - s = socket.socket(arg_domain, arg_type, arg_proto) - socket_pool[s.fileno()] = s - regs['eax'] = s.fileno() - - - vm_set_gpreg(regs) - - -def xxx_htonl(): - ret_ad = vm_pop_uint32_t() - arg_dw = get_dw_stack(0) - - print whoami(), hex(ret_ad), '(', arg_dw,')' - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = socket.htonl(arg_dw) - vm_set_gpreg(regs) - -def xxx_htons(): - ret_ad = vm_pop_uint32_t() - arg_dw = get_dw_stack(0) - - print whoami(), hex(ret_ad), '(', arg_dw,')' - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = socket.htons(arg_dw) - vm_set_gpreg(regs) - -def xxx_bind(): - ret_ad = vm_pop_uint32_t() - arg_sockfd = get_dw_stack(0) - arg_addr = get_dw_stack(4) - arg_addrlen = get_dw_stack(8) - - print whoami(), hex(ret_ad), '(', arg_sockfd, hex(arg_addr), arg_addrlen,')' - - addr_s = vm_get_str(arg_addr, arg_addrlen) - print repr(addr_s) - sin_f, sin_port, sin_addr = struct.unpack('>HHL', addr_s[:8]) - print repr(sin_f), repr(sin_port), repr(sin_addr) - # XXX - #sin_port = 2222 - socket_pool[arg_sockfd].bind(('', sin_port)) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def xxx_listen(): - ret_ad = vm_pop_uint32_t() - arg_sockfd = get_dw_stack(0) - arg_backlog = get_dw_stack(4) - - print whoami(), hex(ret_ad), '(', arg_sockfd, arg_backlog, ')' - socket_pool[arg_sockfd].listen(arg_backlog) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def xxx_accept(): - ret_ad = vm_pop_uint32_t() - arg_sockfd = get_dw_stack(0) - arg_addr = get_dw_stack(4) - arg_addrlen = get_dw_stack(8) - - print whoami(), hex(ret_ad), '(', arg_sockfd, hex(arg_addr), arg_addrlen, ')' - conn, addr = socket_pool[arg_sockfd].accept() - socket_pool[conn.fileno()] = conn - - print 'ACCEPT', conn, addr - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = conn.fileno() - vm_set_gpreg(regs) - - -def xxx_puts(): - ret_ad = vm_pop_uint32_t() - arg_s = get_dw_stack(0) - - print whoami(), hex(ret_ad), '(', arg_s, ')' - s = get_str_ansi(arg_s) - print 'PUTS' - print s - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def xxx_putchar(): - ret_ad = vm_pop_uint32_t() - arg_c = get_dw_stack(0) - - print whoami(), hex(ret_ad), '(', arg_c, ')' - print chr(arg_c&0xff) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def xxx__IO_putc(): - ret_ad = vm_pop_uint32_t() - arg_c = get_dw_stack(0) - arg_stream = get_dw_stack(4) - - print whoami(), hex(ret_ad), '(', hex(arg_stream), hex(arg_c), ')' - socket_pool[arg_stream].write(chr(arg_c&0xFF)) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - - -def xxx_recv(): - ret_ad = vm_pop_uint32_t() - arg_sockfd = get_dw_stack(0) - arg_buf = get_dw_stack(4) - arg_len = get_dw_stack(8) - arg_flags = get_dw_stack(12) - - print whoami(), hex(ret_ad), '(', arg_sockfd, arg_buf, arg_len, arg_sockfd, ')' - buf = socket_pool[arg_sockfd].recv(arg_len) - - print 'RECV', repr(buf) - vm_set_mem(arg_buf, buf) - - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - if buf: - regs['eax'] = len(buf) - else: - regs['eax'] = -1 - vm_set_gpreg(regs) - - -def xxx_send(): - ret_ad = vm_pop_uint32_t() - arg_sockfd = get_dw_stack(0) - arg_buf = get_dw_stack(4) - arg_len = get_dw_stack(8) - arg_flags = get_dw_stack(12) - - print whoami(), hex(ret_ad), '(', arg_sockfd, arg_buf, arg_len, arg_sockfd, ')' - buf = vm_get_str(arg_buf, arg_len) - try: - socket_pool[arg_sockfd].send(buf) - except: - print 'send fail' - buf = "" - - print 'SEND', repr(buf) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = len(buf) - vm_set_gpreg(regs) - -def xxx_close(): - ret_ad = vm_pop_uint32_t() - arg_sockfd = get_dw_stack(0) - - print whoami(), hex(ret_ad), '(', arg_sockfd, ')' - socket_pool[arg_sockfd].close() - - print 'close', repr(arg_sockfd) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - - -def xxx_signal(): - ret_ad = vm_pop_uint32_t() - arg_signum = get_dw_stack(0) - arg_sigh = get_dw_stack(4) - - print whoami(), hex(ret_ad), '(', arg_signum, hex(arg_sigh), ')' - # XXX todo - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def xxx_setsockopt(): - ret_ad = vm_pop_uint32_t() - arg_sockfd = get_dw_stack(0) - arg_level = get_dw_stack(4) - arg_optname = get_dw_stack(8) - arg_optval = get_dw_stack(12) - arg_optlen = get_dw_stack(16) - - print whoami(), hex(ret_ad), '(', arg_sockfd, hex(arg_level), arg_optname, hex(arg_optval), arg_optlen, ')' - opt_val = vm_get_str(arg_optval, arg_optlen) - print repr(opt_val) - - # Translation between C and python values - # #define SOL_SOCKET 0xffff - dct_level = {0xffff:1, 1:1} - dct_argname = {4:2, 2:2} - arg_level = dct_level[arg_level] - arg_optname = dct_argname[arg_optname] - - print repr(arg_level), repr(arg_optname), repr(opt_val) - socket_pool[arg_sockfd].setsockopt(arg_level, arg_optname, opt_val) - # XXX todo - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - - -def xxx_getpwnam(): - ret_ad = vm_pop_uint32_t() - arg_name = get_dw_stack(0) - - print whoami(), hex(ret_ad), '(', hex(arg_name), ')' - s = get_str_ansi(arg_name) - print repr(s) - # create fake struct - - name = s - password = "pwd_"+name - rname = name - udir = "/home/"+name - ushell = "shell_"+name - - ad = vm_get_memory_page_max_address() - - vm_add_memory_page(ad, PAGE_READ|PAGE_WRITE, 0x1000*"\x00") - ad = (ad+0xfff) & 0xfffff000 - s = struct.pack('IIIIIII', - ad+0x100, - ad+0x200, - 1337, - 1337, - ad+0x300, - ad+0x400, - ad+0x500) - - s = struct.pack('256s256s256s256s256s256s', s, name, password, rname, udir, ushell) - print repr(s) - vm_set_mem(ad, s) - - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ad - vm_set_gpreg(regs) - -def xxx_getuid(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad), '(', ')' - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1337 - vm_set_gpreg(regs) - -def xxx_getgid(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad), '(', ')' - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1337 - vm_set_gpreg(regs) - -def xxx_initgroups(): - ret_ad = vm_pop_uint32_t() - arg_name = get_dw_stack(0) - arg_group = get_dw_stack(4) - - print whoami(), hex(ret_ad), '(', hex(arg_name), arg_group, ')' - s = get_str_ansi(arg_name) - print repr(s) - # XXX todo - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def xxx_setresgid(): - ret_ad = vm_pop_uint32_t() - arg_ruid = get_dw_stack(0) - arg_euid = get_dw_stack(4) - arg_suid = get_dw_stack(8) - - print whoami(), hex(ret_ad), '(', arg_ruid, arg_euid, arg_suid, ')' - # XXX todo - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def xxx_setresuid(): - ret_ad = vm_pop_uint32_t() - arg_ruid = get_dw_stack(0) - arg_euid = get_dw_stack(4) - arg_suid = get_dw_stack(8) - - print whoami(), hex(ret_ad), '(', arg_ruid, arg_euid, arg_suid, ')' - # XXX todo - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def xxx_getegid(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad), '(', ')' - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1337 - vm_set_gpreg(regs) - -def xxx_geteuid(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad), '(', ')' - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1337 - vm_set_gpreg(regs) - -def xxx_chdir(): - ret_ad = vm_pop_uint32_t() - arg_path = get_dw_stack(0) - - print whoami(), hex(ret_ad), '(', hex(arg_path), ')' - if arg_path: - s = get_str_ansi(arg_path) - else: - s = "default_path" - print repr(s) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - - -def xxx_time(): - ret_ad = vm_pop_uint32_t() - arg_time = get_dw_stack(0) - print whoami(), hex(ret_ad), '(', hex(arg_time), ')' - - t = int(time.time()) - if arg_time: - vm_set_mem(arg_time, pdw(t)) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = t - vm_set_gpreg(regs) - -def xxx_ctime(): - global ctime_str - ret_ad = vm_pop_uint32_t() - arg_time = get_dw_stack(0) - print whoami(), hex(ret_ad), '(', hex(arg_time), ')' - - if not ctime_str: - ad = vm_get_memory_page_max_address() - vm_add_memory_page(ad, PAGE_READ|PAGE_WRITE, 0x1000*"\x00") - ctime_str = ad - - t = vm_get_str(arg_time, 4) - t = updw(t) - print hex(t) - s = time.ctime(t) - vm_set_mem(ctime_str, s) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ctime_str - vm_set_gpreg(regs) - -def xxx_srand(): - ret_ad = vm_pop_uint32_t() - arg_seed = get_dw_stack(0) - print whoami(), hex(ret_ad), '(', hex(arg_seed), ')' - - random.seed(arg_seed) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def xxx_rand(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad), '(', ')' - - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = random.randint(0, 0xffffffff) - vm_set_gpreg(regs) - -def xxx_fork(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad), '(', ')' - - - ret = os.fork() - #ret= 0 - print 'FORK', ret - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ret - vm_set_gpreg(regs) - - - -def xxx_strncpy(): - ret_ad = vm_pop_uint32_t() - arg_dst = get_dw_stack(0) - arg_src = get_dw_stack(4) - arg_n = get_dw_stack(8) - - print whoami(), hex(ret_ad), '(', hex(arg_dst), hex(arg_src), arg_n, ')' - src = get_str_ansi(arg_src, arg_n) - src = (src+'\x00'*arg_n)[:arg_n] - - vm_set_mem(arg_dst, src) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = arg_dst - vm_set_gpreg(regs) - -def xxx_strlen(): - ret_ad = vm_pop_uint32_t() - arg_src = get_dw_stack(0) - - print whoami(), hex(ret_ad), '(', hex(arg_src), ')' - src = get_str_ansi(arg_src) - print repr(src) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = len(src) - vm_set_gpreg(regs) - - -def xxx_read(): - ret_ad = vm_pop_uint32_t() - arg_fd = get_dw_stack(0) - arg_buf = get_dw_stack(4) - arg_len = get_dw_stack(8) - - print whoami(), hex(ret_ad), '(', arg_fd, arg_buf, arg_len, ')' - buf = os.read(arg_fd, arg_len) - - print 'RECV', repr(buf) - vm_set_mem(arg_buf, buf) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = len(buf) - vm_set_gpreg(regs) - -def xxx_strcmp(): - ret_ad = vm_pop_uint32_t() - arg_s1 = get_dw_stack(0) - arg_s2 = get_dw_stack(4) - - print whoami(), hex(ret_ad), '(', hex(arg_s1), hex(arg_s2), ')' - s1 = get_str_ansi(arg_s1) - s2 = get_str_ansi(arg_s2) - print repr(s1), repr(s2) - if s1 == s2: - ret = 0 - elif s1 > s2: - ret = 1 - else: - ret = -1 - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ret - vm_set_gpreg(regs) - -def xxx_exit(): - ret_ad = vm_pop_uint32_t() - arg_code = get_dw_stack(0) - - print whoami(), hex(ret_ad), '(', hex(arg_code), ')' - - sys.exit(arg_code) - -def xxx__exit(): - xxx_exit() - - -def xxx_fdopen(): - ret_ad = vm_pop_uint32_t() - arg_fd = get_dw_stack(0) - arg_mode = get_dw_stack(4) - - print whoami(), hex(ret_ad), '(', arg_fd, hex(arg_mode), ')' - m = get_str_ansi(arg_mode) - print repr(m) - - s = os.fdopen(arg_fd, m, 0) - socket_pool[id(s)] = s - - - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = id(s) - vm_set_gpreg(regs) - -def xxx_fclose(): - ret_ad = vm_pop_uint32_t() - arg_fd = get_dw_stack(0) - - print whoami(), hex(ret_ad), '(', arg_fd, ')' - socket_pool[arg_fd].close() - - - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def parse_fmt(s): - fmt = s[:]+"\x00" - out = [] - i = 0 - while i < len(fmt): - c = fmt[i] - if c != "%": - i+=1 - continue - if fmt[i+1] == "%": - i+=2 - continue - j = 0 - i+=1 - while fmt[i+j] in "0123456789$.": - j+=1 - if fmt[i+j] in ['l']: - j +=1 - if fmt[i+j] == "h": - x = fmt[i+j:i+j+2] - else: - x = fmt[i+j] - i+=j - out.append(x) - return out - - -def xxx_fprintf(): - ret_ad = vm_pop_uint32_t() - arg_stream = get_dw_stack(0) - arg_fmt = get_dw_stack(4) - - print whoami(), hex(ret_ad), '(', arg_stream, hex(arg_fmt), ')' - s = get_str_ansi(arg_fmt) - print repr(s) - - fmt_a = parse_fmt(s) - offset = 8 - args = [] - for i, x in enumerate(fmt_a): - a = get_dw_stack(offset+4*i) - if x == "s": - a = get_str_ansi(a) - args.append(a) - print repr(s), repr(args) - - oo = s%(tuple(args)) - print repr(oo) - socket_pool[arg_stream].write(oo) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = len(oo) - vm_set_gpreg(regs) - -def xxx_snprintf(): - ret_ad = vm_pop_uint32_t() - dst = get_dw_stack(0) - size = get_dw_stack(4) - arg_fmt = get_dw_stack(8) - - print whoami(), hex(ret_ad), '(', hex(dst), hex(size), hex(arg_fmt), ')' - s = get_str_ansi(arg_fmt) - fmt_a = parse_fmt(s) - offset = 0xc - args = [] - for i, x in enumerate(fmt_a): - a = get_dw_stack(offset+4*i) - if x == "s": - a = get_str_ansi(a) - args.append(a) - print repr(s), repr(args) - - oo = s%(tuple(args)) - print repr(oo) - vm_set_mem(dst, oo) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = len(oo) - vm_set_gpreg(regs) - -def xxx_isprint(): - ret_ad = vm_pop_uint32_t() - c = get_dw_stack(0) - print whoami(), hex(ret_ad), '(', hex(c), ')' - - if chr(c&0xFF) in string.printable: - ret = 1 - else: - ret = 0 - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ret - vm_set_gpreg(regs) - - -def xxx_fgets(): - ret_ad = vm_pop_uint32_t() - arg_buf = get_dw_stack(0) - arg_size = get_dw_stack(4) - arg_stream = get_dw_stack(8) - - print whoami(), hex(ret_ad), '(', hex(arg_buf), arg_size, arg_stream, ')' - buf = "" - while len(buf) < arg_size-1: - buf += socket_pool[arg_stream].read(1) - if not buf: - break - if "\n" in buf: - break - if "\x00" in buf: - break - if buf: - buf += "\x00" - print repr(buf) - vm_set_mem(arg_buf, buf) - - if not buf: - arg_buf = 0 - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = arg_buf - vm_set_gpreg(regs) - -def xxx_fwrite(): - ret_ad = vm_pop_uint32_t() - arg_buf = get_dw_stack(0) - arg_size = get_dw_stack(4) - arg_nmemb = get_dw_stack(8) - arg_stream = get_dw_stack(12) - - print whoami(), hex(ret_ad), '(', hex(arg_buf), arg_size, arg_nmemb, arg_stream, ')' - - buf = vm_get_str(arg_buf, arg_size*arg_nmemb) - print repr(buf) - socket_pool[arg_stream].write(buf) - """ - except: - print "err in write" - buf = "" - """ - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = len(buf) - vm_set_gpreg(regs) - -def xxx_fflush(): - ret_ad = vm_pop_uint32_t() - arg_stream = get_dw_stack(0) - - print whoami(), hex(ret_ad), '(', arg_stream, ')' - - socket_pool[arg_stream].flush() - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def xxx_malloc(): - ret_ad = vm_pop_uint32_t() - arg_size = get_dw_stack(0) - - print whoami(), hex(ret_ad), '(', hex(arg_size), ')' - - - ad = vm_get_memory_page_max_address() - ad = (ad+0xfff) & 0xfffff000 - vm_add_memory_page(ad, PAGE_READ|PAGE_WRITE, arg_size*"\x00") - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ad - vm_set_gpreg(regs) - -def xxx_calloc(): - xxx_malloc() - -def xxx_free(): - ret_ad = vm_pop_uint32_t() - ptr = get_dw_stack(0) - - print whoami(), hex(ret_ad), '(', hex(ptr), ')' - - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def xxx_bzero(): - ret_ad = vm_pop_uint32_t() - arg_addr = get_dw_stack(0) - arg_size = get_dw_stack(4) - - print whoami(), hex(ret_ad), '(', hex(arg_addr), arg_size, ')' - - vm_set_mem(arg_addr, "\x00"*arg_size) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - - -def xxx_fopen(): - ret_ad = vm_pop_uint32_t() - arg_path = get_dw_stack(0) - arg_mode = get_dw_stack(4) - - print whoami(), hex(ret_ad), '(', arg_path, hex(arg_mode), ')' - path = get_str_ansi(arg_path) - m = get_str_ansi(arg_mode) - print repr(path), repr(m) - path = "/home/serpilliere/projet/pelogger/user.db" - try: - s = open(path, m, 0) - socket_pool[id(s)] = s - s= id(s) - except: - s = 0 - - - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = s - vm_set_gpreg(regs) - -def xxx_fread(): - ret_ad = vm_pop_uint32_t() - arg_buf = get_dw_stack(0) - arg_size = get_dw_stack(4) - arg_nmemb = get_dw_stack(8) - arg_stream = get_dw_stack(12) - - print whoami(), hex(ret_ad), '(', hex(arg_buf), hex(arg_size), hex(arg_nmemb), hex(arg_stream), ')' - - buf = socket_pool[arg_stream].read(arg_size*arg_nmemb) - print repr(buf) - print "ret", arg_nmemb - vm_set_mem(arg_buf, buf) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = arg_nmemb - vm_set_gpreg(regs) - - -def xxx_fseek(): - ret_ad = vm_pop_uint32_t() - stream = get_dw_stack(0) - offset = get_dw_stack(4) - whence = get_dw_stack(8) - - print whoami(), hex(ret_ad), '(', hex(stream), hex(offset), hex(whence), ')' - - buf = socket_pool[stream].seek(offset, whence ) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - - -def xxx_rewind(): - ret_ad = vm_pop_uint32_t() - arg_stream = get_dw_stack(0) - - print whoami(), hex(ret_ad), '(', hex(arg_stream), ')' - - socket_pool[arg_stream].seek(0) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - - -def xxx_atoi(): - ret_ad = vm_pop_uint32_t() - arg_nptr = get_dw_stack(0) - - print whoami(), hex(ret_ad), '(', arg_nptr, ')' - buf = get_str_ansi(arg_nptr) - print repr(buf) - i = int(buf) - print i - - - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = i - vm_set_gpreg(regs) - - -def xxx_strcpy(): - ret_ad = vm_pop_uint32_t() - arg_dst = get_dw_stack(0) - arg_src = get_dw_stack(4) - - print whoami(), hex(ret_ad), '(', hex(arg_dst), hex(arg_src), ')' - src = get_str_ansi(arg_src) - vm_set_mem(arg_dst, src+"\x00") - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = arg_dst - vm_set_gpreg(regs) - - -def my_vprintf(arg_fmt, arg_ap): - fmt = get_str_ansi(arg_fmt) - #print repr(fmt) - - fmt_a = parse_fmt(fmt) - - args = [] - for i, x in enumerate(fmt_a): - a = updw(vm_get_str(arg_ap+4*i, 4)) - if x == "s": - a = get_str_ansi(a) - args.append(a) - - - s = fmt%(tuple(args))+"\x00" - #print repr(s) - return s - -def xxx_vfprintf(): - ret_ad = vm_pop_uint32_t() - arg_stream = get_dw_stack(0) - size = get_dw_stack(4) - arg_fmt = get_dw_stack(8) - arg_ap = get_dw_stack(0xc) - - print whoami(), hex(ret_ad), '(', hex(arg_stream), hex(size), hex(arg_fmt), hex(arg_ap), ')' - s = my_vprintf(arg_fmt, arg_ap) - ad = vm_get_memory_page_max_address() - ad = (ad+0xfff) & 0xfffff000 - - socket_pool[arg_stream].write(s) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = len(s) - vm_set_gpreg(regs) - - -def xxx_vasprintf(): - ret_ad = vm_pop_uint32_t() - arg_strp = get_dw_stack(0) - arg_fmt = get_dw_stack(4) - arg_ap = get_dw_stack(8) - - print whoami(), hex(ret_ad), '(', hex(arg_strp), hex(arg_fmt), hex(arg_ap), ')' - s = my_vprintf(arg_fmt, arg_ap) - print repr(s) - ad = vm_get_memory_page_max_address() - ad = (ad+0xfff) & 0xfffff000 - vm_add_memory_page(ad, PAGE_READ|PAGE_WRITE, (len(s)+1)*"\x00") - - vm_set_mem(arg_strp, pdw(ad)) - vm_set_mem(ad, s) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = len(fmt) - vm_set_gpreg(regs) - - -def xxx_sprintf(): - ret_ad = vm_pop_uint32_t() - arg_str = get_dw_stack(0) - arg_fmt = get_dw_stack(4) - - print whoami(), hex(ret_ad), '(', hex(arg_str), hex(arg_fmt), ')' - s = get_str_ansi(arg_fmt) - print repr(s) - fmt_a = parse_fmt(s) - offset = 8 - args = [] - for i, x in enumerate(fmt_a): - a = get_dw_stack(offset+4*i) - if x == "s": - a = get_str_ansi(a) - args.append(a) - print repr(s), repr(args) - - oo = s%(tuple(args)) - print repr(oo) - vm_set_mem(arg_str, oo+"\x00") - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = len(oo) - vm_set_gpreg(regs) - - -def xxx_strcat(): - ret_ad = vm_pop_uint32_t() - arg_dst = get_dw_stack(0) - arg_src = get_dw_stack(4) - - print whoami(), hex(ret_ad), '(', hex(arg_dst), hex(arg_src), ')' - src = get_str_ansi(arg_src) - dst = get_str_ansi(arg_dst) - print repr(dst), repr(src) - vm_set_mem(arg_dst, dst+src+'\x00') - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = arg_dst - vm_set_gpreg(regs) - -def xxx_strncmp(): - ret_ad = vm_pop_uint32_t() - arg_s1 = get_dw_stack(0) - arg_s2 = get_dw_stack(4) - arg_n = get_dw_stack(8) - - print whoami(), hex(ret_ad), '(', hex(arg_s1), hex(arg_s2), arg_n, ')' - - s1 = get_str_ansi(arg_s1, arg_n) - s2 = get_str_ansi(arg_s2, arg_n) - print repr(s1), repr(s2) - if s1 == s2: - ret = 0 - elif s1 > s2: - ret = 1 - else: - ret = -1 - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ret - vm_set_gpreg(regs) diff --git a/miasm/tools/pe_helper.py b/miasm/tools/pe_helper.py deleted file mode 100644 index b3c70278..00000000 --- a/miasm/tools/pe_helper.py +++ /dev/null @@ -1,743 +0,0 @@ -# -# Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -from elfesteem import * -from elfesteem import pe -from elfesteem import cstruct - -from miasm.arch.ia32_arch import * -from miasm.tools.emul_helper import * -from miasm.arch.ia32_sem import * -import struct -import miasm.core.asmbloc -import miasm.core.bin_stream -import os -import re -try: - from miasm.tools import to_c_helper -except ImportError: - print "WARNING: cannot import to_c_helper, skipping" -from miasm.core import bin_stream -from collections import defaultdict - -pe_cache = {} -def pe_from_name(n): - global pe_cache - - my_path = 'win_dll/' - all_pe = os.listdir(my_path) - if not n in all_pe: - print 'cannot find PE', n - return None - - pe_name = my_path+n - if pe_name in pe_cache: - return pe_cache[pe_name] - e = pe_init.PE(open(pe_name, 'rb').read()) - pe_cache[pe_name] = e - return e - - -def func_from_import(pe_name, func): - e = pe_from_name(pe_name) - - if not e or not e.DirExport: - print 'no export dir found' - return None, None - - - found = None - if type(func) is str: - for i, n in enumerate(e.DirExport.f_names): - if n.name.name == func: - found = e.DirExport.f_address[e.DirExport.f_nameordinals[i].ordinal].rva - break - - elif type(func) in [int, long]: - for i, n in enumerate(e.DirExport.f_names): - if e.DirExport.f_nameordinals[i].ordinal+e.DirExport.expdesc.base == func: - found = e.DirExport.f_address[e.DirExport.f_nameordinals[i].ordinal].rva - break - else: - raise ValueError('unknown fund type', func) - - #XXX todo: test if redirected export - return e, found - - -def get_sectionname(e, offset): - section = e.getsectionbyvad(offset) - if section == None: - return None - if isinstance(e, elf_init.ELF): - return section.sh.name - elif isinstance(e, pe_init.PE): - return section.name - else: - raise ValueError("TODO") - -def is_rva_in_code_section(e, rva): - s = e.getsectionbyrva(rva) - return s.flags&0x20!=0 - -def guess_func_destack_dis(e, ad): - job_done = set() - symbol_pool = asmbloc.asm_symbol_pool() - in_str = bin_stream(e.virt) - - all_bloc = asmbloc.dis_bloc_all(x86_mn, in_str, ad, job_done, symbol_pool, follow_call = False, patch_instr_symb = False) - return guess_func_destack(all_bloc) - - -def guess_imports_ret_unstack(e): - unresolved = set() - resolved = {} - redirected = {} - for i,s in enumerate(e.DirImport.impdesc): - l = "%2d %-25s %s"%(i, repr(s.dlldescname) ,repr(s)) - libname = s.dlldescname.name - - - for ii, f in enumerate(s.impbynames): - print '_'*20 - funcname = f.name - - - my_e, ret = func_from_import(libname.lower(), funcname) - if ret: - func_addr = my_e.rva2virt(ret.rva) - print funcname, hex(func_addr) - else: - print 'not found' - continue - - #XXX python int obj len zarb bug - imgb = my_e.NThdr.ImageBase - if imgb>0x80000000: - imgb-=0x40000000 - func_addr-=0x40000000 - my_e.NThdr.ImageBase = imgb - - if not is_rva_in_code_section(my_e, ret.rva): - print "not in code section" - continue - - - ok, r = guess_func_destack_dis(my_e, func_addr) - print funcname, 'ret', r - if ok == True: - resolved[(libname, funcname)] = r - elif ok == None: - unresolved.add((libname, funcname)) - else: - resolved[(libname, funcname)] = r - - - return resolved, unresolved, redirected - - -def get_import_address(e): - import2addr = defaultdict(set) - for i,s in enumerate(e.DirImport.impdesc): - fthunk = e.rva2virt(s.firstthunk) - l = "%2d %-25s %s"%(i, repr(s.dlldescname) ,repr(s)) - libname = s.dlldescname.name.lower() - for ii, imp in enumerate(s.impbynames): - if isinstance(imp, pe.ImportByName): - funcname = imp.name - else: - funcname = imp - l = " %2d %-16s"%(ii, repr(funcname)) - import2addr[(libname, funcname)].add(e.rva2virt(s.firstthunk+4*ii)) - return import2addr - - -def get_import_address_elf(e): - import2addr = defaultdict(set) - for sh in e.sh: - if not hasattr(sh, 'rel'): - continue - for k, v in sh.rel.items(): - import2addr[('xxx', k)].add(v.offset) - return import2addr - - -def get_symbols_elf(e): - sym2addr = {} - for k, v in e.sh.dynsym.symbols.items(): - sym2addr[k] = v - return sym2addr - - -def get_java_constant_pool(e): - constants = {} - for i, c in enumerate(e.hdr.constants_pool): - constants[i+1] = c - return constants - -def guess_redirected(e, resolved, unresolved, redirected, import2addr): - - import2addr_inv = [(x[1], x[0]) for x in import2addr.items()] - - to_del = [] - for imp in redirected: - ad = redirected[imp] - if ad in import2addr_inv: - my_imp = import2addr[ad] - if not my_imp in resolved: - continue - else: - resolved[my_imp] = resolved[imp] - to_del.append(my_imp) - - redirected = [x for x in redirected if not x in to_del] - return resolved, unresolved, redirected - -if __name__ == '__main__': - e, ret = func_from_import('hal.dll', 'KfAcquireSpinLock') - if ret: - print dir(ret) - print hex(e.rva2virt(ret.rva)) - -def get_imp_to_dict(e): - imp2ad = get_import_address(e) - imp_d = {} - for libf, ads in imp2ad.items(): - for ad in ads: - libname, f = libf - imp_d[ad] = libf - return imp_d - - - - -def get_imp_bloc(all_bloc, new_lib, imp_d, symbol_pool): - f_imps = [] - symb_equiv = {} - for b in all_bloc: - for l in b.lines: - for a in l.arg: - if not x86_afs.ad in a or not a[x86_afs.ad]: - continue - print a - if not x86_afs.imm in a: - continue - ad = a[x86_afs.imm] - if not ad in imp_d: - continue - print 'spot', ad, l - lab = symbol_pool.getby_offset_create(ad) - print lab - - - l = symbol_pool.getby_offset(ad) - print "ioioio", l - l.offset = None - - a[x86_afs.symb] = {lab.name:1} - print a - del a[x86_afs.imm] - - libname, func = imp_d[ad] - print func - new_lib.append( - ({"name":libname, - "firstthunk":None}, - [func]), - ) - f_imps.append(func) - symb_equiv[func] = l - return f_imps, symb_equiv - - -def code_is_line(e, ad): - job_done = set() - in_str = bin_stream.bin_stream(e.virt) - symbol_pool = asmbloc.asm_symbol_pool() - all_bloc = asmbloc.dis_bloc_all(x86_mn, in_str, ad, job_done, symbol_pool, bloc_wd = 2) - if len(all_bloc) !=1: - return None - if len(all_bloc[0].lines)!=1: - return None - return all_bloc - -def is_jmp_imp(l, imp_d): - if not l.m.name == 'jmp': - return False - if not is_address(l.arg[0]): - return False - ad = dict(l.arg[0]) - del ad[x86_afs.ad] - if not is_imm(ad): - return False - print ad - i = ad[x86_afs.imm] - if not i in imp_d: - return False - print imp_d[i] - return imp_d[i] - - -def code_is_jmp_imp(e, ad, imp_d): - all_bloc = code_is_line(e, ad) - if not all_bloc: - return None - l = all_bloc[0].lines[0] - return is_jmp_imp(l, imp_d) - - -def test_ret_and_cc(in_str, ad): - while in_str[ad] == "\xCC": - ad -=1 - return in_str[ad] == '\xC3' or in_str[ad-2] == "\xC2" - -# giving e and address in function guess function start -def guess_func_start(in_str, line_ad, max_offset = 0x200): - ad = line_ad+1 - done = False - func_addrs = set() - symbol_pool = asmbloc.asm_symbol_pool() - all_bloc = asmbloc.dis_bloc_all(x86_mn, in_str, line_ad, - func_addrs, symbol_pool) - while not done: - ad_found = None - while ad > line_ad - max_offset: - ad-=1 - ####### heuristic CC pad ####### - if in_str[ad] == "\xCC": - if in_str[((ad+3)&~3)-1] == "\xCC": - ad_found = ((ad+3)&~3) - if test_ret_and_cc(in_str, ad_found): - break - else: - continue - else: - continue - l = x86_mn.dis(in_str[ad:ad+15]) - if not l: - continue - if l.m.name in ["ret"]: - ad_found = ad+l.l - break - if not ad_found: - print 'cannot find func start' - return None - while in_str[ad_found] == "\xCC": - ad_found+=1 - # lea eax, [eax] - if in_str[ad_found:ad_found+3] == "\x8D\x40\x00": - ad_found += 3 - - job_done = set() - symbol_pool = asmbloc.asm_symbol_pool() - all_bloc = asmbloc.dis_bloc_all(x86_mn, in_str, ad_found, job_done, symbol_pool) - if func_addrs.issubset(job_done): - return ad_found - -def get_nul_term(e, ad): - out = "" - while True: - c = e.virt[ad] - if c == None: - return None - if c == "\x00": - break - out+=c - ad+=1 - return out - -#return None if is not str -def guess_is_string(out): - if out == None or len(out) == 0: - return None - cpt = 0 - for c in out: - if c.isalnum(): - cpt+=1 - if cpt * 100 / len(out) > 40: - return out - return None - - -def get_guess_string(e, ad): - s = get_nul_term(e, ad) - return guess_is_string(s) - -def is_redirected_export(e, ad): - # test is ad points to code or dll name - out = '' - for i in xrange(0x200): - c = e.virt[ad+i] - if c == "\x00": - break - out += c - if not (c.isalnum() or c in "_.-+*$@&#()[]={}"): - return False - if not "." in out: - return False - i = out.find('.') - return out[:i], out[i+1:] - - -def canon_libname_libfunc(libname, libfunc): - dn = libname.split('.')[0] - if type(libfunc) == str: - return "%s_%s"%(dn, libfunc) - else: - return str(dn), libfunc - -class libimp: - def __init__(self, lib_base_ad = 0x77700000): - self.name2off = {} - self.libbase2lastad = {} - self.libbase_ad = lib_base_ad - self.lib_imp2ad = {} - self.lib_imp2dstad = {} - self.fad2cname = {} - self.fad2info = {} - - def lib_get_add_base(self, name): - name = name.lower().strip(' ') - if not "." in name: - print 'warning adding .dll to modulename' - name += '.dll' - print name - - if name in self.name2off: - ad = self.name2off[name] - else: - ad = self.libbase_ad - print 'new lib', name, hex(ad) - self.name2off[name] = ad - self.libbase2lastad[ad] = ad+0x1 - self.lib_imp2ad[ad] = {} - self.lib_imp2dstad[ad] = {} - self.libbase_ad += 0x1000 - return ad - - def lib_get_add_func(self, libad, imp_ord_or_name, dst_ad = None): - if not libad in self.name2off.values(): - raise ValueError('unknown lib base!', hex(libad)) - - #test if not ordinatl - #if imp_ord_or_name >0x10000: - # imp_ord_or_name = vm_get_str(imp_ord_or_name, 0x100) - # imp_ord_or_name = imp_ord_or_name[:imp_ord_or_name.find('\x00')] - - - #/!\ can have multiple dst ad - if not imp_ord_or_name in self.lib_imp2dstad[libad]: - self.lib_imp2dstad[libad][imp_ord_or_name] = set() - self.lib_imp2dstad[libad][imp_ord_or_name].add(dst_ad) - - - if imp_ord_or_name in self.lib_imp2ad[libad]: - return self.lib_imp2ad[libad][imp_ord_or_name] - #print 'new imp', imp_ord_or_name, dst_ad - ad = self.libbase2lastad[libad] - self.libbase2lastad[libad] += 0x11 # arbitrary - self.lib_imp2ad[libad][imp_ord_or_name] = ad - - name_inv = dict([(x[1], x[0]) for x in self.name2off.items()]) - c_name = canon_libname_libfunc(name_inv[libad], imp_ord_or_name) - self.fad2cname[ad] = c_name - self.fad2info[ad] = libad, imp_ord_or_name - return ad - - def check_dst_ad(self): - for ad in self.lib_imp2dstad: - all_ads = self.lib_imp2dstad[ad].values() - all_ads.sort() - for i, x in enumerate(all_ads[:-1]): - if x == None or all_ads[i+1] == None: - return False - if x+4 != all_ads[i+1]: - return False - return True - - def add_export_lib(self, e, name): - # will add real lib addresses to database - if name in self.name2off: - ad = self.name2off[name] - else: - print 'new lib', name - ad = e.NThdr.ImageBase - libad = ad - self.name2off[name] = ad - self.libbase2lastad[ad] = ad+0x1 - self.lib_imp2ad[ad] = {} - self.lib_imp2dstad[ad] = {} - self.libbase_ad += 0x1000 - - ads = get_export_name_addr_list(e) - todo = ads - done = [] - while todo: - #for imp_ord_or_name, ad in ads: - imp_ord_or_name, ad = todo.pop() - - # if export is a redirection, search redirected dll - # and get function real addr - ret = is_redirected_export(e, ad) - if ret: - exp_dname, exp_fname = ret - #print "export redirection", imp_ord_or_name - #print "source", exp_dname, exp_fname - exp_dname = exp_dname+'.dll' - exp_dname = exp_dname.lower() - # if dll auto refes in redirection - if exp_dname == name: - libad_tmp = self.name2off[exp_dname] - if not exp_fname in self.lib_imp2ad[libad_tmp]: - # schedule func - todo = [(imp_ord_or_name, ad)]+todo - continue - elif not exp_dname in self.name2off: - raise ValueError('load %r first'%exp_dname) - c_name = canon_libname_libfunc(exp_dname, exp_fname) - libad_tmp = self.name2off[exp_dname] - ad = self.lib_imp2ad[libad_tmp][exp_fname] - #print hex(ad) - #if not imp_ord_or_name in self.lib_imp2dstad[libad]: - # self.lib_imp2dstad[libad][imp_ord_or_name] = set() - #self.lib_imp2dstad[libad][imp_ord_or_name].add(dst_ad) - - #print 'new imp', imp_ord_or_name, hex(ad) - self.lib_imp2ad[libad][imp_ord_or_name] = ad - - name_inv = dict([(x[1], x[0]) for x in self.name2off.items()]) - c_name = canon_libname_libfunc(name_inv[libad], imp_ord_or_name) - self.fad2cname[ad] = c_name - self.fad2info[ad] = libad, imp_ord_or_name - - - def gen_new_lib(self, e, filter=lambda x: True): - new_lib = [] - for n, ad in self.name2off.items(): - out_ads = dict() - for k, vs in self.lib_imp2dstad[ad].items(): - for v in vs: - out_ads[v] = k - all_ads = self.lib_imp2dstad[ad].values() - all_ads = reduce(lambda x,y:x+list(y), all_ads, []) - all_ads = [x for x in all_ads if filter(x)] - #print [hex(x) for x in all_ads] - all_ads.sort() - #first, drop None - if not all_ads: - continue - for i,x in enumerate(all_ads): - if not x in [0, None]: - break - all_ads = all_ads[i:] - while all_ads: - othunk = all_ads[0] - i = 0 - while i+1 < len(all_ads) and all_ads[i]+4 == all_ads[i+1]: - i+=1 - funcs = [out_ads[x] for x in all_ads[:i+1]] - if e.virt2off(othunk) != None:#e.is_in_virt_address(othunk): - new_lib.append(({"name":n, - "firstthunk":e.virt2rva(othunk)}, - funcs) - ) - all_ads = all_ads[i+1:] - return new_lib - -def vm_load_pe(e, align_s = True, load_hdr = True): - aligned = True - for s in e.SHList: - if s.addr & 0xFFF: - aligned = False - break - - if aligned: - if load_hdr: - hdr_len = max(0x200, e.NThdr.sectionalignment) - min_len = min(e.SHList[0].addr, hdr_len) - pe_hdr = e.content[:hdr_len] - pe_hdr = pe_hdr+min_len*"\x00" - pe_hdr = pe_hdr[:min_len] - to_c_helper.vm_add_memory_page(e.NThdr.ImageBase, to_c_helper.PAGE_READ|to_c_helper.PAGE_WRITE, pe_hdr) - if align_s: - for i, s in enumerate(e.SHList[:-1]): - s.size = e.SHList[i+1].addr - s.addr - s.rawsize = s.size - s.offset = s.addr - s = e.SHList[-1] - s.size = (s.size+0xfff)&0xfffff000 - for s in e.SHList: - data = str(s.data) - data += "\x00"*(s.size-len(data)) - to_c_helper.vm_add_memory_page(e.rva2virt(s.addr), to_c_helper.PAGE_READ|to_c_helper.PAGE_WRITE, data) - #s.offset = s.addr - return - - #not aligned - print 'WARNING pe is not aligned, creating big section' - min_addr = None - max_addr = None - data = "" - - if load_hdr: - data = e.content[:0x400] - data += (e.SHList[0].addr - len(data))*"\x00" - min_addr = 0 - - for i, s in enumerate(e.SHList): - if i < len(e.SHList)-1: - s.size = e.SHList[i+1].addr - s.addr - s.rawsize = s.size - s.offset = s.addr - - if min_addr == None or s.addr < min_addr: - min_addr = s.addr - if max_addr == None or s.addr + s.size > max_addr: - max_addr = s.addr + max(s.size, len(s.data)) - min_addr = e.rva2virt(min_addr) - max_addr = e.rva2virt(max_addr) - print hex(min_addr) , hex(max_addr), hex(max_addr - min_addr) - - - to_c_helper.vm_add_memory_page(min_addr, - to_c_helper.PAGE_READ|to_c_helper.PAGE_WRITE, - (max_addr - min_addr)*"\x00") - for s in e.SHList: - print hex(e.rva2virt(s.addr)), len(s.data) - to_c_helper.vm_set_mem(e.rva2virt(s.addr), str(s.data)) - - -def vm_load_elf(e, align_s = True, load_hdr = True): - for p in e.ph.phlist: - if p.ph.type != 1: - continue - print hex(p.ph.vaddr), hex(p.ph.offset), hex(p.ph.filesz) - data = e._content[p.ph.offset:p.ph.offset + p.ph.filesz] - r_vaddr = p.ph.vaddr & ~0xFFF - data = (p.ph.vaddr - r_vaddr) *"\x00" + data - data += (((len(data) +0xFFF) & ~0xFFF)-len(data)) * "\x00" - to_c_helper.vm_add_memory_page(r_vaddr, to_c_helper.PAGE_READ|to_c_helper.PAGE_WRITE, data) - - - -def preload_lib(e, runtime_lib, patch_vm_imp = True): - fa = get_import_address(e) - dyn_funcs = {} - #print 'imported funcs:', fa - for (libname, libfunc), ads in fa.items(): - for ad in ads: - ad_base_lib = runtime_lib.lib_get_add_base(libname) - ad_libfunc = runtime_lib.lib_get_add_func(ad_base_lib, libfunc, ad) - - libname_s = canon_libname_libfunc(libname, libfunc) - dyn_funcs[libname_s] = ad_libfunc - if patch_vm_imp: - to_c_helper.vm_set_mem(ad, struct.pack(cstruct.size2type[e._wsize], ad_libfunc)) - return dyn_funcs - -def preload_elf(e, patch_vm_imp = True, lib_base_ad = 0x77700000): - # XXX quick hack - fa = get_import_address_elf(e) - runtime_lib = libimp(lib_base_ad) - - dyn_funcs = {} - #print 'imported funcs:', fa - for (libname, libfunc), ads in fa.items(): - for ad in ads: - ad_base_lib = runtime_lib.lib_get_add_base(libname) - ad_libfunc = runtime_lib.lib_get_add_func(ad_base_lib, libfunc, ad) - - libname_s = canon_libname_libfunc(libname, libfunc) - dyn_funcs[libname_s] = ad_libfunc - if patch_vm_imp: - to_c_helper.vm_set_mem(ad, struct.pack(cstruct.size2type[e.size], ad_libfunc)) - return runtime_lib, dyn_funcs - - -def get_export_name_addr_list(e): - out = [] - # add func name - for i, n in enumerate(e.DirExport.f_names): - addr = e.DirExport.f_address[e.DirExport.f_nameordinals[i].ordinal] - f_name = n.name.name - #print f_name, hex(e.rva2virt(addr.rva)) - out.append((f_name, e.rva2virt(addr.rva))) - - # add func ordinal - for i, o in enumerate(e.DirExport.f_nameordinals): - addr = e.DirExport.f_address[o.ordinal] - #print o.ordinal, e.DirExport.expdesc.base, hex(e.rva2virt(addr.rva)) - out.append((o.ordinal+e.DirExport.expdesc.base, e.rva2virt(addr.rva))) - return out - - -class pattern_class: - pass - -class pattern_call_x86(pattern_class): - patterns = ["\xE8"] - @classmethod - def test_candidate(cls, in_str, off_i, off_dst): - off = off_i + 5 + struct.unpack('i', in_str[off_i+1:off_i+5])[0] - #print "XXX", hex(off_i), hex(off) - if off == off_dst: - return off_i - return None - -class pattern_jmp_long_x86(pattern_call_x86): - patterns = ["\xE9"] - -class pattern_jmp_short_x86(pattern_call_x86): - patterns = ["\xEB"] - @classmethod - def test_candidate(cls, in_str, off_i, off_dst): - off = off_i + 2 + struct.unpack('b', in_str[off_i+1:off_i+2])[0] - #print "XXX", hex(off_i), hex(off) - if off == off_dst: - return off_i - return None - - -class find_pattern: - def __init__(self, in_str, off_dst, find_class): - import re - self.in_str = in_str - self.off_dst = off_dst - if not type(find_class) is list: - find_class = [find_class] - self.find_classes = find_class - self.class_index = 0 - self.ad = 0 - def next(self): - while self.class_index < len(self.find_classes): - find_class = self.find_classes[self.class_index] - for p in find_class.patterns: - while True: - #off_i = self.my_iter.next().start() - self.ad = self.in_str.find(p, self.ad) - if self.ad == -1: - break - off = find_class.test_candidate(self.in_str, self.ad, self.off_dst) - self.ad +=1 - if off: - #print 'found', hex(off) - return off - self.class_index+=1 - self.ad = 0 - raise StopIteration - def __iter__(self): - return self diff --git a/miasm/tools/seh_helper.py b/miasm/tools/seh_helper.py deleted file mode 100644 index 2ca499f2..00000000 --- a/miasm/tools/seh_helper.py +++ /dev/null @@ -1,736 +0,0 @@ -# -# Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -#from codenat import * -from to_c_helper import * -from elfesteem import * -import to_c_helper -import logging - - -log = logging.getLogger("seh_helper") -console_handler = logging.StreamHandler() -console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s")) -log.addHandler(console_handler) -log.setLevel(logging.WARN) - -FS_0_AD = 0x7ff70000 -PEB_AD = 0x7ffdf000 -LDR_AD = 0x340000 - -MAX_MODULES = 0x40 - -# fs:[0] Page (TIB) -tib_address = FS_0_AD -peb_address = PEB_AD -peb_ldr_data_offset = 0x1ea0 -peb_ldr_data_address = LDR_AD + peb_ldr_data_offset#PEB_AD + 0x1000 - - -modules_list_offset = 0x1f00 - -InInitializationOrderModuleList_offset = 0x1ee0 #0x1f48 -InInitializationOrderModuleList_address = LDR_AD + InInitializationOrderModuleList_offset#PEB_AD + 0x2000 - -InLoadOrderModuleList_offset = 0x1ee0+MAX_MODULES*0x1000#0x1f48 + MAX_MODULES*0x1000 -InLoadOrderModuleList_address = LDR_AD + InLoadOrderModuleList_offset#PEB_AD + 0x2000 - -#in_load_order_module_1 = LDR_AD + in_load_order_module_list_offset#PEB_AD + 0x3000 -default_seh = PEB_AD + 0x20000 - -process_environment_address = 0x10000 -process_parameters_address = 0x200000 - -context_address = 0x201000 -exception_record_address = context_address+0x1000 -return_from_exception = 0x6eadbeef - -FAKE_SEH_B_AD = context_address+0x2000 - -cur_seh_ad = FAKE_SEH_B_AD - -loaded_modules = ["win_dll/kernel32.dll", "win_dll/ntdll.dll"] -main_pe = None -main_pe_name = "c:\\xxx\\toto.exe" - -def build_fake_teb(): - """ - +0x000 NtTib : _NT_TIB - +0x01c EnvironmentPointer : Ptr32 Void - +0x020 ClientId : _CLIENT_ID - +0x028 ActiveRpcHandle : Ptr32 Void - +0x02c ThreadLocalStoragePointer : Ptr32 Void - +0x030 ProcessEnvironmentBlock : Ptr32 _PEB - +0x034 LastErrorValue : Uint4B - ... - """ - o = "" - o += pdw(default_seh) - o += (0x18 - len(o)) *"\x00" - o += pdw(tib_address) - - o += (0x30 - len(o)) *"\x00" - o += pdw(peb_address) - o += pdw(0x11223344) - - return o - - -def build_fake_peb(): - """ - +0x000 InheritedAddressSpace : UChar - +0x001 ReadImageFileExecOptions : UChar - +0x002 BeingDebugged : UChar - +0x003 SpareBool : UChar - +0x004 Mutant : Ptr32 Void - +0x008 ImageBaseAddress : Ptr32 Void - +0x00c Ldr : Ptr32 _PEB_LDR_DATA - +0x010 processparameter - """ - - offset_serverdata = 0x100 - offset_data1 = 0x108 - offset_data2 = 0x110 - o = "" - o += "\x00"*0x8 - if main_pe: - o += pdw(main_pe.NThdr.ImageBase) - else: - o += "AAAA" - o += pdw(peb_ldr_data_address) - o += pdw(process_parameters_address) - - o += (0x54 - len(o)) *"A" - o += pdw(peb_address+offset_serverdata) - o += (offset_serverdata - len(o)) *"B" - o += pdw(0x33333333) - o += pdw(peb_address+offset_data1) - o += (offset_data1 - len(o)) *"C" - o += pdw(0x44444444) - o += pdw(peb_address+offset_data2) - o += (offset_data2 - len(o)) *"D" - o += pdw(0x55555555) - o += pdw(0x0077007C) - return o - - -def build_fake_ldr_data(modules_info): - """ - +0x000 Length : Uint4B - +0x004 Initialized : UChar - +0x008 SsHandle : Ptr32 Void - +0x00c InLoadOrderModuleList : _LIST_ENTRY - +0x014 InMemoryOrderModuleList : _LIST_ENTRY - +0x01C InInitializationOrderModuleList : _LIST_ENTRY - """ - o = "" - #ldr offset pad - o += "\x00" * peb_ldr_data_offset - o += "\x00"*0xc - #text XXX - - # get main pe info - m_e = None - for bname, (addr, e) in modules_info.items(): - if e == main_pe: - m_e = (e, bname, addr) - break - if not m_e: - log.warn('no main pe, ldr data will be unconsistant') - else: - print 'inloadorder first', hex(m_e[2]) - o += pdw(m_e[2]) + pdw(0) - - # get ntdll - ntdll_e = None - for bname, (addr, e) in modules_info.items(): - if bname[::2].lower() == "ntdll.dll": - ntdll_e = (e, bname, addr) - continue - if not ntdll_e: - log.warn('no ntdll, ldr data will be unconsistant') - else: - print 'ntdll', hex(ntdll_e[2]) - o += pdw(ntdll_e[2]+0x10) + pdw(0) # XXX TODO - o += pdw(ntdll_e[2]+0x10) + pdw(0) - - - return o - - -def build_fake_InInitializationOrderModuleList(modules_name): - """ - +0x000 Flink : Ptr32 -+ This distance - +0x004 Blink : Ptr32 | is eight bytes - +0x018 DllBase : Ptr32 Void -+ DllBase -> _IMAGE_DOS_HEADER - +0x01c EntryPoint : Ptr32 Void - +0x020 SizeOfImage : Uint4B - +0x024 FullDllName : _UNICODE_STRING - +0x02c BaseDllName : _UNICODE_STRING - +0x034 Flags : Uint4B - +0x038 LoadCount : Uint2B - +0x03a TlsIndex : Uint2B - +0x03c HashLinks : _LIST_ENTRY - +0x03c SectionPointer : Ptr32 Void - +0x040 CheckSum : Uint4B - +0x044 TimeDateStamp : Uint4B - +0x044 LoadedImports : Ptr32 Void - +0x048 EntryPointActivationContext : Ptr32 Void - +0x04c PatchInformation : Ptr32 Void - """ - - o = "" - offset_name = 0x700 - """ - first_name = "\x00".join(main_pe_name+"\x00\x00") - - o = "" - o += pdw(in_load_order_module_1 ) - o += pdw(in_load_order_module_1 + (len(modules_name)-1)*0x1000) - o += pdw(in_load_order_module_1+8 ) - o += pdw(in_load_order_module_1 + (len(modules_name)-1)*0x1000 +8) - o += pdw(in_load_order_module_1+0x10) - o += pdw(in_load_order_module_1 + (len(modules_name)-1)*0x1000 +0x10) - - if main_pe: - o += pdw(main_pe.NThdr.ImageBase) - o += pdw(main_pe.rva2virt(main_pe.Opthdr.AddressOfEntryPoint)) - else: - # no fixed values - pass - - o += (0x24 - len(o))*"A" - o += struct.pack('HH', len(first_name), len(first_name)) - o += pdw(InInitializationOrderModuleList_address+offset_name) - - o += (0x2C - len(o))*"A" - o += struct.pack('HH', len(first_name), len(first_name)) - o += pdw(InInitializationOrderModuleList_address+offset_name) - - o += (offset_name - len(o))*"B" - o += first_name - o += (0x1000 - len(o))*"C" - """ - for i, m in enumerate(modules_name): - #fname = os.path.join('win_dll', m) - if isinstance(m, tuple): - fname, e = m - else: - fname, e = m, None - bname = os.path.split(fname)[1].lower() - bname = "\x00".join(bname)+"\x00" - print "add module", repr(bname) - print hex(InInitializationOrderModuleList_address+i*0x1000) - if e == None: - e = pe_init.PE(open(fname, 'rb').read()) - - next_ad = InInitializationOrderModuleList_address + (i+1)*0x1000 - if i == len(modules_name) -1: - next_ad = InInitializationOrderModuleList_address - m_o = "" - m_o += pdw(next_ad ) - m_o += pdw(InInitializationOrderModuleList_address + (i-1)*0x1000) - m_o += pdw(next_ad + 8 ) - m_o += pdw(InInitializationOrderModuleList_address + (i-1)*0x1000 + 8) - m_o += pdw(next_ad + 0x10 ) - m_o += pdw(InInitializationOrderModuleList_address + (i-1)*0x1000 + 0x10) - m_o += pdw(e.NThdr.ImageBase) - m_o += pdw(e.rva2virt(e.Opthdr.AddressOfEntryPoint)) - m_o += pdw(e.NThdr.sizeofimage) - - m_o += (0x24 - len(m_o))*"A" - print hex(len(bname)), repr(bname) - m_o += struct.pack('HH', len(bname), len(bname)+2) - m_o += pdw(InInitializationOrderModuleList_address+i*0x1000+offset_name) - - m_o += (0x2C - len(m_o))*"A" - m_o += struct.pack('HH', len(bname), len(bname)+2) - m_o += pdw(InInitializationOrderModuleList_address+i*0x1000+offset_name) - - m_o += (offset_name - len(m_o))*"B" - m_o += bname - m_o += "\x00"*3 - - - m_o += (0x1000 - len(m_o))*"J" - - print "module", "%.8X"%e.NThdr.ImageBase, fname - - o += m_o - return o - - -dummy_e = pe_init.PE() -dummy_e.NThdr.ImageBase = 0 -dummy_e.Opthdr.AddressOfEntryPoint = 0 -dummy_e.NThdr.sizeofimage = 0 - -def create_modules_chain(modules_name): - modules_info = {} - base_addr = LDR_AD + modules_list_offset #XXXX - offset_name = 0x500 - offset_path = 0x600 - - - out = "" - for i, m in enumerate([(main_pe_name, main_pe), ("", dummy_e)] + modules_name): - addr = base_addr + i*0x1000 - #fname = os.path.join('win_dll', m) - if isinstance(m, tuple): - fname, e = m - else: - fname, e = m, None - bpath = fname.replace('/', '\\') - bname = os.path.split(fname)[1].lower() - bname = "\x00".join(bname)+"\x00" - #print "add module", repr(bname), repr(bpath) - #print hex(InInitializationOrderModuleList_address+i*0x1000) - if e == None: - e = pe_init.PE(open(fname, 'rb').read()) - print "add module", hex(e.NThdr.ImageBase), repr(bname) - - modules_info[bname] = addr, e - - m_o = "" - m_o += pdw(0) - m_o += pdw(0) - m_o += pdw(0) - m_o += pdw(0) - m_o += pdw(0) - m_o += pdw(0) - m_o += pdw(e.NThdr.ImageBase) - m_o += pdw(e.rva2virt(e.Opthdr.AddressOfEntryPoint)) - m_o += pdw(e.NThdr.sizeofimage) - - m_o += (0x24 - len(m_o))*"A" - print hex(len(bname)), repr(bname) - m_o += struct.pack('HH', len(bname), len(bname)+2) - m_o += pdw(addr+offset_path) - - m_o += (0x2C - len(m_o))*"A" - m_o += struct.pack('HH', len(bname), len(bname)+2) - m_o += pdw(addr + offset_name) - - m_o += (offset_name - len(m_o))*"B" - m_o += bname - m_o += "\x00"*3 - - m_o += (offset_path - len(m_o))*"B" - m_o += "\x00".join(bpath)+"\x00" - m_o += "\x00"*3 - #out += m_o - vm_set_mem(addr, m_o) - return modules_info - - -def fix_InLoadOrderModuleList(module_info): - # first binary is PE - # last is dumm_e - olist =[] - m_e = None - d_e = None - for bname, (addr, e) in module_info.items(): - print bname - if e == main_pe: - m_e = (e, bname, addr) - continue - elif e == dummy_e: - d_e = (e, bname, addr) - continue - olist.append((e, bname, addr)) - if not m_e or not d_e: - log.warn('no main pe, ldr data will be unconsistant') - else: - olist[0:0] =[m_e] - olist.append(d_e) - - last_addr = 0 - for i in xrange(len(olist)): - e, bname, addr = olist[i] - p_e, p_bname, p_addr = olist[(i-1)%len(olist)] - n_e, n_bname, n_addr = olist[(i+1)%len(olist)] - vm_set_mem(addr+0, pdw(n_addr)+pdw(p_addr)) - - - -def fix_InInitializationOrderModuleList(module_info): - # first binary is ntdll - # second binary is kernel32 - olist =[] - ntdll_e = None - kernel_e= None - for bname, (addr, e) in module_info.items(): - if bname[::2].lower() == "ntdll.dll": - ntdll_e = (e, bname, addr) - continue - elif bname[::2].lower() == "kernel32.dll": - kernel_e = (e, bname, addr) - continue - elif e == dummy_e: - d_e = (e, bname, addr) - continue - elif e == main_pe: - continue - olist.append((e, bname, addr)) - if not ntdll_e or not kernel_e or not d_e: - log.warn('no kernel ntdll, ldr data will be unconsistant') - else: - olist[0:0] =[ntdll_e] - olist[1:1] =[kernel_e] - - olist.append(d_e) - - last_addr = 0 - for i in xrange(len(olist)): - e, bname, addr = olist[i] - p_e, p_bname, p_addr = olist[(i-1)%len(olist)] - n_e, n_bname, n_addr = olist[(i+1)%len(olist)] - vm_set_mem(addr+0x10, pdw(n_addr+0x10)+pdw(p_addr+0x10)) - - -def add_process_env(): - env_str = 'ALLUSERSPROFILE=C:\\Documents and Settings\\All Users\x00' - env_str = '\x00'.join(env_str) - env_str += "\x00"*0x10 - vm_add_memory_page(process_environment_address, - PAGE_READ | PAGE_WRITE, - env_str) - vm_set_mem(process_environment_address, env_str) - -def add_process_parameters(): - o = "" - o+= pdw(0x1000) #size - o += "E"*(0x48 - len(o)) - o += pdw(process_environment_address) - vm_add_memory_page(process_parameters_address, - PAGE_READ | PAGE_WRITE, - o) - - -def build_fake_InLoadOrderModuleList(modules_name): - """ - +0x000 Flink : Ptr32 -+ This distance - +0x004 Blink : Ptr32 | is eight bytes - +0x018 DllBase : Ptr32 Void -+ DllBase -> _IMAGE_DOS_HEADER - +0x01c EntryPoint : Ptr32 Void - +0x020 SizeOfImage : Uint4B - +0x024 FullDllName : _UNICODE_STRING - +0x02c BaseDllName : _UNICODE_STRING - +0x034 Flags : Uint4B - +0x038 LoadCount : Uint2B - +0x03a TlsIndex : Uint2B - +0x03c HashLinks : _LIST_ENTRY - +0x03c SectionPointer : Ptr32 Void - +0x040 CheckSum : Uint4B - +0x044 TimeDateStamp : Uint4B - +0x044 LoadedImports : Ptr32 Void - +0x048 EntryPointActivationContext : Ptr32 Void - +0x04c PatchInformation : Ptr32 Void - """ - - o = "" - offset_name = 0x700 - first_name = "\x00".join(main_pe_name+"\x00\x00") - - o = "" - o += pdw(InLoadOrderModuleList_address ) - o += pdw(InLoadOrderModuleList_address + (len(modules_name)-1)*0x1000) - o += pdw(InLoadOrderModuleList_address+8 ) - o += pdw(InLoadOrderModuleList_address + (len(modules_name)-1)*0x1000 +8) - o += pdw(InLoadOrderModuleList_address+0x10) - o += pdw(InLoadOrderModuleList_address + (len(modules_name)-1)*0x1000 +0x10) - - if main_pe: - o += pdw(main_pe.NThdr.ImageBase) - o += pdw(main_pe.rva2virt(main_pe.Opthdr.AddressOfEntryPoint)) - else: - # no fixed values - pass - - o += (0x24 - len(o))*"A" - o += struct.pack('HH', len(first_name), len(first_name)) - o += pdw(InLoadOrderModuleList_address+offset_name) - - o += (0x2C - len(o))*"A" - o += struct.pack('HH', len(first_name), len(first_name)) - o += pdw(InLoadOrderModuleList_address+offset_name) - - o += (offset_name - len(o))*"B" - o += first_name - o += (0x1000 - len(o))*"C" - for i, m in enumerate(modules_name): - #fname = os.path.join('win_dll', m) - if isinstance(m, tuple): - fname, e = m - else: - fname, e = m, None - bname = os.path.split(fname)[1].lower() - bname = "\x00".join(bname)+"\x00" - print hex(InLoadOrderModuleList_address+i*0x1000) - if e == None: - e = pe_init.PE(open(fname, 'rb').read()) - - print "add module", hex(e.NThdr.ImageBase), repr(bname) - - next_ad = InLoadOrderModuleList_address + (i+1)*0x1000 - if i == len(modules_name) -1: - next_ad = InLoadOrderModuleList_address - m_o = "" - m_o += pdw(next_ad ) - m_o += pdw(InLoadOrderModuleList_address + (i-1)*0x1000) - m_o += pdw(next_ad + 8 ) - m_o += pdw(InLoadOrderModuleList_address + (i-1)*0x1000 + 8) - m_o += pdw(next_ad + 0x10 ) - m_o += pdw(InLoadOrderModuleList_address + (i-1)*0x1000 + 0x10) - m_o += pdw(e.NThdr.ImageBase) - m_o += pdw(e.rva2virt(e.Opthdr.AddressOfEntryPoint)) - m_o += pdw(e.NThdr.sizeofimage) - - m_o += (0x24 - len(m_o))*"A" - print hex(len(bname)), repr(bname) - m_o += struct.pack('HH', len(bname), len(bname)+2) - m_o += pdw(InLoadOrderModuleList_address+i*0x1000+offset_name) - - m_o += (0x2C - len(m_o))*"A" - m_o += struct.pack('HH', len(bname), len(bname)+2) - m_o += pdw(InLoadOrderModuleList_address+i*0x1000+offset_name) - - m_o += (offset_name - len(m_o))*"B" - m_o += bname - m_o += "\x00"*3 - - - m_o += (0x1000 - len(m_o))*"J" - - print "module", "%.8X"%e.NThdr.ImageBase, fname - - o += m_o - return o - - - -all_seh_ad = dict([(x, None) for x in xrange(FAKE_SEH_B_AD, FAKE_SEH_B_AD+0x1000, 0x20)]) -#http://blog.fireeye.com/research/2010/08/download_exec_notes.html -def init_seh(): - global seh_count - seh_count = 0 - #vm_add_memory_page(tib_address, PAGE_READ | PAGE_WRITE, p(default_seh) + p(0) * 11 + p(peb_address)) - vm_add_memory_page(FS_0_AD, PAGE_READ | PAGE_WRITE, build_fake_teb()) - #vm_add_memory_page(peb_address, PAGE_READ | PAGE_WRITE, p(0) * 3 + p(peb_ldr_data_address)) - vm_add_memory_page(peb_address, PAGE_READ | PAGE_WRITE, build_fake_peb()) - #vm_add_memory_page(peb_ldr_data_address, PAGE_READ | PAGE_WRITE, p(0) * 3 + p(in_load_order_module_list_address) + p(0) * 0x20) - - """ - ldr_data += "\x00"*(InInitializationOrderModuleList_offset - len(ldr_data)) - ldr_data += build_fake_InInitializationOrderModuleList(loaded_modules) - ldr_data += "\x00"*(InLoadOrderModuleList_offset - len(ldr_data)) - ldr_data += build_fake_InLoadOrderModuleList(loaded_modules) - """ - vm_add_memory_page(LDR_AD, PAGE_READ | PAGE_WRITE, "\x00"*MAX_MODULES*0x1000) - module_info = create_modules_chain(loaded_modules) - fix_InLoadOrderModuleList(module_info) - fix_InInitializationOrderModuleList(module_info) - - ldr_data = build_fake_ldr_data(module_info) - vm_set_mem(LDR_AD, ldr_data) - add_process_env() - add_process_parameters() - - #fds - - #vm_add_memory_page(in_load_order_module_list_address, PAGE_READ | PAGE_WRITE, p(0) * 40) - # vm_add_memory_page(in_load_order_module_list_address, PAGE_READ | PAGE_WRITE, build_fake_inordermodule(loaded_modules)) - vm_add_memory_page(default_seh, PAGE_READ | PAGE_WRITE, p(0xffffffff) + p(0x41414141) + p(0x42424242)) - - vm_add_memory_page(context_address, PAGE_READ | PAGE_WRITE, '\x00' * 0x2cc) - vm_add_memory_page(exception_record_address, PAGE_READ | PAGE_WRITE, '\x00' * 200) - - vm_add_memory_page(FAKE_SEH_B_AD, PAGE_READ | PAGE_WRITE, 0x10000*"\x00") - -#http://www.codeproject.com/KB/system/inject2exe.aspx#RestorethefirstRegistersContext5_1 -def regs2ctxt(regs): - ctxt = "" - ctxt += '\x00\x00\x00\x00' #ContextFlags - ctxt += '\x00\x00\x00\x00' * 6 #drX - ctxt += '\x00' * 112 #float context - ctxt += '\x00\x00\x00\x00' + '\x3b\x00\x00\x00' + '\x23\x00\x00\x00' + '\x23\x00\x00\x00' #segment selectors - ctxt += p(regs['edi']) + p(regs['esi']) + p(regs['ebx']) + p(regs['edx']) + p(regs['ecx']) + p(regs['eax']) + p(regs['ebp']) + p(regs['eip']) #gpregs - ctxt += '\x23\x00\x00\x00' #cs - ctxt += '\x00\x00\x00\x00' #eflags - ctxt += p(regs['esp']) #esp - ctxt += '\x23\x00\x00\x00' #ss segment selector - return ctxt - - -def ctxt2regs(ctxt): - ctxt = ctxt[:] - regs = {} - #regs['ctxtsflags'] = updw(ctxt[:4]) - ctxt = ctxt[4:] - for i in xrange(8): - if i in [4, 5]: - continue - #regs['dr%d'%i] = updw(ctxt[:4]) - ctxt = ctxt[4:] - - ctxt = ctxt[112:] #skip float - - #regs['seg_gs'] = updw(ctxt[:4]) - ctxt = ctxt[4:] - #regs['seg_fs'] = updw(ctxt[:4]) - ctxt = ctxt[4:] - #regs['seg_es'] = updw(ctxt[:4]) - ctxt = ctxt[4:] - #regs['seg_ds'] = updw(ctxt[:4]) - ctxt = ctxt[4:] - - regs['edi'], regs['esi'], regs['ebx'], regs['edx'], regs['ecx'], regs['eax'], regs['ebp'], regs['eip'] = struct.unpack('I'*8, ctxt[:4*8]) - ctxt = ctxt[4*8:] - - #regs['seg_cs'] = updw(ctxt[:4]) - ctxt = ctxt[4:] - - #regs['eflag'] = updw(ctxt[:4]) - ctxt = ctxt[4:] - - regs['esp'] = updw(ctxt[:4]) - ctxt = ctxt[4:] - - for a, b in regs.items(): - print a, hex(b) - #skip extended - return regs - - -def get_free_seh_place(): - global all_seh_ad - ads = all_seh_ad.keys() - ads.sort() - for ad in ads: - v = all_seh_ad[ad] - if v == None: - print 'TAKING SEH', hex(ad) - all_seh_ad[ad] = True - return ad - raise ValueError('too many stacked seh ') - -def free_seh_place(ad): - print 'RELEASING SEH', hex(ad) - - if not ad in all_seh_ad: - raise ValueError('zarb seh ad!', hex(ad)) - if all_seh_ad[ad] != True: - raise ValueError('seh alreaedy remouvede?!!', hex(ad)) - all_seh_ad[ad] = None - -def fake_seh_handler(except_code): - global seh_count - regs = vm_get_gpreg() - print '-> exception at', hex(regs['eip']), seh_count - seh_count += 1 - - # Help lambda - p = lambda s: struct.pack('I', s) - - dump_gpregs_py() - # Forge a CONTEXT - ctxt = '\x00\x00\x00\x00' + '\x00\x00\x00\x00' * 6 + '\x00' * 112 + '\x00\x00\x00\x00' + '\x3b\x00\x00\x00' + '\x23\x00\x00\x00' + '\x23\x00\x00\x00' + p(regs['edi']) + p(regs['esi']) + p(regs['ebx']) + p(regs['edx']) + p(regs['ecx']) + p(regs['eax']) + p(regs['ebp']) + p(regs['eip']) + '\x23\x00\x00\x00' + '\x00\x00\x00\x00' + p(regs['esp']) + '\x23\x00\x00\x00' - #ctxt = regs2ctxt(regs) - - # Find a room for seh - #seh = (get_memory_page_max_address_py()+0x1000)&0xfffff000 - - # Get current seh (fs:[0]) - seh_ptr = vm_read_dword(tib_address) - - # Retrieve seh fields - old_seh, eh, safe_place = struct.unpack('III', vm_get_str(seh_ptr, 0xc)) - - print '-> seh_ptr', hex(seh_ptr), '-> { old_seh', hex(old_seh), 'eh', hex(eh), 'safe_place', hex(safe_place), '}' - #print '-> write SEH at', hex(seh&0xffffffff) - - # Write current seh - #vm_add_memory_page(seh, PAGE_READ | PAGE_WRITE, p(old_seh) + p(eh) + p(safe_place) + p(0x99999999)) - - # Write context - vm_set_mem(context_address, ctxt) - - # Write exception_record - - """ - #http://msdn.microsoft.com/en-us/library/aa363082(v=vs.85).aspx - - typedef struct _EXCEPTION_RECORD { - DWORD ExceptionCode; - DWORD ExceptionFlags; - struct _EXCEPTION_RECORD *ExceptionRecord; - PVOID ExceptionAddress; - DWORD NumberParameters; - ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; - } EXCEPTION_RECORD, *PEXCEPTION_RECORD; - """ - - vm_set_mem(exception_record_address, p(except_code) + p(0) + p(0) + p(regs['eip']) + p(0) + p(0) ) - - # Prepare the stack - vm_push_uint32_t(context_address) # Context - vm_push_uint32_t(seh_ptr) # SEH - vm_push_uint32_t(exception_record_address) # ExceptRecords - vm_push_uint32_t(return_from_exception) # Ret address - - - - # Set fake new current seh for exception - - fake_seh_ad = get_free_seh_place() - print hex(fake_seh_ad) - vm_set_mem(fake_seh_ad, p(seh_ptr) + p(0xaaaaaaaa) + p(0xaaaaaabb) + p(0xaaaaaacc)) - vm_set_mem(tib_address, p(fake_seh_ad)) - - dump_seh() - - print '-> jumping at', hex(eh) - to_c_helper.vm_reset_exception() - - - regs = vm_get_gpreg() - #XXX set ebx to nul? - regs['ebx'] = 0 - vm_set_gpreg(regs) - - return eh - -fake_seh_handler.base = FAKE_SEH_B_AD - - -def dump_seh(): - print 'dump_seh:' - print '-> tib_address:', hex(tib_address) - cur_seh_ptr = vm_read_dword(tib_address) - indent = 1 - loop = 0 - while True: - if loop > 5: - print "too many seh, quit" - return - prev_seh, eh = struct.unpack('II', vm_get_str(cur_seh_ptr, 8)) - print '\t' * indent + 'seh_ptr:', hex(cur_seh_ptr), ' -> { prev_seh:', hex(prev_seh), 'eh:', hex(eh), '}' - if prev_seh in [0xFFFFFFFF, 0]: - break - cur_seh_ptr = prev_seh - indent += 1 - loop += 1 diff --git a/miasm/tools/to_c_helper.py b/miasm/tools/to_c_helper.py deleted file mode 100644 index 284e2d83..00000000 --- a/miasm/tools/to_c_helper.py +++ /dev/null @@ -1,1374 +0,0 @@ -# -# Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -from miasm.core import asmbloc -from miasm.core.bin_stream import bin_stream -from miasm.arch.ia32_arch import * -from miasm.arch.ia32_sem import * -import struct - -log_to_c_h = logging.getLogger("emu.to_c_helper") -console_handler = logging.StreamHandler() -console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s")) -log_to_c_h.addHandler(console_handler) -log_to_c_h.setLevel(logging.WARN) - -from elfesteem import * - - - -from miasm.tools.emul_helper import * -from miasm.expression.expression_eval_abstract import eval_abs -from miasm.expression.expression_helper import * - -from elfesteem.strpatchwork import StrPatchwork -import ctypes - -def id2new(i): - return str(i)+'_new' - -mask_int = 0xffffffffffffffff - - -pfmem08_0 = ExprId("pfmem08_0", 8) -pfmem08_1 = ExprId("pfmem08_1", 8) -pfmem08_2 = ExprId("pfmem08_2", 8) -pfmem08_3 = ExprId("pfmem08_3", 8) -pfmem08_4 = ExprId("pfmem08_4", 8) -pfmem08_5 = ExprId("pfmem08_5", 8) -pfmem08_6 = ExprId("pfmem08_6", 8) -pfmem08_7 = ExprId("pfmem08_7", 8) - -pfmem16_0 = ExprId("pfmem16_0", 16) -pfmem16_1 = ExprId("pfmem16_1", 16) -pfmem16_2 = ExprId("pfmem16_2", 16) -pfmem16_3 = ExprId("pfmem16_3", 16) -pfmem16_4 = ExprId("pfmem16_4", 16) -pfmem16_5 = ExprId("pfmem16_5", 16) -pfmem16_6 = ExprId("pfmem16_6", 16) -pfmem16_7 = ExprId("pfmem16_7", 16) - -pfmem32_0 = ExprId("pfmem32_0", 32) -pfmem32_1 = ExprId("pfmem32_1", 32) -pfmem32_2 = ExprId("pfmem32_2", 32) -pfmem32_3 = ExprId("pfmem32_3", 32) -pfmem32_4 = ExprId("pfmem32_4", 32) -pfmem32_5 = ExprId("pfmem32_5", 32) -pfmem32_6 = ExprId("pfmem32_6", 32) -pfmem32_7 = ExprId("pfmem32_7", 32) - -pfmem64_0 = ExprId("pfmem64_0", 64) -pfmem64_1 = ExprId("pfmem64_1", 64) -pfmem64_2 = ExprId("pfmem64_2", 64) -pfmem64_3 = ExprId("pfmem64_3", 64) -pfmem64_4 = ExprId("pfmem64_4", 64) -pfmem64_5 = ExprId("pfmem64_5", 64) -pfmem64_6 = ExprId("pfmem64_6", 64) -pfmem64_7 = ExprId("pfmem64_7", 64) - - -my_C_id = [ - eax, - ebx, - ecx, - edx, - esi, - edi, - esp, - ebp, - eip, - zf, - nf, - pf, - of, - cf, - af, - df, - #eax_new, - #ebx_new, - #ecx_new, - #edx_new, - #esi_new, - #edi_new, - #esp_new, - #ebp_new, - #eip_new, - #zf_new, - #nf_new, - #pf_new, - #of_new, - #cf_new, - #af_new, - #df_new, - tf, - i_f, - iopl, - nt, - rf, - vm, - ac, - vif, - vip, - i_d, - #tf_new, - #i_f_new, - #iopl_new, - #nt_new, - #rf_new, - #vm_new, - #ac_new, - #vif_new, - #vip_new, - #i_d_new, - #my_tick, - float_control, - float_eip , - float_cs , - float_address , - float_ds , - #cond, - #vm_exception_flags, - #vm_exception_flags_new, - #vm_last_write_ad, - #vm_last_write_size, - tsc1, - tsc2, - - - es , - cs , - ss , - ds , - fs , - gs , - - float_st0, - float_st1, - float_st2, - float_st3, - float_st4, - float_st5, - float_st6, - float_st7, - - float_c0, - float_c1, - float_c2, - float_c3, - - cr0, - cr3, - - float_stack_ptr, - pfmem08_0, - pfmem08_1, - pfmem08_2, - pfmem08_3, - pfmem08_4, - pfmem08_5, - pfmem08_6, - pfmem08_7, - - pfmem16_0, - pfmem16_1, - pfmem16_2, - pfmem16_3, - pfmem16_4, - pfmem16_5, - pfmem16_6, - pfmem16_7, - - pfmem32_0, - pfmem32_1, - pfmem32_2, - pfmem32_3, - pfmem32_4, - pfmem32_5, - pfmem32_6, - pfmem32_7, - - pfmem64_0, - pfmem64_1, - pfmem64_2, - pfmem64_3, - pfmem64_4, - pfmem64_5, - pfmem64_6, - pfmem64_7, - - mm0, - mm1, - mm2, - mm3, - mm4, - mm5, - mm6, - mm7, - - ] - -float_id_e = [ - float_st0, - float_st1, - float_st2, - float_st3, - float_st4, - float_st5, - float_st6, - float_st7, - ] - -id2Cid = {} -for x in my_C_id: - id2Cid[x] = ExprId('vmcpu.'+str(x), x.get_size()) - -def patch_c_id(e): - return e.replace_expr(id2Cid) - - -code_deal_exception_at_instr = r""" -if (vmcpu.vm_exception_flags > EXCEPT_NUM_UDPT_EIP) { - %s = 0x%X; - return vmcpu.eip; -} -""" -code_deal_exception_post_instr = r""" -if (vmcpu.vm_exception_flags) { - %s = (vmcpu.vm_exception_flags > EXCEPT_NUM_UDPT_EIP) ? 0x%X : 0x%X; - return vmcpu.eip; -} -""" - - -tab_uintsize ={8:uint8, - 16:uint16, - 32:uint32, - 64:uint64 - } - -def Exp2C(exprs, l = None, addr2label = None, gen_exception_code = False): - my_size_mask = {1:1, 8:0xFF, 16:0xFFFF, 32:0xFFFFFFFF, 64:0xFFFFFFFFFFFFFFFFL, - 2: 3} - if not addr2label: - addr2label = lambda x:x - id_to_update = [] - out = [] - out_eip = [] - #print [str(x) for x in exprs] - - dst_dict = {} - src_mem = {} - - prefect_mem_pool = {8: [pfmem08_0 ,pfmem08_1, pfmem08_2, pfmem08_3, - pfmem08_4, pfmem08_5, pfmem08_6, pfmem08_7], - 16: [pfmem16_0 ,pfmem16_1, pfmem16_2, pfmem16_3, - pfmem16_4, pfmem16_5, pfmem16_6, pfmem16_7], - 32: [pfmem32_0 ,pfmem32_1, pfmem32_2, pfmem32_3, - pfmem32_4, pfmem32_5, pfmem32_6, pfmem32_7], - 64: [pfmem64_0 ,pfmem64_1, pfmem64_2, pfmem64_3, - pfmem64_4, pfmem64_5, pfmem64_6, pfmem64_7],} - - new_expr = [] - - eip_is_dst = False - - for e in exprs: - if not isinstance(e, ExprAff): - raise ValueError('should be expr', str(e)) - - if isinstance(e.dst, ExprId): - if not e.dst in dst_dict: - dst_dict[e.dst] = [] - dst_dict[e.dst].append(e) - else: - new_expr.append(e) - # search mem lookup for generate mem read prefetch - rs = e.src.get_r(mem_read=True) - for r in rs: - if (not isinstance(r, ExprMem)) or r in src_mem: - continue - pfmem = prefect_mem_pool[r.get_size()].pop(0) - src_mem[r] = pfmem - - for dst, exs in dst_dict.items(): - if len(exs) ==1: - new_expr += exs - continue - log_to_c_h.debug('warning: detected multi dst to same id') - log_to_c_h.debug(str(l)) - new_expr+=exs - #test if multi slice (for example xchg al, ah) - if not False in [isinstance(e.src, ExprCompose) for e in exs]: - #spotted multi affectation to same id - e_colision = reduce(lambda x,y:x+y, [e.get_modified_slice() for e in exs]) - #print [str(x) for x in e_colision] - known_intervals = [(x[1], x[2]) for x in e_colision] - #print known_intervals - missing_i = get_missing_interval(known_intervals) - #print missing_i - rest = [(ExprSlice(dst, r[0], r[1]), r[0], r[1]) for r in missing_i] - final_dst = ExprCompose(e_colision+ rest) - new_expr.append(ExprAff(dst, final_dst)) - out_mem = [] - - # first, generate mem prefetch - mem_k = src_mem.keys() - mem_k.sort() - for k in mem_k: - str_src = patch_c_id(k).toC() - str_dst = patch_c_id(src_mem[k]).toC() - out.append('%s = %s;'%(str_dst, str_src)) - src_w_len = {} - for k, v in src_mem.items(): - cast_int = tab_uintsize[k.get_size()] - src_w_len[k] = v - for e in new_expr: - if True:#e.dst != eip: - src, dst = e.src, e.dst - # reload src using prefetch - src = src.replace_expr(src_w_len) - str_src = patch_c_id(src).toC() - str_dst = patch_c_id(dst).toC() - if isinstance(dst, ExprId): - id_to_update.append(dst) - str_dst = id2new(patch_c_id(dst)) - if dst in float_id_e: - # dont mask float affectation - out.append('%s = (%s);'%(str_dst, str_src)) - else: - out.append('%s = (%s)&0x%X;'%(str_dst, str_src, - my_size_mask[src.get_size()])) - elif isinstance(dst, ExprMem): - str_dst = str_dst.replace('MEM_LOOKUP', 'MEM_WRITE') - out_mem.append('%s, %s);'%(str_dst[:-1], str_src)) - - if e.dst == eip : - eip_is_dst = True - if isinstance(e.src, ExprCond): - #out_eip.append("cond = %s;"%e.src.cond.toC()) - out.append("vmcpu.cond = %s;"%patch_c_id(e.src.cond).toC()) - out_eip+=["if (vmcpu.cond)", - "\tGOTO_STATIC(vmcpu.eip);//%s);"%(addr2label(e.src.src1.arg)), - "else", - "\tGOTO_STATIC(vmcpu.eip);//%s);"%(addr2label(e.src.src2.arg)), - ] - else: - if isinstance(e.src, ExprInt): - if l.is_subcall(): - out_eip.append("GOTO_STATIC_SUB(%s);"%(addr2label(e.src.arg))) - else: - out_eip.append("GOTO_STATIC(0x%.16X);"%(e.src.arg)) - else: - if l.is_subcall(): - out_eip.append("GOTO_DYN_SUB(%s);"%(patch_c_id(e.src).toC())) - else: - out_eip.append('GOTO_DYNAMIC; //(%s);'%patch_c_id(e.src).toC()) - - - #if len(id_to_update) != len(set(id_to_update)): - # raise ValueError('Not implemented: multi dst to same id!', str([str(x) for x in exprs])) - - out+=out_mem - - if gen_exception_code: - out.append(code_deal_exception_at_instr % (patch_c_id(eip), (l.offset&mask_int))) - - for i in id_to_update: - out.append('%s = %s;'%(patch_c_id(i), id2new(patch_c_id(i)))) - - - - - post_instr = [] - #### test stop exec #### - if gen_exception_code: - if eip_is_dst: - #post_instr.append("if (vmcpu.vm_exception_flags) { /*eip = 0x%X; */return (unsigned int)vm_get_exception(vmcpu.vm_exception_flags); }"%(l.offset)) - post_instr.append("if (vmcpu.vm_exception_flags) { /*eip = 0x%X; */return vmcpu.eip; }"%(l.offset)) - else: - post_instr.append(code_deal_exception_post_instr % (patch_c_id(eip), (l.offset&mask_int), (l.offset + l.l)&mask_int)) - - """ - print "1" - print out - print "2" - print out_eip - print "3" - print post_instr - """ - - - - #eip manip after all modifications - return out+out_eip, post_instr - - -def bloc2C(all_bloc, addr2label = None, gen_exception_code = False, dbg_instr = False, dbg_reg = False, dbg_lbl = False, filtered_ad = None, tick_dbg = None, segm_to_do = set()): - all_instrs = digest_allbloc_instr(all_bloc, segm_to_do) - - if not addr2label: - addr2label = lambda x:"loc_%.16X"%(x&mask_int) - - - out = [] - label_done = set() - for b in all_bloc: - #out.append("%s:"%str(b.label.name)) - if dbg_lbl or dbg_instr: - if (not filtered_ad) or b.label.offset in filtered_ad: - if tick_dbg!=None: - out.append('if (my_tick > %d)'%tick_dbg) - out.append(r'fprintf(stdout, "%s\n");'%str(b.label.name)) - - - for l in b.lines: - if l.offset in label_done: - continue - label_done.add(l.offset) - l,ex = all_instrs[l.offset] - if addr2label: - out.append("%s:"%addr2label(l.offset)) - else: - out.append("loc_%.16X:"%(l.offset&mask_int)) - - o, post_instr = Exp2C(ex, l, addr2label, gen_exception_code) - - - - - #if add_return: - # o.append('return;'); - #if add_call: - # o.append('%s();'%add_call); - - if (0xF2 in l.prefix or 0xF3 in l.prefix) and l.m.name in ["ins", "outs", "movsb", "movsw", "movsd", "lodsb", "lodsw", "lodsd", "stosb", "stosw", "stosd" ]+ [ "cmpsb", "cmpsw", "cmpsd", "scasb", "scasw", "scasd" ]: - zf_w = zf in reduce(lambda x,y:x+y, [list(x.get_w()) for x in ex], []) - my_o = ["while (1){"] - #my_o.append("if (vmcpu.vm_exception_flags) { %s = 0x%X; return (PyObject*)vm_get_exception(vm_exception_flags); }"%(patch_c_id(eip), l.offset)) - #my_o.append(code_deal_exception_post_instr % (patch_c_id(eip), l.offset, l.offset + l.l)) - my_o.append(code_deal_exception_post_instr % (patch_c_id(eip), (l.offset&mask_int), (l.offset&mask_int))) - - - #my_o.append(r'fprintf(stderr, "ecx %.8X\n", ecx );') - my_o+= ['if (%s==0) break;'%patch_c_id(ecx)] - my_o+=o - my_o+= ['%s--;'%patch_c_id(ecx)] - if zf_w: - if 0xF3 in l.prefix: - my_o+= ['if (%s==0) break;'%patch_c_id(zf)] - if 0xF2 in l.prefix: - my_o+= ['if (%s==1) break;'%patch_c_id(zf)] - - - my_o += ["}"] - - o = my_o - - o+= post_instr - #print "\t"+"\n\t".join(o) - - if dbg_reg and ((not filtered_ad) or l.offset in filtered_ad): - if tick_dbg!=None: - out.append(r'vmcpu.my_tick++;') - out.append('if (vmcpu.my_tick > %d)'%tick_dbg) - out.append(r'printf(" eax %.8X ebx %.8X ecx %.8X edx %.8X esi %.8X edi %.8X esp %.8X ebp %.8X c%X p%X a%X z%X n%X d%X o%X\n", vmcpu.eax, vmcpu.ebx, vmcpu.ecx, vmcpu.edx, vmcpu.esi, vmcpu.edi, vmcpu.esp, vmcpu.ebp, vmcpu.cf, vmcpu.pf, vmcpu.af, vmcpu.zf, vmcpu.nf, vmcpu.df, vmcpu.of );') - if dbg_instr and ((not filtered_ad) or l.offset in filtered_ad): - if tick_dbg!=None: - out.append('if (vmcpu.my_tick > %d)'%tick_dbg) - out.append(r'fprintf(stdout, "%s\n");'%str(l)) - else: - out.append(r'//%s'%str(l)) - - out+=o - - - for c in b.bto: - if c.c_t == asmbloc.asm_constraint.c_next: - out.append("GOTO_STATIC(0x%.16X);"%(c.label.offset&mask_int)) - - """ - #in case of bad disasm, no next, so default next instr - #XXX BUG if no line!!! - - if b.lines: - l = b.lines[-1] - out.append("GOTO_STATIC(%s);"%(addr2label(l.offset + l.l))) - """ - - - return out - - - -def bloc_gen_C_func(all_bloc, funcname, addr2label = None, gen_exception_code = False, dbg_instr = False, dbg_reg = False, dbg_lbl = False, filtered_ad = None, tick_dbg = None, segm_to_do = set()): - f_dec = 'uint64_t %s(void)'%funcname - out = [] - out+=[f_dec, - '{', - ] - out += bloc2C(all_bloc, addr2label, gen_exception_code, - dbg_instr, dbg_reg, dbg_lbl, - filtered_ad, tick_dbg, - segm_to_do) - out+=['}', - ] - return f_dec, out - - -def gen_x86_core(): - import os - - lib_dir = os.path.dirname(os.path.realpath(__file__)) - lib_dir = os.path.join(lib_dir, 'emul_lib') - - txt = "" - txt += '#include "%s/queue.h"\n'%lib_dir - txt += '#include "%s/libcodenat.h"\n'%lib_dir - - txt += r''' - -//#define RAISE(errtype,msg) { PyErr_SetString(errtype,msg); RE_RAISE; } -//#define RE_RAISE { return NULL; } - -#define RAISE(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return p;} - - - -''' - return txt - - -def gen_C_source(funcs_code, known_mems, dyn_dispatcher): - c_source = dyn_dispatcher - c_source+= "\n".join(funcs_code) - - kmems = gen_known_mems_code(known_mems) - c_source = gen_x86_core()+"\n".join(kmems)+c_source - return c_source - - -def blocs_to_memory_ranges(all_blocs): - code_addr = [] - for b in all_blocs: - # XXX no lines in bloc? - if not b.lines: - continue - code_addr.append((b.lines[0].offset, b.lines[-1].offset + b.lines[-1].l)) - return code_addr - -def del_bloc_in_range(all_blocs, ad1, ad2): - bloc_out = [] - for b in all_blocs: - # XXX no lines in bloc? - if not b.lines: - continue - - if b.lines[0].offset>=ad2 or b.lines[-1].offset + b.lines[-1].l <= ad1: - bloc_out.append(b) - else: - #print 'inv bloc', b.label - pass - return bloc_out - -def merge_memory_ranges(t): - i = 0 - while i < len(t)-1: - j = i+1 - rA1, rA2 = t[i] - while j < len(t): - rB1, rB2 = t[j] - #print "uu", hex(rA1), hex(rA2) - #print "vv", hex(rB1), hex(rB2) - - if rA1 >= rB1 and rA2 <= rB2: - #print '#rA included in rB' - rA1, rA2 = t[j] - del(t[j]) - continue - elif rA1 <= rB1 and rA2 >= rB2: - #print '#rB included in rA' - del(t[j]) - continue - elif rA1 <= rB1 and rA2 >= rB1: - #print '#rA ends in rB' - rA2 = rB2 - del(t[j]) - continue - elif rB1 <= rA1 and rB2 >= rA1: - #print '#rB ends in rA' - rA1 = rB1 - del(t[j]) - continue - j+=1 - if t[i] != (rA1, rA2): - t[i] = rA1, rA2 - else: - i+=1 - - -def gen_code_addr_tab(t): - out = [] - - out += ["#define CODE_ADDR_SIZE (2*%d)"%len(t)] - out += ["unsigned int code_addr_tab[2*%d] = {"%len(t)] - for r in t: - out += ["\t0x%.8X, 0x%.8X,"%(r)] - - out += ['};'] - return '\n'.join(out)+'\n' - -def asm2C(f_name, known_mems, dyn_func, in_str, x86_mn, symbol_pool, func_to_dis, dont_dis = [], follow_call = False, dontdis_retcall = False, log_mn = False, log_reg = False, log_lbl = False, filtered_ad = [], tick_dbg = None, code_addr = [], all_bloc_funcs = []): - - funcs_code = [] - funcs_dec = [] - - all_bloc_funcs+=asmbloc.dis_multi_func(in_str, x86_mn, symbol_pool, func_to_dis, dont_dis, follow_call, dontdis_retcall) - - - - for b in all_bloc_funcs: - if b.label.offset in dont_dis: - continue - - #XXX no lines in bloc? - if not b.lines: - continue - l = b.lines[-1] - #if l.m.name.startswith('jmp') and not x86_afs.symb in l.arg[0]: - # raise ValueError('unsupported dst', str(l)) - ''' - if (l.m.name.startswith('call') or l.m.name.startswith('jmp')) and not x86_afs.symb in l.arg[0]: - - #print "TOTO", hex(l.offset), l, l.arg[0] - - #deal dyn call - instr = x86_mn.dis(x86_mn.asm('mov eax, eax')[0]) - #XXX HACK to be unik address - instr.offset = l.offset+1 - - instr.arg = [{x86_afs.symb:{ExprId('dyn_dst'):1}}, dict(l.arg[0])] - - #print instr, str(instr) - #instr.offset = 0x1337beef - - #b.lines[-1:-1] = [instr] - #l.arg[0] = {x86_afs.symb:func_deal_dyn} - - - #if dyn func is not in ref, add it (todo in gen C) - ''' - - for l in b.lines: - - #test imm redirect mem ad - for a in l.arg: - if not x86_afs.imm in a: continue - i = a[x86_afs.imm] - - - l_name = None - for m_ad, m_val in known_mems.items(): - if m_ad <= i < m_ad+len(m_val): - l_name = "(unsigned int)&tab_%.8X[0x%X]"%(m_ad, i-m_ad) - break - - for f in dyn_func: - if i == f: - l_name = "(unsigned int)0x%.8X"%(f) - for f in func_to_dis: - if i == f: - l_name = "(unsigned int)0x%.8X"%(f) - break - - if not l_name: - continue - - label = symbol_pool.add_label(l_name, i) - a[x86_afs.symb] = {label:1} - del a[x86_afs.imm] - - - code_addr += blocs_to_memory_ranges(all_bloc_funcs) - merge_memory_ranges(code_addr) - - - allb = all_bloc_funcs#reduce(lambda x,y:x+y, all_bloc_funcs.values(), []) - f_dec, out = bloc_gen_C_func(allb, f_name, None, True, log_mn, log_reg, log_lbl, filtered_ad, tick_dbg) - funcs_dec.append(f_dec) - funcs_code+=out - - - for f, f_code in dyn_func.items(): - l_name = "loc_%.16X"%(f&mask_int) - funcs_code[-1:-1] = [l_name+":"] - funcs_code[-1:-1] = f_code.split('\n') - l = symbol_pool.add_label(l_name, f) - b = asmbloc.asm_bloc(l) - #all_bloc_funcs[f] = [b] - all_bloc_funcs += [b] - - funcs_code[2:2] = ["FUNC_DYNAMIC;"] - funcs_code[3:3] = ["GOTO_DYNAMIC;"] - - funcs_code[0:0] = [gen_code_addr_tab(code_addr)] - #funcs_dec = ["void func_%.8X(void)"%x for x in all_bloc_funcs] - - - #test return direct dyn dispatch - dispatch_table = dispatch_table_from_f_blocs(all_bloc_funcs) - dyn_dispatcher = gen_dynamic_dispatcher(dispatch_table) - - return funcs_code, dyn_dispatcher - - -def gen_C_from_asmbloc(in_str, offset, symbol_pool, dont_dis = [], job_done = None, log_mn = False, log_reg = False, log_lbl = False, filtered_ad = [], tick_dbg = None, code_addr = [], all_bloc_funcs = [], segm_to_do = set(), **kargs): - if job_done == None: - job_done = set() - - f_name = "bloc_%.16X"%(offset&mask_int) - l = symbol_pool.getby_offset_create(offset) - cur_bloc = asmbloc.asm_bloc(l) - asmbloc.dis_bloc(x86_mn, in_str, cur_bloc, offset, job_done, symbol_pool,[], - follow_call = False, patch_instr_symb = True, - dontdis_retcall = False,lines_wd = None, - **kargs) - f_dec, out = bloc_gen_C_func([cur_bloc], f_name, None, True, - log_mn, log_reg, log_lbl, - filtered_ad, tick_dbg, segm_to_do) - #print "\n".join(out) - return f_name, f_dec, out, cur_bloc - - -def dispatch_table_from_f_blocs(all_f_b): - dispatch_table = {} - #for b in all_f_b: - # dispatch_table[b.label.offset] = b.label.name - for b in all_f_b: - dispatch_table[b.label.offset] = b.label.name - for l in b.lines: - dispatch_table[l.offset] = "loc_%.16X"%(l.offset&mask_int) - - return dispatch_table - - -def gen_dynamic_dispatcher(dispatch_table): - offsets = dispatch_table.keys() - offsets.sort() - - out1 = [] - out1 += ["#define FUNC_DYNAMIC"] - out1 += ['void* tab_eip_label[(%d+1)*2] = '%len(dispatch_table)] - out1 += ['{'] - for o in offsets: - out1+=['\t(void*)0x%.8X, (void*)&&%s,'%(o, dispatch_table[o])] - out1+=['\t(void*)0x%.8X, (void*)0x0,'%(0)] - - out1 += ['};'] - - out2 = [] - out2 += ["void * get_label_from_eip(void** tab_eip_label)"] - out2 += ['{'] - - out2 += ['\tvoid *labelref = NULL;'] - - out2 += ['\tunsigned int i = 0;'] - out2 += ['\twhile (tab_eip_label[2*i]!= NULL && tab_eip_label[2*i+1]!=NULL){'] - out2 += ['\t\tif (tab_eip_label[i*2] == (void*)vmcpu.eip){'] - out2 += ['\t\t\tlabelref = tab_eip_label[i*2+1];'] - out2 += ['\t\t\treturn labelref;'] - out2 += ['\t\t}'] - out2 += ['\ti++;'] - out2 += ['\t}'] - out2 += [r'fprintf(stderr, "Unkown destination! 0x%.8X\n", vmcpu.eip);'] - out2 += [r'vmcpu.vm_exception_flags |= EXCEPT_UNK_EIP;'] - #out2 += [r'exit(0);'] - out2 += ['return labelref;'] - out2 += ['}'] - - - out = [] - - out += ["#define GOTO_DYNAMIC"] - out += ["labelref = get_label_from_eip();"] - out += ["if (labelref == NULL) {"] - out += [r'fprintf(stderr, "Unkown destination! 0x%.8X\n", vmcpu.eip);'] - out += [r'vmcpu.vm_exception_flags |= EXCEPT_UNK_EIP;'] - out += ["return (PyObject*)vm_get_exception(vm_exception_flags);"] - out += ['}'] - out += ['goto *labelref;'] - - """ - out += ['{'] - #out += [r'fprintf(stderr, "search dst: %X\n", eip);'] - - out += ['switch(eip){'] - for o in offsets: - out+=['case 0x%.8X:'%o] - out+=['goto %s;'%dispatch_table[o]] - out+=['break;'] - - out += ['case 0x1337beef:'] - out += [r'fprintf(stderr, "return reached %X\n", eip);'] - out += ['return NULL;'] - out += ['default:'] - out += [r'fprintf(stderr, "Unkown destination! 0x%.8X\n", eip);'] - out += [r'vm_exception_flags |= EXCEPT_UNK_EIP;'] - out += ["return (PyObject*)vm_get_exception(vm_exception_flags);"] - out += ['break;'] - out += ['}'] - out += ['}'] - """ - return out1, out2 - -def gen_dyn_func_manager(dyn_func, dis_func): - total_func_num = len(dyn_func)+len(dis_func) - out = "int (*tab_func[%d][2])(void) = {"%(total_func_num) - dec_f_ptr = "" - init_f_ptr = "" - for f_ad, f_name in dyn_func.items(): - out+="{%s, %s},"%("0x%.8X"%f_ad, f_name) - - dec_f_ptr += "unsigned int dyn_func_%.8X;\n"%(f_ad) - init_f_ptr+= "dyn_func_%.8X = (unsigned int)&%s;\n"%(f_ad, f_name) - - for f_ad in dis_func: - out+="{0x%.8X, func_%.8X},"%(f_ad, f_ad) - out+="};" - - - code = "\n" - code += "#define DYN_FUNC_NUM %d"%total_func_num - code += r""" -/* -void func_dyn_manager(void) -{ - unsigned int i; -""" + out + r""" - - for (i=0;i<DYN_FUNC_NUM;i++){ - if (dyn_dst == tab_func[i][0]){ - fprintf(stderr, "i %d v@%X r@%X\n", i, tab_func[i][0], tab_func[i][1]); - tab_func[i][1](); - return; - } - } - - fprintf(stderr, "unknown dyn dst!\n"); - exit(0); -} -*/ - """ - return dec_f_ptr, init_f_ptr, code - - - -def insert_printf(c_source, label): - for i, l in enumerate(c_source): - print l - if l.startswith(label): - c_source[i+1:i+1] = ['printf("reached %s\\n");'%label] - - - - -def gen_label_declaration(known_mems): - lab_dec = [] - - for m_ad, m_val in known_mems.items(): - dec_name = "char tab_%.8X[0x%X]"%(m_ad, len(m_val)) - data = m_val - dec_name+=' = {'+', '.join(["0x%.2X"%ord(x) for x in data])+'};' - lab_dec.append(dec_name) - - - return lab_dec - - -def gen_call_func(funcname, args, precode = "", postcode = ""): - out = "" - -def gen_known_mems_code(known_mems): - code = [] - for m_ad, m_val in known_mems.items(): - out = "" - out += "char *tab_%.8X;"%(m_ad) - out += "char tab_data_%.8X[0x%X] = "%(m_ad, len(m_val)) - out += '{'+', '.join(["0x%.2X"%ord(x) for x in m_val])+'};' - out += 'unsigned int get_tab_%.8X() { return (unsigned int)tab_%.8X;}'%(m_ad, m_ad) - code.append(out) - - #test transform tab_XX to dynamic allocated prod - """ - code.append("void init_tab_mem(void)") - code.append("{") - code.append("unsigned int ret;") - - for m_ad, m_val in known_mems.items(): - #code.append("tab_%.8X = malloc(0x%.8X);\n"%(m_ad, len(m_val))) - code.append("ret = posix_memalign(&tab_%.8X, 0x10000, 0x%.8X);"%(m_ad, len(m_val))) - code.append("if (ret){") - code.append(r' fprintf(stderr, "cannot alloc");') - code.append(r' exit(-1);') - code.append(r'}') - - - code.append("memcpy(tab_%.8X, tab_data_%.8X, 0x%.8X);"%(m_ad, m_ad, len(m_val))) - code.append("}\n") - """ - - - - return code - -if __name__ == '__main__': - e = dec(ExprMem(eax)) - for x in e: - print x - print '_'*80 - o = Exp2C(e) - for x in o: - print x - print '#'*80 - - new_e = [x.replace_expr({ExprMem(eax): ExprId('ioio')}) for x in e] - for x in new_e: - print x - print '-'*80 - o = Exp2C(new_e) - for x in o: - print x - print '#'*80 - - - - -def _compile(self): - import os - from distutils.core import setup, Extension - import os - - lib_dir = os.path.dirname(os.path.realpath(__file__)) - lib_dir = os.path.join(lib_dir, 'emul_lib') - - os.chdir(self._buildDir) - ext = Extension(self._moduleName, - [self._srcFileName], - library_dirs=self._options.get('library_dirs'), - libraries=self._options.get('libraries'), - define_macros=self._options.get('define_macros'), - undef_macros=self._options.get('undef_macros'), - extra_link_args = ['-Wl,-rpath,'+lib_dir] - ) - try: - setup(name = self._moduleName, - version = self._moduleVersion, - ext_modules = [ext], - script_args = ["build"] + (self._options.get('distutils_args') or []), - script_name="C.py", - package_dir=self._buildDir, - ) - except SystemExit, e: - raise BuildError(e) - - os.chdir(self._homeDir) - - - - - -from miasm.tools.codenat import * -''' -def updt_bloc_emul(known_blocs, in_str, my_eip, symbol_pool, code_blocs_mem_range, dont_dis = [], log_mn = False, log_regs = False): - - f_dec, funcs_code, cur_bloc = gen_C_from_asmbloc(in_str, my_eip, symbol_pool, dont_dis, log_mn, log_regs) - - dyn_dispatcher = """ - #define GOTO_DYNAMIC do {return %s;} while(0) - #define GOTO_STATIC(a) do {vmcpu.eip = a;return %s;} while(0) - #define GOTO_STATIC_SUB(a) do {return %s;} while(0) - #define GOTO_DYN_SUB(a) do {return %s;} while(0) - #define vm_get_exception(a) %s - """%(patch_c_id(eip), patch_c_id(eip), patch_c_id(eip), patch_c_id(eip), patch_c_id(eip)) - - c_source = gen_C_source(funcs_code, {}, dyn_dispatcher) - c_source = "#include <Python.h>\n"+c_source - - a = gen_C_module(c_source) - bn = bloc_nat(my_eip, cur_bloc, a, log_mn, log_regs) - #f_dec = f_dec[10:-6] - f_dec = f_dec[13:-6] - a.func = a[f_dec] - known_blocs[my_eip] = bn - - ###### update code ranges ### - - code_addr = blocs_to_memory_ranges([bn.b]) - code_blocs_mem_range += code_addr - merge_memory_ranges(code_blocs_mem_range) - reset_code_bloc_pool_py() - for a, b in code_blocs_mem_range: - vm_add_code_bloc(a, b) -''' - -ttt = 0 -def updt_bloc_emul(known_blocs, in_str, my_eip, symbol_pool, code_blocs_mem_range, dont_dis = [], job_done = None, log_mn = False, log_regs = False, segm_to_do = set(), **kargs): - if job_done == None: - job_done = set() - fname, f_dec, funcs_code, cur_bloc = gen_C_from_asmbloc(in_str, my_eip, symbol_pool, dont_dis, job_done, log_mn, log_regs, segm_to_do = segm_to_do, **kargs) - - dyn_dispatcher = """ - #define GOTO_DYNAMIC do {return %s;} while(0) - #define GOTO_STATIC(a) do {vmcpu.eip = a; return %s;} while(0) - #define GOTO_STATIC_SUB(a) do {return %s;} while(0) - #define GOTO_DYN_SUB(a) do {return %s;} while(0) - #define vm_get_exception(a) %s - """%(patch_c_id(eip), patch_c_id(eip), patch_c_id(eip), patch_c_id(eip), patch_c_id(eip)) - - c_source = gen_C_source(funcs_code, {}, dyn_dispatcher) - - c_source = """ -#ifdef __x86_64__ -#ifndef __LP64__ -/* - for ubuntu ?!? XXX TODO - /!\ force 64 bit system using 64 bits libc - change this to __ILP32__ to do so. -*/ -#define __LP64__ -#endif -#endif -""" + "#include <Python.h>\n" + c_source - - #c_source = '#include "emul_lib/libcodenat.h"\n'+c_source - #print c_source - a = gen_C_module_tcc(fname, c_source) - bn = bloc_nat(my_eip, cur_bloc, a, c_source, log_mn, log_regs) - - bn.c_source = c_source - #f_dec = f_dec[10:-6] - f_dec = f_dec[13:-6] - #a.func = a[f_dec] - known_blocs[my_eip] = bn - ###### update code ranges ### - code_addr = blocs_to_memory_ranges([bn.b]) - code_blocs_mem_range += code_addr - merge_memory_ranges(code_blocs_mem_range) - reset_code_bloc_pool_py() - for a, b in code_blocs_mem_range: - vm_add_code_bloc(a, b) -#''' - -def updt_pe_from_emul(e): - for s in e.SHList: - sdata = vm_get_str(e.rva2virt(s.addr), s.rawsize) - e.virt[e.rva2virt(s.addr)] = sdata - return bin_stream(e.virt) - -def updt_automod_code(known_blocs): - w_ad, w_size = vm_get_last_write_ad(), vm_get_last_write_size() - log_to_c_h.debug("%X %X"%(w_ad, w_size)) - known_blocs = del_bloc_in_range(known_blocs, w_ad, w_ad+w_size/8) - code_addr = blocs_to_memory_ranges([bn.b for bn in known_blocs.values()]) - merge_memory_ranges(code_addr) - reset_code_bloc_pool_py() - - for a, b in code_addr: - vm_add_code_bloc(a, b) - vm_reset_exception() - - return known_blocs, code_addr - - -def flush_all_blocs(known_blocs): - for ad in known_blocs.keys(): - known_blocs = del_bloc_in_range(known_blocs, ad, ad+1) - code_addr = blocs_to_memory_ranges([bn.b for bn in known_blocs.values()]) - merge_memory_ranges(code_addr) - reset_code_bloc_pool_py() - - for a, b in code_addr: - vm_add_code_bloc(a, b) - vm_reset_exception() - return known_blocs, code_addr - - -def dump_stack(): - esp = vm_get_gpreg()['esp'] - print 'esp', hex(esp) - a = vm_get_str(esp, 0x20) - while a: - x = struct.unpack('I', a[:4])[0] - a = a[4:] - print hex(x) - -import random - -def c_emul_bloc(known_blocs, my_eip): - if not my_eip in known_blocs: - raise ValueError('unknown bloc (should have been disasm...', hex(my_eip)) - return known_blocs[my_eip].module_c.func() - - -class bin_stream_vm(): - def __init__(self, offset = 0L): - self.offset = offset - - def readbs(self, l=1): - try: - s = vm_get_str(self.offset, l) - except: - raise IOError('cannot get mem ad', hex(self.offset)) - self.offset+=l - return s - - def writebs(self, l=1): - raise 'writebs unsupported' - - def __str__(self): - raise 'writebs unsupported' - def setoffset(self, val): - val = val & 0xFFFFFFFF - self.offset = val - def __getitem__(self, item): - if not type(item) is slice: # integer - self.offset = item - return self.readbs(1) - start = item.start - stop = item.stop - step = item.step - self.offset = start - s = self.readbs(stop-start) - return s[::step] - - - -vm_read_dword = lambda a: struct.unpack('I', vm_get_str(a, 4))[0] -p = lambda addr: struct.pack('I', addr) -pdw = p -updw = lambda bbbb: struct.unpack('I', bbbb)[0] -pw = lambda x: struct.pack('H', x) -upw = lambda x: struct.unpack('H', x)[0] - -base_dll_imp = ["ntdll.dll", "kernel32.dll", "user32.dll", - "imm32.dll", "msvcrt.dll", - "oleaut32.dll", "shlwapi.dll", - "version.dll", "advapi32.dll", - "ws2help.dll", - "rpcrt4.dll", "shell32.dll", "winmm.dll", - #"mswsock.dll", - "ws2_32.dll", - "gdi32.dll", "ole32.dll", - "secur32.dll", "comdlg32.dll", - #"wsock32.dll" - ] - - -def load_pe_in_vm(fname_in, options, all_imp_dll = None, **kargs): - import os - import seh_helper - import win_api - global base_dll_imp - from miasm.tools import pe_helper - from miasm.tools import codenat - - e = pe_init.PE(open(fname_in, 'rb').read(), - parse_resources = options.parse_resources) - - vm_init_regs() - init_memory_page_pool_py() - init_code_bloc_pool_py() - init_memory_breakpoint_py() - in_str = bin_stream_vm() - codenat_tcc_init() - runtime_dll = pe_helper.libimp(kargs.get('runtime_basead', 0x71111000)) - - align_s = False - if 'align_s' in kargs: - align_s = kargs['align_s'] - pe_helper.vm_load_pe(e, align_s = align_s, load_hdr = options.loadhdr) - - if all_imp_dll == None: - if options.loadbasedll: - all_imp_dll = base_dll_imp - else: - all_imp_dll = [] - - mod_list = all_imp_dll - exp_func = {} - all_pe = [] - for n in mod_list: - fname = os.path.join('win_dll', n) - ee = pe_init.PE(open(fname, 'rb').read()) - pe_helper.vm_load_pe(ee, align_s = align_s) - runtime_dll.add_export_lib(ee, n) - exp_funcs = pe_helper.get_export_name_addr_list(ee) - exp_func[n] = exp_funcs - all_pe.append((fname, ee)) - - for fname, ee in all_pe: - pe_helper.preload_lib(ee, runtime_dll) - seh_helper.runtime_dll = runtime_dll - if options.loadmainpe: - seh_helper.main_pe = e - seh_helper.main_pe_name = kargs.get("main_pe_name", "toto.exe") - seh_helper.loaded_modules = all_pe - dll_dyn_funcs = pe_helper.preload_lib(e, runtime_dll) - - win_api.winobjs.runtime_dll = runtime_dll - win_api.winobjs.current_pe = e - win_api.winobjs.module_name = kargs.get("main_pe_name", "toto.exe")+"\x00" - win_api.winobjs.module_path = seh_helper.main_pe_name+"\x00" - win_api.winobjs.hcurmodule = e.NThdr.ImageBase - - stack_size = 0x10000 - if 'stack_size' in kargs: - stack_size = kargs['stack_size'] - - stack_base = 0x1230000 - if 'stack_base' in kargs: - stack_base = kargs['stack_base'] - - stack_base_ad = kargs.get('stack_base_ad', stack_base) - stack_size = kargs.get('stack_size', stack_size) - vm_add_memory_page(stack_base_ad, - codenat.PAGE_READ|codenat.PAGE_WRITE, - "\x00"*stack_size) - dump_memory_page_pool_py() - - - regs = vm_get_gpreg() - regs['esp'] = stack_base_ad+stack_size - vm_set_gpreg(regs) - - if options.usesegm: - segms = vm_get_segm() - segms['fs'] = 0x4 - vm_set_segm(segms) - vm_set_segm_base(segms['fs'], seh_helper.FS_0_AD) - segm_to_do = set([x86_afs.reg_sg.index(x86_afs.r_fs)]) - seh_helper.init_seh() - else: - segm_to_do = set() - - symbol_pool = asmbloc.asm_symbol_pool() - - return e, in_str, runtime_dll, segm_to_do, symbol_pool - - -def vm2pe(fname, runtime_dll = None, e_orig = None, max_addr = 1<<64, min_addr = 0x401000, min_section_offset = 0x1000): - from elfesteem import pe - - mye = pe_init.PE() - mye.NThdr.ImageBase = e_orig.NThdr.ImageBase - all_mem = vm_get_all_memory() - addrs = all_mem.keys() - addrs.sort() - mye.Opthdr.AddressOfEntryPoint = mye.virt2rva(vm_get_gpreg()['eip']) - first = True - for ad in addrs: - if not min_addr <= ad < max_addr: - continue - if first: - mye.SHList.add_section("%.8X"%ad, addr = ad - mye.NThdr.ImageBase, data = all_mem[ad]['data'], - offset = min_section_offset) - else: - mye.SHList.add_section("%.8X"%ad, addr = ad - mye.NThdr.ImageBase, data = all_mem[ad]['data']) - first = False - - if runtime_dll: - new_dll = runtime_dll.gen_new_lib(mye) - #print new_dll - mye.DirImport.add_dlldesc(new_dll) - - s_imp = mye.SHList.add_section("import", rawsize = len(mye.DirImport)) - mye.DirImport.set_rva(s_imp.addr) - print repr(mye.SHList) - if e_orig: - # resource - xx = str(mye) - mye.content = xx - ad = e_orig.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].rva - print 'dirres', hex(ad) - if ad != 0: - mye.NThdr.optentries[pe.DIRECTORY_ENTRY_RESOURCE].rva = ad - mye.DirRes = pe.DirRes.unpack(xx,ad,mye) - #print repr(mye.DirRes) - s_res = mye.SHList.add_section(name = "myres", rawsize = len(mye.DirRes)) - mye.DirRes.set_rva(s_res.addr) - print repr(mye.DirRes) - - # generation - open(fname, 'w').write(str(mye)) - -def manage_runtime_func(my_eip, api_modues, runtime_dll, dbg = False): - from miasm.tools import win_api - fname = runtime_dll.fad2cname[my_eip] - if dbg: - print "call api", fname, hex(updw(vm_get_str(vm_get_gpreg()['esp'], 4))) - f = None - for m in api_modues: - if isinstance(m, dict): - if fname in m: - f = m[fname] - break - else: - if fname in m.__dict__: - f = m.__dict__[fname] - break - if not f: - print repr(fname) - raise ValueError('unknown api', hex(vm_pop_uint32_t())) - f() - regs = vm_get_gpreg() - return regs['eip'] - -def do_bloc_emul(known_blocs, in_str, my_eip, symbol_pool, - code_blocs_mem_range, dont_dis = [], job_done = None, - log_mn = False, log_regs = False, - segm_to_do = set(), dump_blocs = False, **kargs): - if not my_eip in known_blocs: - updt_bloc_emul(known_blocs, in_str, my_eip, - symbol_pool, code_blocs_mem_range, - log_regs = log_regs, log_mn = log_mn, - segm_to_do = segm_to_do) - vm_reset_exception() - if dump_blocs: - dump_gpregs_py() - print known_blocs[my_eip].b - - if not known_blocs[my_eip].b.lines: - raise ValueError('cannot disasm bloc') - try: - my_eip = vm_exec_bloc(my_eip, known_blocs) - except KeyboardInterrupt: - return None, None - py_exception = vm_get_exception() - return my_eip, py_exception - - -#try: -if True: - from emul_lib.libcodenat_interface import * - - #vm_init_regs = libcodenat.vm_init_regs -#except: -# print "WARNING! unable to build libcodenat C interface!!" - - - - - diff --git a/miasm/tools/win_api.py b/miasm/tools/win_api.py deleted file mode 100644 index 8eb62e95..00000000 --- a/miasm/tools/win_api.py +++ /dev/null @@ -1,3081 +0,0 @@ -# -# Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -from to_c_helper import * -import struct -try: - from Crypto.Hash import MD5 -except ImportError: - print "cannot find crypto MD5, skipping" -import inspect -from zlib import crc32 -import seh_helper -import os -import time - - - - -def get_next_alloc_addr(size): - global alloc_ad - ret = winobjs.alloc_ad - winobjs.alloc_ad = (winobjs.alloc_ad + size + winobjs.alloc_align-1) - winobjs.alloc_ad &= (0xffffffff ^ (winobjs.alloc_align-1)) - return ret - -""" -typedef struct tagPROCESSENTRY32 { - DWORD dwSize; - DWORD cntUsage; - DWORD th32ProcessID; - ULONG_PTR th32DefaultHeapID; - DWORD th32ModuleID; - DWORD cntThreads; - DWORD th32ParentProcessID; - LONG pcPriClassBase; - DWORD dwFlags; - TCHAR szExeFile[MAX_PATH]; -} PROCESSENTRY32, *PPROCESSENTRY32; -""" - - -access_dict = { 0x0: 0, - 0x1: 0, - 0x2: PAGE_READ, - 0x4: PAGE_READ | PAGE_WRITE, - 0x10: PAGE_EXEC, - 0x20: PAGE_EXEC | PAGE_READ, - 0x40: PAGE_EXEC | PAGE_READ | PAGE_WRITE, - 0x80: PAGE_EXEC | PAGE_READ | PAGE_WRITE, - # 0x80: PAGE_EXECUTE_WRITECOPY - 0x100: 0 - } - -access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()]) - -class whandle(): - def __init__(self, name, info): - self.name = name - self.info = info - def __repr__(self): - return '<%r %r %r>'%(self.__class__.__name__, self.name, self.info) - - -class handle_generator(): - def __init__(self): - self.offset = 600 - self.all_handles = {} - def add(self, name, info = None): - self.offset += 1 - h = whandle(name, info) - self.all_handles[self.offset] = h - - print repr(self) - return self.offset - - def __repr__(self): - out = '<%r\n'%self.__class__.__name__ - ks = self.all_handles.keys() - ks.sort() - - for k in ks: - out += " %r %r\n"%(k, self.all_handles[k]) - out +='>' - return out - - def __contains__(self, e): - return e in self.all_handles - - def __getitem__(self, item): - return self.all_handles.__getitem__(item) - def __delitem__(self, item): - self.all_handles.__delitem__(item) - - -class c_winobjs: - def __init__(self): - self.alloc_ad = 0x20000000 - self.alloc_align = 0x4000 - self.handle_toolhelpsnapshot = 0xaaaa00 - self.toolhelpsnapshot_info = {} - self.handle_curprocess = 0xaaaa01 - self.dbg_present = 0 - self.tickcount =0 - self.dw_pid_dummy1 = 0x111 - self.dw_pid_explorer = 0x222 - self.dw_pid_dummy2 = 0x333 - self.dw_pid_cur = 0x444 - self.module_fname_nux = None - self.module_name = "test.exe\x00" - self.module_path = "c:\\mydir\\"+self.module_name - self.hcurmodule = None - self.module_filesize = None - self.getversion = 0x0A280105 - self.getforegroundwindow = 0x333333 - self.cryptcontext_hwnd = 0x44400 - self.cryptcontext_bnum = 0x44000 - self.cryptcontext_num = 0 - self.cryptcontext = {} - self.phhash_crypt_md5 = 0x55555 - self.files_hwnd = {} - self.windowlong_dw = 0x77700 - self.module_cur_hwnd = 0x88800 - self.module_file_nul = 0x999000 - self.runtime_dll = None - self.current_pe = None - self.tls_index = 0xf - self.tls_values = {} - self.handle_pool = handle_generator() - self.hkey_handles = {0x80000001: "hkey_current_user"} - - self.nt_mdl = {} - self.nt_mdl_ad = None - self.nt_mdl_cur = 0 - self.win_event_num = 0x13370 - self.cryptdll_md5_h = {} - - self.lastwin32error = 0 - self.mutex = {} - self.env_variables = {} - self.events_pool = {} -winobjs = c_winobjs() - - - - - -def whoami(): - return inspect.stack()[1][3] - - -class hobj: - pass - - -class mdl: - def __init__(self, ad, l): - self.ad = ad - self.l = l - def __str__(self): - return struct.pack('LL', self.ad, self.l) - -def get_str_ansi(ad_str, max_char = None): - l = 0 - tmp = ad_str - while (max_char == None or l < max_char) and vm_get_str(tmp, 1) != "\x00": - tmp +=1 - l+=1 - return vm_get_str(ad_str, l) - -def get_str_unic(ad_str, max_char = None): - l = 0 - tmp = ad_str - while (max_char == None or l < max_char) and vm_get_str(tmp, 2) != "\x00\x00": - tmp +=2 - l+=2 - return vm_get_str(ad_str, l) - -def set_str_ansi(s): - return s + "\x00" - -def set_str_unic(s): - return "\x00".join(list(s))+'\x00'*3 - - -def kernel32_GlobalAlloc(): - ret_ad = vm_pop_uint32_t() - uflags = vm_pop_uint32_t() - msize = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(uflags), hex(msize), ')' - - alloc_addr = get_next_alloc_addr(msize) - vm_add_memory_page(alloc_addr, PAGE_READ|PAGE_WRITE, "\x00"*msize) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = alloc_addr - vm_set_gpreg(regs) - -def kernel32_LocalFree(): - ret_ad = vm_pop_uint32_t() - lpvoid = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(lpvoid), ')' - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - vm_set_gpreg(regs) - - -def kernel32_LocalAlloc(): - ret_ad = vm_pop_uint32_t() - uflags = vm_pop_uint32_t() - msize = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(uflags), hex(msize), ')' - alloc_addr = get_next_alloc_addr(msize) - vm_add_memory_page(alloc_addr, PAGE_READ|PAGE_WRITE, "\x00"*msize) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = alloc_addr - vm_set_gpreg(regs) - - -def kernel32_GlobalFree(): - ret_ad = vm_pop_uint32_t() - ad = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(ad), ')' - regs = vm_get_gpreg() - regs['eip'] = ret_ad - vm_set_gpreg(regs) - -def kernel32_IsDebuggerPresent(): - ret_ad = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', ')' - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = winobjs.dbg_present - vm_set_gpreg(regs) - - -def kernel32_CreateToolhelp32Snapshot(): - ret_ad = vm_pop_uint32_t() - dwflags = vm_pop_uint32_t() - th32processid = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(dwflags), hex(th32processid), ')' - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = winobjs.handle_toolhelpsnapshot - vm_set_gpreg(regs) - -def kernel32_GetCurrentProcess(): - ret_ad = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', ')' - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = winobjs.handle_curprocess - vm_set_gpreg(regs) - -def kernel32_GetCurrentProcessId(): - ret_ad = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', ')' - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = winobjs.dw_pid_cur - vm_set_gpreg(regs) - - -process_list = [ - [ - 0x40, #DWORD dwSize; - 0, #DWORD cntUsage; - winobjs.dw_pid_dummy1, #DWORD th32ProcessID; - 0x11111111, #ULONG_PTR th32DefaultHeapID; - 0x11111112, #DWORD th32ModuleID; - 1, #DWORD cntThreads; - winobjs.dw_pid_explorer, #DWORD th32ParentProcessID; - 0xbeef, #LONG pcPriClassBase; - 0x0, #DWORD dwFlags; - "dummy1.exe" #TCHAR szExeFile[MAX_PATH]; - ], - [ - 0x40, #DWORD dwSize; - 0, #DWORD cntUsage; - winobjs.dw_pid_explorer, #DWORD th32ProcessID; - 0x11111111, #ULONG_PTR th32DefaultHeapID; - 0x11111112, #DWORD th32ModuleID; - 1, #DWORD cntThreads; - 4, #DWORD th32ParentProcessID; - 0xbeef, #LONG pcPriClassBase; - 0x0, #DWORD dwFlags; - "explorer.exe" #TCHAR szExeFile[MAX_PATH]; - ], - - [ - 0x40, #DWORD dwSize; - 0, #DWORD cntUsage; - winobjs.dw_pid_dummy2, #DWORD th32ProcessID; - 0x11111111, #ULONG_PTR th32DefaultHeapID; - 0x11111112, #DWORD th32ModuleID; - 1, #DWORD cntThreads; - winobjs.dw_pid_explorer, #DWORD th32ParentProcessID; - 0xbeef, #LONG pcPriClassBase; - 0x0, #DWORD dwFlags; - "dummy2.exe" #TCHAR szExeFile[MAX_PATH]; - ], - - [ - 0x40, #DWORD dwSize; - 0, #DWORD cntUsage; - winobjs.dw_pid_cur, #DWORD th32ProcessID; - 0x11111111, #ULONG_PTR th32DefaultHeapID; - 0x11111112, #DWORD th32ModuleID; - 1, #DWORD cntThreads; - winobjs.dw_pid_explorer, #DWORD th32ParentProcessID; - 0xbeef, #LONG pcPriClassBase; - 0x0, #DWORD dwFlags; - winobjs.module_name #TCHAR szExeFile[MAX_PATH]; - ], - - -] - -def kernel32_Process32First(): - ret_ad = vm_pop_uint32_t() - s_handle = vm_pop_uint32_t() - ad_pentry = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(s_handle), hex(ad_pentry), ')' - - pentry = struct.pack('IIIIIIIII', *process_list[0][:-1])+process_list[0][-1] - vm_set_mem(ad_pentry, pentry) - winobjs.toolhelpsnapshot_info[s_handle] = 0 - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - - -def kernel32_Process32Next(): - ret_ad = vm_pop_uint32_t() - s_handle = vm_pop_uint32_t() - ad_pentry = vm_pop_uint32_t() - - winobjs.toolhelpsnapshot_info[s_handle] +=1 - if winobjs.toolhelpsnapshot_info[s_handle] >= len(process_list): - eax = 0 - else: - eax = 1 - n = winobjs.toolhelpsnapshot_info[s_handle] - print whoami(), hex(ret_ad), '(', hex(s_handle), hex(ad_pentry), ')' - pentry = struct.pack('IIIIIIIII', *process_list[n][:-1])+process_list[n][-1] - vm_set_mem(ad_pentry, pentry) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = eax - vm_set_gpreg(regs) - - - - -def kernel32_GetTickCount(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad), '(', ')' - winobjs.tickcount +=1 - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = winobjs.tickcount - vm_set_gpreg(regs) - - -def kernel32_GetVersion(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad), '(', ')' - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = winobjs.getversion - vm_set_gpreg(regs) - -def my_GetVersionEx(funcname, set_str): - ret_ad = vm_pop_uint32_t() - ptr_struct = vm_pop_uint32_t() - - print funcname, hex(ret_ad), '(', ')' - - s = struct.pack("IIIII", - 0x114, # struct size - 0x5, # maj vers - 0x2, # min vers - 0x666, # build nbr - 0x2, # platform id - ) + set_str("Service pack 4") - vm_set_mem(ptr_struct, s) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - -def kernel32_GetVersionExA(): - my_GetVersionEx(whoami(), set_str_ansi) -def kernel32_GetVersionExW(): - my_GetVersionEx(whoami(), set_str_unic) - - -def kernel32_GetPriorityClass(): - ret_ad = vm_pop_uint32_t() - hwnd = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(hwnd), ')' - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def kernel32_SetPriorityClass(): - ret_ad = vm_pop_uint32_t() - hwnd = vm_pop_uint32_t() - dwpclass = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(hwnd), hex(dwpclass),')' - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def kernel32_CloseHandle(): - ret_ad = vm_pop_uint32_t() - hwnd = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(hwnd),')' - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - -def user32_GetForegroundWindow(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad), '(', ')' - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = winobjs.getforegroundwindow - vm_set_gpreg(regs) - - - -def user32_FindWindowA(): - ret_ad = vm_pop_uint32_t() - pclassname = vm_pop_uint32_t() - pwindowname = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(pclassname), hex(pwindowname), ')' - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - - -def user32_GetTopWindow(): - ret_ad = vm_pop_uint32_t() - hwnd = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(hwnd), ')' - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def user32_BlockInput(): - ret_ad = vm_pop_uint32_t() - b = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(b), ')' - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - -def advapi32_CryptAcquireContext(funcname, get_str): - ret_ad = vm_pop_uint32_t() - phprov = vm_pop_uint32_t() - pszcontainer = vm_pop_uint32_t() - pszprovider = vm_pop_uint32_t() - dwprovtype = vm_pop_uint32_t() - dwflags = vm_pop_uint32_t() - - print funcname, hex(ret_ad), '(', hex(phprov), hex(pszcontainer), hex(pszprovider), hex(dwprovtype), hex(dwflags), ')' - - if pszprovider: - prov = get_str(pszprovider) - else: - prov = "NONE" - print 'prov:', prov - vm_set_mem(phprov, pdw(winobjs.cryptcontext_hwnd)) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - - -def advapi32_CryptAcquireContextA(): - advapi32_CryptAcquireContext(whoami(), get_str_ansi) -def advapi32_CryptAcquireContextW(): - advapi32_CryptAcquireContext(whoami(), get_str_unic) - - -def advapi32_CryptCreateHash(): - ret_ad = vm_pop_uint32_t() - hprov = vm_pop_uint32_t() - algid = vm_pop_uint32_t() - hkey = vm_pop_uint32_t() - dwflags = vm_pop_uint32_t() - phhash = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(hprov), hex(algid), hex(hkey), hex(dwflags), hex(phhash), ')' - - winobjs.cryptcontext_num +=1 - - if algid == 0x00008003: - print 'algo is MD5' - vm_set_mem(phhash, pdw(winobjs.cryptcontext_bnum+winobjs.cryptcontext_num)) - winobjs.cryptcontext[winobjs.cryptcontext_bnum+winobjs.cryptcontext_num] = hobj() - winobjs.cryptcontext[winobjs.cryptcontext_bnum+winobjs.cryptcontext_num].h = MD5.new() - else: - raise ValueError('un impl algo1') - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - -def advapi32_CryptHashData(): - ret_ad = vm_pop_uint32_t() - hhash = vm_pop_uint32_t() - pbdata = vm_pop_uint32_t() - dwdatalen = vm_pop_uint32_t() - dwflags = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(hhash), hex(pbdata), hex(dwdatalen), hex(dwflags), ')' - - if not hhash in winobjs.cryptcontext: - raise ValueError("unknown crypt context") - - data = vm_get_str(pbdata, dwdatalen) - print 'will hash' - print repr(data) - winobjs.cryptcontext[hhash].h.update(data) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - - -def advapi32_CryptGetHashParam(): - ret_ad = vm_pop_uint32_t() - hhash = vm_pop_uint32_t() - param = vm_pop_uint32_t() - pbdata = vm_pop_uint32_t() - dwdatalen = vm_pop_uint32_t() - dwflags = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(hhash), hex(pbdata), hex(dwdatalen), hex(dwflags), ')' - - if not hhash in winobjs.cryptcontext: - raise ValueError("unknown crypt context") - - - if param == 2: - # XXX todo: save h state? - h = winobjs.cryptcontext[hhash].h.digest() - else: - raise ValueError('not impl', param) - vm_set_mem(pbdata, h) - vm_set_mem(dwdatalen, pdw(len(h))) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - - - -def advapi32_CryptReleaseContext(): - ret_ad = vm_pop_uint32_t() - hhash = vm_pop_uint32_t() - flags = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(hhash), hex(flags), ')' - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - - -def advapi32_CryptDeriveKey(): - ret_ad = vm_pop_uint32_t() - hprov = vm_pop_uint32_t() - algid = vm_pop_uint32_t() - hbasedata = vm_pop_uint32_t() - dwflags = vm_pop_uint32_t() - phkey = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(hprov), hex(algid), hex(hbasedata), hex(dwflags), hex(phkey), ')' - - if algid == 0x6801: - print 'using DES' - else: - raise ValueError('un impl algo2') - h = winobjs.cryptcontext[hbasedata].h.digest() - print 'hash', repr(h) - winobjs.cryptcontext[hbasedata].h_result = h - vm_set_mem(phkey, pdw(hbasedata)) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - -def advapi32_CryptDestroyHash(): - ret_ad = vm_pop_uint32_t() - hhash = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(hhash), ')' - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - -def advapi32_CryptDecrypt(): - ret_ad = vm_pop_uint32_t() - hkey = vm_pop_uint32_t() - hhash = vm_pop_uint32_t() - final = vm_pop_uint32_t() - dwflags = vm_pop_uint32_t() - pbdata = vm_pop_uint32_t() - pdwdatalen = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(hkey), hex(hhash), hex(final), hex(dwflags), hex(pbdata), hex(pdwdatalen), ')' - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - - fdfsd - -def kernel32_CreateFile(funcname, get_str): - ret_ad = vm_pop_uint32_t() - lpfilename = vm_pop_uint32_t() - access = vm_pop_uint32_t() - dwsharedmode = vm_pop_uint32_t() - lpsecurityattr = vm_pop_uint32_t() - dwcreationdisposition = vm_pop_uint32_t() - dwflagsandattr = vm_pop_uint32_t() - htemplatefile = vm_pop_uint32_t() - - - - print funcname, hex(ret_ad), hex(lpfilename), hex(access), hex(dwsharedmode), hex(lpsecurityattr), hex(dwcreationdisposition), hex(dwflagsandattr), hex(htemplatefile) - - fname = get_str(lpfilename) - print 'fname', fname - - eax = 0xffffffff - - if fname.upper() in [r"\\.\SICE", r"\\.\NTICE", r"\\.\SIWVID"]: - pass - elif fname.upper() in ['NUL']: - eax = winobjs.module_cur_hwnd - else: - # nuxify path - fname = fname.replace('\\', "/").lower() - # go in sandbox files - f = os.path.join('file_sb', fname) - if access & 0x80000000: - # read - if not os.access(f, os.R_OK): - raise ValueError("file doesn't exit", f) - h = open(f, 'rb+') - eax = winobjs.handle_pool.add(f, h) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = eax - vm_set_gpreg(regs) - - -def kernel32_CreateFileA(): - kernel32_CreateFile(whoami(), get_str_ansi) -def kernel32_CreateFileW(): - kernel32_CreateFile(whoami(), lambda x:get_str_unic(x)[::2]) - - - -def kernel32_ReadFile(): - ret_ad = vm_pop_uint32_t() - hwnd = vm_pop_uint32_t() - lpbuffer = vm_pop_uint32_t() - nnumberofbytestoread = vm_pop_uint32_t() - lpnumberofbytesread = vm_pop_uint32_t() - lpoverlapped = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(hwnd), hex(lpbuffer), hex(nnumberofbytestoread), hex(lpnumberofbytesread), hex(lpoverlapped), ')' - - if hwnd == winobjs.module_cur_hwnd: - pass - elif hwnd in winobjs.handle_pool: - pass - else: - raise ValueError('unknown hwnd!') - - eax = 0xffffffff - data = None - if hwnd in winobjs.files_hwnd: - data = winobjs.files_hwnd[winobjs.module_cur_hwnd].read(nnumberofbytestoread) - elif hwnd in winobjs.handle_pool: - wh = winobjs.handle_pool[hwnd] - data = wh.info.read(nnumberofbytestoread) - else: - raise ValueError('unknown filename') - - if data != None: - if (lpnumberofbytesread): - vm_set_mem(lpnumberofbytesread, pdw(len(data))) - vm_set_mem(lpbuffer, data) - - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - -def kernel32_GetFileSize(): - ret_ad = vm_pop_uint32_t() - hwnd = vm_pop_uint32_t() - lpfilesizehight = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(hwnd), hex(lpfilesizehight), ')' - - if hwnd == winobjs.module_cur_hwnd: - eax = len(open(winobjs.module_fname_nux).read()) - elif hwnd in winobjs.handle_pool: - wh = winobjs.handle_pool[hwnd] - print wh - eax = len(open(wh.name).read()) - else: - raise ValueError('unknown hwnd!') - - if lpfilesizehight != 0: - vm_set_mem(lpfilesizehight, pdw(eax&0xffff0000)) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = eax - vm_set_gpreg(regs) - - -def kernel32_FlushInstructionCache(): - ret_ad = vm_pop_uint32_t() - hprocess = vm_pop_uint32_t() - lpbasead = vm_pop_uint32_t() - dwsize = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(hprocess), hex(lpbasead), hex(dwsize) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0x1337 - vm_set_gpreg(regs) - - - -def kernel32_VirtualProtect(): - ret_ad = vm_pop_uint32_t() - lpvoid = vm_pop_uint32_t() - dwsize = vm_pop_uint32_t() - flnewprotect = vm_pop_uint32_t() - lpfloldprotect = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(lpvoid), hex(dwsize), hex(flnewprotect), hex(lpfloldprotect), ')' - # XXX mask hpart - flnewprotect &= 0xFFF - - if not flnewprotect in access_dict: - raise ValueError( 'unknown access dw!') - vm_set_mem_access(lpvoid, access_dict[flnewprotect]) - - #XXX todo real old protect - if lpfloldprotect: - vm_set_mem(lpfloldprotect, pdw(0x40)) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - #dump_memory_page_pool_py() - - - -def kernel32_VirtualAlloc(): - ret_ad = vm_pop_uint32_t() - lpvoid = vm_pop_uint32_t() - dwsize = vm_pop_uint32_t() - alloc_type = vm_pop_uint32_t() - flprotect = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(lpvoid), hex(dwsize), hex(alloc_type), hex(flprotect), ')' - - access_dict = { 0x0: 0, - 0x1: 0, - 0x2: PAGE_READ, - 0x4: PAGE_READ | PAGE_WRITE, - 0x10: PAGE_EXEC, - 0x20: PAGE_EXEC | PAGE_READ, - 0x40: PAGE_EXEC | PAGE_READ | PAGE_WRITE, - 0x100: 0 - } - - access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()]) - - - if not flprotect in access_dict: - raise ValueError( 'unknown access dw!') - - - if lpvoid == 0: - alloc_addr = get_next_alloc_addr(dwsize) - vm_add_memory_page(alloc_addr, access_dict[flprotect], "\x00"*dwsize) - else: - alloc_addr = lpvoid - vm_set_mem_access(lpvoid, access_dict[flprotect]) - - - - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = alloc_addr - vm_set_gpreg(regs) - dump_memory_page_pool_py() - print 'ret', hex(alloc_addr), hex(ret_ad) - - -def kernel32_VirtualFree(): - ret_ad = vm_pop_uint32_t() - lpvoid = vm_pop_uint32_t() - dwsize = vm_pop_uint32_t() - alloc_type = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(lpvoid), hex(dwsize), hex(alloc_type), ')' - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - vm_set_gpreg(regs) - -def user32_GetWindowLongA(): - ret_ad = vm_pop_uint32_t() - hwnd = vm_pop_uint32_t() - nindex = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(hwnd), hex(nindex), ')' - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = winobjs.windowlong_dw - vm_set_gpreg(regs) - -def user32_SetWindowLongA(): - ret_ad = vm_pop_uint32_t() - hwnd = vm_pop_uint32_t() - nindex = vm_pop_uint32_t() - newlong = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(hwnd), hex(nindex), hex(newlong), ')' - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = winobjs.windowlong_dw - vm_set_gpreg(regs) - - - - -def kernel32_GetModuleFileName(funcname, set_str): - ret_ad = vm_pop_uint32_t() - hmodule = vm_pop_uint32_t() - lpfilename = vm_pop_uint32_t() - nsize = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(hmodule), hex(lpfilename), hex(nsize), ')' - - if hmodule in [0, winobjs.hcurmodule]: - p = winobjs.module_path[:] - elif winobjs.runtime_dll and hmodule in winobjs.runtime_dll.name2off.values() : - name_inv = dict([(x[1], x[0]) for x in winobjs.runtime_dll.name2off.items()]) - p = name_inv[hmodule] - else: - print ValueError('unknown module h', hex(hmodule)) - p = None - - - if p == None: - l = 0 - elif nsize < len(p): - p = p[:nsize] - l = len(p) - else: - l = len(p) - - print repr(p) - if p: - vm_set_mem(lpfilename, set_str(p)) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = l - vm_set_gpreg(regs) - - -def kernel32_GetModuleFileNameA(): - kernel32_GetModuleFileName(whoami(), set_str_ansi) -def kernel32_GetModuleFileNameW(): - kernel32_GetModuleFileName(whoami(), set_str_unic) - - - -def kernel32_CreateMutex(funcname, get_str): - ret_ad = vm_pop_uint32_t() - mutexattr = vm_pop_uint32_t() - initowner = vm_pop_uint32_t() - lpname = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(mutexattr), hex(initowner), hex(lpname) - - if lpname: - name = get_str(lpname) - print repr(name) - else: - name = None - if name in winobjs.mutex: - ret = 0 - else: - winobjs.mutex[name] = id(name) - ret = winobjs.mutex[name] - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ret - vm_set_gpreg(regs) - - -def kernel32_CreateMutexA(): - kernel32_CreateMutex(whoami(), get_str_ansi) -def kernel32_CreateMutexW(): - kernel32_CreateMutex(whoami(), get_str_unic) - - -def shell32_SHGetSpecialFolderLocation(): - ret_ad = vm_pop_uint32_t() - hwndowner = vm_pop_uint32_t() - nfolder = vm_pop_uint32_t() - ppidl = vm_pop_uint32_t() - print whoami(), hex(hwndowner), hex(nfolder), hex(ppidl) - - vm_set_mem(ppidl, pdw(nfolder)) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - - -def kernel32_SHGetPathFromIDList(funcname, set_str): - ret_ad = vm_pop_uint32_t() - pidl = vm_pop_uint32_t() - ppath = vm_pop_uint32_t() - print whoami(), hex(pidl), hex(ppath) - - if pidl == 7:# CSIDL_STARTUP: - s = "c:\\doc\\user\\startmenu\\programs\\startup" - s = set_str(s) - else: - raise ValueError('pidl not implemented', pidl) - vm_set_mem(ppath, s) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - -def shell32_SHGetPathFromIDListW(): - kernel32_SHGetPathFromIDList(whoami(), set_str_unic) -def shell32_SHGetPathFromIDListA(): - kernel32_SHGetPathFromIDList(whoami(), set_str_ansi) - - -def kernel32_GetLastError(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad), '(', ')' - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = winobjs.lastwin32error - vm_set_gpreg(regs) - -def kernel32_SetLastError(): - ret_ad = vm_pop_uint32_t() - e = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(e) - - #lasterr addr - ad = seh_helper.FS_0_AD + 0x34 - vm_set_mem(ad, pdw(e)) - - winobjs.lastwin32error = e - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - - -def kernel32_LoadLibraryA(): - ret_ad = vm_pop_uint32_t() - dllname = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(dllname) - - libname = get_str_ansi(dllname, 0x100) - print repr(libname) - - eax = winobjs.runtime_dll.lib_get_add_base(libname) - print "ret", hex(eax) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = eax - vm_set_gpreg(regs) - -def kernel32_GetProcAddress(): - ret_ad = vm_pop_uint32_t() - libbase = vm_pop_uint32_t() - fname = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(libbase), hex(fname) - fname = fname & 0xFFFFFFFF - if fname < 0x10000: - fname = fname - else: - fname = get_str_ansi(fname, 0x100) - if not fname: - fname = None - print repr(fname) - if fname != None: - ad = winobjs.runtime_dll.lib_get_add_func(libbase, fname) - else: - ad = 0 - ad = winobjs.runtime_dll.lib_get_add_func(libbase, fname) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ad - vm_set_gpreg(regs) - - - -def kernel32_LoadLibraryW(): - ret_ad = vm_pop_uint32_t() - dllname = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(dllname) - - libname = get_str_unic(dllname, 0x100)[::2] - print repr(libname) - - eax = winobjs.runtime_dll.lib_get_add_base(libname) - print "ret", hex(eax) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = eax - vm_set_gpreg(regs) - - -def kernel32_GetModuleHandle(funcname, get_str): - ret_ad = vm_pop_uint32_t() - dllname = vm_pop_uint32_t() - print funcname, hex(ret_ad), hex(dllname) - - if dllname: - libname = get_str(dllname) - print repr(libname) - if libname: - eax = winobjs.runtime_dll.lib_get_add_base(libname) - else: - print 'unknown module!' - eax = 0 - else: - eax = winobjs.current_pe.NThdr.ImageBase - print "default img base" , hex(eax) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = eax - vm_set_gpreg(regs) - -def kernel32_GetModuleHandleA(): - kernel32_GetModuleHandle(whoami(), get_str_ansi) -def kernel32_GetModuleHandleW(): - kernel32_GetModuleHandle(whoami(), lambda x:get_str_unic(x)[::2]) - - -def kernel32_VirtualLock(): - ret_ad = vm_pop_uint32_t() - lpaddress = vm_pop_uint32_t() - dwsize = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(lpaddress), hex(dwsize) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - - -def kernel32_GetSystemInfo(): - ret_ad = vm_pop_uint32_t() - sys_ptr = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(sys_ptr) - - vm_set_mem(sys_ptr, "\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x01\x00\xFF\xFF\xFE\x7F\x0F\x00\x00\x00\x04\x00\x00\x00\x4A\x02\x00\x00\x00\x00\x01\x00\x06\x00\x0B\x0F") - regs = vm_get_gpreg() - regs['eip'] = ret_ad - #regs['eax'] = 0 - vm_set_gpreg(regs) - -def kernel32_IsWow64Process(): - ret_ad = vm_pop_uint32_t() - h = vm_pop_uint32_t() - bool_ptr = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(h), hex(bool_ptr) - - vm_set_mem(bool_ptr, pdw(0)) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - -def kernel32_GetCommandLineA(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - - s = winobjs.module_path - s = '"%s"'%s - alloc_addr = get_next_alloc_addr(0x1000) - vm_add_memory_page(alloc_addr, PAGE_READ|PAGE_WRITE, s) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = alloc_addr - vm_set_gpreg(regs) - -def cryptdll_MD5Init(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - ad_ctx = vm_pop_uint32_t() - index = len(winobjs.cryptdll_md5_h) - h = MD5.new() - winobjs.cryptdll_md5_h[index] = h - - vm_set_mem(ad_ctx, pdw(index)) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - vm_set_gpreg(regs) - - -def cryptdll_MD5Update(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - ad_ctx = vm_pop_uint32_t() - ad_input = vm_pop_uint32_t() - inlen = vm_pop_uint32_t() - - index = vm_get_str(ad_ctx, 4) - index = updw(index) - if not index in winobjs.cryptdll_md5_h: - raise ValueError('unknown h context', index) - - data = vm_get_str(ad_input, inlen) - winobjs.cryptdll_md5_h[index].update(data) - print hexdump(data) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - vm_set_gpreg(regs) - -def cryptdll_MD5Final(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - - ad_ctx = vm_pop_uint32_t() - - index = vm_get_str(ad_ctx, 4) - index = updw(index) - if not index in winobjs.cryptdll_md5_h: - raise ValueError('unknown h context', index) - h = winobjs.cryptdll_md5_h[index].digest() - vm_set_mem(ad_ctx + 88, h) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - vm_set_gpreg(regs) - -def ntdll_RtlInitAnsiString(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - ad_ctx = vm_pop_uint32_t() - ad_str = vm_pop_uint32_t() - - s = get_str_ansi(ad_str) - l = len(s) - print "string", l, s - vm_set_mem(ad_ctx, pw(l)+pw(l+1)+pdw(ad_str)) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - vm_set_gpreg(regs) - - -def ntdll_RtlAnsiStringToUnicodeString(): - ret_ad = vm_pop_uint32_t() - ad_ctxu = vm_pop_uint32_t() - ad_ctxa = vm_pop_uint32_t() - alloc_dst = vm_pop_uint32_t() - - print whoami(), hex(ret_ad) - - l1, l2, ptra = struct.unpack('HHL', vm_get_str(ad_ctxa, 8)) - print hex(l1), hex(l2), hex(ptra) - - s = vm_get_str(ptra, l1) - print s - s = '\x00'.join(s) + "\x00\x00" - if alloc_dst: - alloc_addr = get_next_alloc_addr(0x1000) - vm_add_memory_page(alloc_addr , PAGE_READ | PAGE_WRITE, s) - - vm_set_mem(ad_ctxu, pw(len(s))+pw(len(s)+1)+pdw(alloc_addr)) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - - -def ntdll_RtlHashUnicodeString(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - ad_ctxu = vm_pop_uint32_t() - case_i = vm_pop_uint32_t() - h_id = vm_pop_uint32_t() - phout = vm_pop_uint32_t() - - print hex(h_id) - if h_id != 1: - raise ValueError('unk hash unicode', h_id) - - l1, l2, ptra = struct.unpack('HHL', vm_get_str(ad_ctxu, 8)) - print hex(l1), hex(l2), hex(ptra) - s = vm_get_str(ptra, l1) - print repr(s) - s = s[::2][:-1] - print repr(s) - hv = 0 - - if case_i: - s = s.lower() - for c in s: - hv = ((65599*hv)+ord(c) )&0xffffffff - print "unicode h", hex(hv) - vm_set_mem(phout, pdw(hv)) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def ntdll_RtlFreeUnicodeString(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - ad_ctxu = vm_pop_uint32_t() - l1, l2, ptra = struct.unpack('HHL', vm_get_str(ad_ctxu, 8)) - print l1, l2, hex(ptra) - s = vm_get_str(ptra, l1) - print 'free', repr(s) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - vm_set_gpreg(regs) - - - -def kernel32_RtlMoveMemory(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - ad_dst = vm_pop_uint32_t() - ad_src = vm_pop_uint32_t() - m_len = vm_pop_uint32_t() - print hex(ad_dst), hex(ad_src), hex(m_len) - data = vm_get_str(ad_src, m_len) - vm_set_mem(ad_dst, data) - print hexdump(data) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - vm_set_gpreg(regs) - - -def ntdll_RtlAnsiCharToUnicodeChar(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - ad_ad_ch = vm_pop_uint32_t() - print hex(ad_ad_ch) - ad_ch = updw(vm_get_str(ad_ad_ch, 4)) - print hex(ad_ch) - ch = ord(vm_get_str(ad_ch, 1)) - vm_set_mem(ad_ad_ch, pdw(ad_ch+1)) - - print repr(ch), repr(chr(ch)) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ch - vm_set_gpreg(regs) - -def ntdll_RtlFindCharInUnicodeString(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - flags = vm_pop_uint32_t() - main_str_ad = vm_pop_uint32_t() - search_chars_ad = vm_pop_uint32_t() - pos_ad = vm_pop_uint32_t() - - print flags - if flags != 0: - raise ValueError('unk flags') - - ml1, ml2, mptra = struct.unpack('HHL', vm_get_str(main_str_ad, 8)) - print ml1, ml2, hex(mptra) - sl1, sl2, sptra = struct.unpack('HHL', vm_get_str(search_chars_ad, 8)) - print sl1, sl2, hex(sptra) - main_data= vm_get_str(mptra, ml1)[:-1] - search_data= vm_get_str(sptra, sl1)[:-1] - - print repr(main_data[::2]) - print repr(search_data) - - pos = None - for i, c in enumerate(main_data): - for s in search_data: - if s == c: - pos = i - break - if pos: - break - print pos - regs = vm_get_gpreg() - regs['eip'] = ret_ad - if pos == None: - regs['eax'] = 0xC0000225 - vm_set_mem(pos_ad, pdw(0)) - else: - regs['eax'] = 0 - vm_set_mem(pos_ad, pdw(pos)) - vm_set_gpreg(regs) - print 'ret', hex(regs['eax']) - -def ntdll_RtlComputeCrc32(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - dwinit = vm_pop_uint32_t() - pdata = vm_pop_uint32_t() - ilen = vm_pop_uint32_t() - - - data = vm_get_str(pdata, ilen) - print hex(dwinit) - print hexdump(data) - crc_r = crc32(data, dwinit) - print "crc32", hex(crc_r) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = crc_r - vm_set_gpreg(regs) - -def ntdll_RtlExtendedIntegerMultiply(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - b2 = vm_pop_uint32_t() - b1 = vm_pop_uint32_t() - bm = vm_pop_uint32_t() - print hex(b1), hex(b2), hex(bm) - a = (b1<<32)+b2 - a = a*bm - print hex(a) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = (a&0xffffffff) - regs['edx'] = (a>>32)&0xffffffff - - vm_set_gpreg(regs) - -def ntdll_RtlLargeIntegerAdd(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - a2 = vm_pop_uint32_t() - a1 = vm_pop_uint32_t() - b2 = vm_pop_uint32_t() - b1 = vm_pop_uint32_t() - print hex(a1), hex(a2), hex(b1), hex(b2) - a = (a1<<32)+a2 + (b1<<32)+b2 - print hex(a) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = (a&0xffffffff) - regs['edx'] = (a>>32)&0xffffffff - - vm_set_gpreg(regs) - -def ntdll_RtlLargeIntegerShiftRight(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - a2 = vm_pop_uint32_t() - a1 = vm_pop_uint32_t() - m = vm_pop_uint32_t() - print hex(a1), hex(a2), hex(m) - a = ((a1<<32)+a2)>>m - print hex(a) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = (a&0xffffffff) - regs['edx'] = (a>>32)&0xffffffff - - vm_set_gpreg(regs) - -def ntdll_RtlEnlargedUnsignedMultiply(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - a = vm_pop_uint32_t()&0xFFFFFFFF - b = vm_pop_uint32_t()&0xFFFFFFFF - print hex(a), hex(b) - a = a*b - print hex(a) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = (a&0xffffffff) - regs['edx'] = (a>>32)&0xffffffff - - vm_set_gpreg(regs) - -def ntdll_RtlLargeIntegerSubtract(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - a2 = vm_pop_uint32_t() - a1 = vm_pop_uint32_t() - b2 = vm_pop_uint32_t() - b1 = vm_pop_uint32_t() - print hex(a1), hex(a2), hex(b1), hex(b2) - a = (a1<<32)+a2 - (b1<<32)+b2 - print hex(a) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = (a&0xffffffff) - regs['edx'] = (a>>32)&0xffffffff - - vm_set_gpreg(regs) - - -def ntdll_RtlCompareMemory(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - ad1 = vm_pop_uint32_t() - ad2 = vm_pop_uint32_t() - m_len = vm_pop_uint32_t() - print hex(ad1), hex(ad2), hex(m_len) - data1 = vm_get_str(ad1, m_len) - data2 = vm_get_str(ad2, m_len) - - print hexdump(data1) - print hexdump(data2) - i = 0 - while data1[i] == data2[i]: - i+=1 - if i >=m_len: - break - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = i - vm_set_gpreg(regs) - print 'compare ret:', i - - -def user32_GetMessagePos(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0x00110022 - vm_set_gpreg(regs) - -def kernel32_Sleep(): - ret_ad = vm_pop_uint32_t() - t = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(t) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - vm_set_gpreg(regs) - - #XXX for malware tests - vm_set_mem(regs['esp']-0x20, pdw(0xFFFFFFFF)) - -def ntdll_ZwUnmapViewOfSection(): - ret_ad = vm_pop_uint32_t() - h = vm_pop_uint32_t() - ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(h), hex(ad) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def kernel32_IsBadReadPtr(): - ret_ad = vm_pop_uint32_t() - lp = vm_pop_uint32_t() - ucb = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(lp), hex(ucb) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def ntoskrnl_KeInitializeEvent(): - ret_ad = vm_pop_uint32_t() - my_event = vm_pop_uint32_t() - my_type = vm_pop_uint32_t() - my_state = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(my_event), hex(my_type), hex(my_state) - vm_set_mem(my_event, pdw(winobjs.win_event_num)) - winobjs.win_event_num +=1 - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - - -def ntoskrnl_RtlGetVersion(): - ret_ad = vm_pop_uint32_t() - ptr_version = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(ptr_version) - - s = struct.pack("IIIII", - 0x114, # struct size - 0x5, # maj vers - 0x2, # min vers - 0x666, # build nbr - 0x2, # platform id - ) + set_str_unic("Service pack 4") - - vm_set_mem(ptr_version, s) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def ntoskrnl_RtlVerifyVersionInfo(): - ret_ad = vm_pop_uint32_t() - ptr_version = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(ptr_version) - - s = vm_get_str(ptr_version, 0x5*4) - print repr(s) - s_size, s_majv, s_minv, s_buildn, s_platform = struct.unpack('IIIII', s) - print s_size, s_majv, s_minv, s_buildn, s_platform - fds - vm_set_mem(ptr_version, s) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - - -def hal_ExAcquireFastMutex(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def mdl2ad(n): - return winobjs.nt_mdl_ad+0x10*n - -def ad2mdl(ad): - return ((ad-winobjs.nt_mdl_ad)&0xFFFFFFFFL)/0x10 - -def ntoskrnl_IoAllocateMdl(): - ret_ad = vm_pop_uint32_t() - v_addr = vm_pop_uint32_t() - l = vm_pop_uint32_t() - second_buf = vm_pop_uint32_t() - chargequota = vm_pop_uint32_t() - pirp = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(v_addr), hex(l), hex(second_buf), hex(chargequota), hex(pirp) - m = mdl(v_addr, l) - winobjs.nt_mdl[winobjs.nt_mdl_cur] = m - vm_set_mem(mdl2ad(winobjs.nt_mdl_cur), str(m)) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = mdl2ad(winobjs.nt_mdl_cur) - vm_set_gpreg(regs) - - winobjs.nt_mdl_cur += 1 - -def ntoskrnl_MmProbeAndLockPages(): - ret_ad = vm_pop_uint32_t() - p_mdl = vm_pop_uint32_t()&0xffffffff - access_mode = vm_pop_uint32_t() - op = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(p_mdl), hex(access_mode), hex(op) - - if not ad2mdl(p_mdl) in winobjs.nt_mdl: - raise ValueError('unk mdl', hex(p_mdl)) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def ntoskrnl_MmMapLockedPagesSpecifyCache(): - ret_ad = vm_pop_uint32_t() - p_mdl = vm_pop_uint32_t()&0xffffffff - access_mode = vm_pop_uint32_t() - cache_type = vm_pop_uint32_t() - base_ad = vm_pop_uint32_t() - bugcheckonfailure = vm_pop_uint32_t() - priority = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(p_mdl), hex(access_mode), hex(cache_type), hex(base_ad), hex(bugcheckonfailure), hex(priority) - if not ad2mdl(p_mdl) in winobjs.nt_mdl: - raise ValueError('unk mdl', hex(p_mdl)) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = winobjs.nt_mdl[ad2mdl(p_mdl)].ad - vm_set_gpreg(regs) - -def ntoskrnl_MmProtectMdlSystemAddress(): - ret_ad = vm_pop_uint32_t() - p_mdl = vm_pop_uint32_t()&0xffffffff - prot = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(p_mdl), hex(prot) - if not ad2mdl(p_mdl) in winobjs.nt_mdl: - raise ValueError('unk mdl', hex(p_mdl)) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def ntoskrnl_MmUnlockPages(): - ret_ad = vm_pop_uint32_t() - p_mdl = vm_pop_uint32_t()&0xffffffff - print whoami(), hex(ret_ad), hex(p_mdl) - if not ad2mdl(p_mdl) in winobjs.nt_mdl: - raise ValueError('unk mdl', hex(p_mdl)) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def ntoskrnl_IoFreeMdl(): - ret_ad = vm_pop_uint32_t() - p_mdl = vm_pop_uint32_t()&0xffffffff - print whoami(), hex(ret_ad), hex(p_mdl) - if not ad2mdl(p_mdl) in winobjs.nt_mdl: - raise ValueError('unk mdl', hex(p_mdl)) - del(winobjs.nt_mdl[ad2mdl(p_mdl)]) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def hal_ExReleaseFastMutex(): - ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) -def ntoskrnl_RtlQueryRegistryValues(): - ret_ad = vm_pop_uint32_t() - relativeto = vm_pop_uint32_t() - path = vm_pop_uint32_t() - querytable = vm_pop_uint32_t() - context = vm_pop_uint32_t() - environ = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(relativeto), hex(path), hex(querytable), hex(context), hex(environ) - p = get_str_unic(path) - print repr(p[::2]) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def ntoskrnl_ExAllocatePoolWithTagPriority(): - ret_ad = vm_pop_uint32_t() - pool_type = vm_pop_uint32_t() - nbr_of_bytes = vm_pop_uint32_t() - tag = vm_pop_uint32_t() - priority = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(pool_type), hex(nbr_of_bytes), hex(tag), hex(priority) - - alloc_addr = get_next_alloc_addr(nbr_of_bytes) - vm_add_memory_page(alloc_addr, PAGE_READ|PAGE_WRITE, "\x00"*nbr_of_bytes) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = alloc_addr - vm_set_gpreg(regs) - - print "ad", hex(alloc_addr) - - - - - -def my_lstrcmp(funcname, get_str): - ret_ad = vm_pop_uint32_t() - ptr_str1 = vm_pop_uint32_t() - ptr_str2 = vm_pop_uint32_t() - print "%s (%08x, %08x) (ret @ %08x)" % (funcname, - ptr_str1, ptr_str2, - ret_ad) - s1 = get_str(ptr_str1) - s2 = get_str(ptr_str2) - print '%s (%r, %r)' % (' '*len(funcname), s1, s2) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = cmp(s1, s2) - vm_set_gpreg(regs) - -def kernel32_lstrcmpA(): - my_lstrcmp(whoami(), get_str_ansi) - -def kernel32_lstrcmpiA(): - my_lstrcmp(whoami(), lambda x: get_str_ansi(x).lower()) - -def kernel32_lstrcmpW(): - my_lstrcmp(whoami(), get_str_unic) - -def kernel32_lstrcmpiW(): - my_lstrcmp(whoami(), lambda x: get_str_unic(x).lower()) - -def kernel32_lstrcmpi(): - my_lstrcmp(whoami(), lambda x: get_str_ansi(x).lower()) - - - -def my_strcpy(funcname, get_str, set_str): - ret_ad = vm_pop_uint32_t() - ptr_str1 = vm_pop_uint32_t() - ptr_str2 = vm_pop_uint32_t() - print "%s (%08x, %08x) (ret @ %08x)" % (funcname, - ptr_str1, ptr_str2, - ret_ad) - s2 = get_str(ptr_str2) - print '%s (%r)' % (funcname, s2) - vm_set_mem(ptr_str1, set_str(s2)) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ptr_str1 - vm_set_gpreg(regs) - -def kernel32_lstrcpyW(): - my_strcpy(whoami(), get_str_unic, lambda x:x+"\x00\x00") - -def kernel32_lstrcpyA(): - my_strcpy(whoami(), get_str_ansi, lambda x:x+"\x00") - -def kernel32_lstrcpy(): - my_strcpy(whoami(), get_str_ansi, lambda x:x+"\x00") - - -def kernel32_lstrcpyn(): - ret_ad = vm_pop_uint32_t() - ptr_str1 = vm_pop_uint32_t() - ptr_str2 = vm_pop_uint32_t() - mlen = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(ptr_str1), hex(ptr_str2), hex(mlen) - - s2 = get_str_ansi(ptr_str2) - print repr(s2) - s2 = s2[:mlen] - vm_set_mem(ptr_str1, s2) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ptr_str1 - vm_set_gpreg(regs) - -def my_strlen(funcname, get_str, mylen): - ret_ad = vm_pop_uint32_t() - arg_src = vm_pop_uint32_t() - - print funcname, hex(ret_ad), '(', hex(arg_src), ')' - src = get_str(arg_src) - print funcname, repr(src) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = mylen(src) - vm_set_gpreg(regs) - -def kernel32_lstrlenA(): - my_strlen(whoami(), get_str_ansi, lambda x:len(x)) -def kernel32_lstrlenW(): - my_strlen(whoami(), get_str_unic, lambda x:len(x[::2])) - - -def my_lstrcat(funcname, get_str): - ret_ad = vm_pop_uint32_t() - ptr_str1 = vm_pop_uint32_t() - ptr_str2 = vm_pop_uint32_t() - print "%s (%08x, %08x) (ret @ %08x)" % (funcname, - ptr_str1, ptr_str2, - ret_ad) - s1 = get_str(ptr_str1) - s2 = get_str(ptr_str2) - print '%s (%r, %r)' % (whoami(), s1, s2) - - s = s1+s2 - print repr(s) - vm_set_mem(ptr_str1, s1+s2) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ptr_str1 - vm_set_gpreg(regs) - -def kernel32_lstrcatA(): - my_lstrcat(whoami(), get_str_ansi) -def kernel32_lstrcatW(): - my_lstrcat(whoami(), get_str_unic) - - -def kernel32_GetUserGeoID(): - ret_ad = vm_pop_uint32_t() - geoclass = vm_pop_uint32_t() - print whoami(), hex(geoclass) - - if geoclass == 14: - ret = 12345678 - elif geoclass == 16: - ret = 55667788 - else: - raise ValueError('unknown geolcass') - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ret - vm_set_gpreg(regs) - - -def my_GetVolumeInformation(funcname, get_str, set_str): - ret_ad = vm_pop_uint32_t() - lprootpathname = vm_pop_uint32_t() - lpvolumenamebuffer = vm_pop_uint32_t() - nvolumenamesize = vm_pop_uint32_t() - lpvolumeserialnumber = vm_pop_uint32_t() - lpmaximumcomponentlength = vm_pop_uint32_t() - lpfilesystemflags = vm_pop_uint32_t() - lpfilesystemnamebuffer = vm_pop_uint32_t() - nfilesystemnamesize = vm_pop_uint32_t() - - print funcname,hex(lprootpathname),hex(lpvolumenamebuffer),\ - hex(nvolumenamesize),hex(lpvolumeserialnumber),\ - hex(lpmaximumcomponentlength),hex(lpfilesystemflags),\ - hex(lpfilesystemnamebuffer),hex(nfilesystemnamesize) - - if lprootpathname: - s = get_str(lprootpathname) - print repr(s) - - if lpvolumenamebuffer: - s = "volumename" - s = s[:nvolumenamesize] - vm_set_mem(lpvolumenamebuffer, set_str(s)) - - if lpvolumeserialnumber: - vm_set_mem(lpvolumeserialnumber, pdw(11111111)) - if lpmaximumcomponentlength: - vm_set_mem(lpmaximumcomponentlength, pdw(0xff)) - if lpfilesystemflags: - vm_set_mem(lpfilesystemflags, pdw(22222222)) - - if lpfilesystemnamebuffer: - s = "filesystemname" - s = s[:nfilesystemnamesize] - vm_set_mem(lpfilesystemnamebuffer, set_str(s)) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - -def kernel32_GetVolumeInformationA(): - my_GetVolumeInformation(whoami(), get_str_ansi, lambda x:x+"\x00") -def kernel32_GetVolumeInformationW(): - my_GetVolumeInformation(whoami(), get_str_unic, set_str_unic) - -def kernel32_MultiByteToWideChar(): - ret_ad = vm_pop_uint32_t() - codepage = vm_pop_uint32_t() - dwflags = vm_pop_uint32_t() - lpmultibytestr = vm_pop_uint32_t() - cbmultibyte = vm_pop_uint32_t() - lpwidecharstr = vm_pop_uint32_t() - cchwidechar = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), \ - hex(codepage),hex(dwflags),hex(lpmultibytestr),hex(cbmultibyte),hex(lpwidecharstr),hex(cchwidechar) - src = get_str_ansi(lpmultibytestr)+'\x00' - l = len(src) - print repr(src) - - src = "\x00".join(list(src)) - print repr(src), hex(len(src)) - vm_set_mem(lpwidecharstr, src) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = l - vm_set_gpreg(regs) - -def my_GetEnvironmentVariable(funcname, get_str, set_str, mylen): - ret_ad = vm_pop_uint32_t() - lpname = vm_pop_uint32_t() - lpbuffer = vm_pop_uint32_t() - nsize = vm_pop_uint32_t() - - print funcname,hex(lpname), hex(lpbuffer), hex(nsize) - s = get_str(lpname) - if get_str == get_str_unic: - s = s[::2] - print 'variable', repr(s) - if s in winobjs.env_variables: - v = set_str(winobjs.env_variables[s]) - else: - print 'WARNING unknown env variable', repr(s) - v = "" - print 'return', repr(v) - vm_set_mem(lpbuffer, v) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = mylen(v) - vm_set_gpreg(regs) - -def my_GetSystemDirectory(funcname, set_str): - ret_ad = vm_pop_uint32_t() - lpbuffer = vm_pop_uint32_t() - usize = vm_pop_uint32_t() - print "%s (%08x, %08x) (ret @ %08x)" % (whoami(), - lpbuffer,usize, - ret_ad) - - s = "c:\\windows\\system32" - l = len(s) - s = set_str(s) - vm_set_mem(lpbuffer, s) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = l - vm_set_gpreg(regs) - - -def kernel32_GetSystemDirectoryA(): - my_GetSystemDirectory(whoami(), set_str_ansi) -def kernel32_GetSystemDirectoryW(): - my_GetSystemDirectory(whoami(), set_str_unic) - - -def my_CreateDirectory(funcname, get_str): - ret_ad = vm_pop_uint32_t() - lppath = vm_pop_uint32_t() - secattrib = vm_pop_uint32_t() - print "%s (%08x, %08x) (ret @ %08x)" % (funcname, - lppath,secattrib, - ret_ad) - p = get_str(lppath) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0x1337 - vm_set_gpreg(regs) - -def kernel32_CreateDirectoryW(): - my_CreateDirectory(whoami(), get_str_unic) -def kernel32_CreateDirectoryW(): - my_CreateDirectory(whoami(), get_str_ansi) - - - -def kernel32_GetEnvironmentVariableA(): - my_GetEnvironmentVariable(whoami(), - get_str_ansi, - lambda x:x+"\x00", - lambda x:len(x)) - -def kernel32_GetEnvironmentVariableW(): - my_GetEnvironmentVariable(whoami(), - get_str_unic, - lambda x:"\x00".join(list(x+"\x00")), - lambda x:len(x[::2])) - -def my_CreateEvent(funcname, get_str): - ret_ad = vm_pop_uint32_t() - lpeventattributes = vm_pop_uint32_t() - bmanualreset = vm_pop_uint32_t() - binitialstate = vm_pop_uint32_t() - lpname = vm_pop_uint32_t() - - print funcname, hex(lpeventattributes), hex(bmanualreset), hex(binitialstate), hex(lpname) - if lpname: - s = get_str(lpname) - else: - s = None - print repr(s) - if not s in winobjs.events_pool: - winobjs.events_pool[s] = (bmanualreset, binitialstate) - else: - print 'WARNING: known event' - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = id(s) - vm_set_gpreg(regs) - -def kernel32_CreateEventA(): - my_CreateEvent(whoami(), get_str_ansi) -def kernel32_CreateEventA(): - my_CreateEvent(whoami(), get_str_unic) - - - -def kernel32_WaitForSingleObject(): - ret_ad = vm_pop_uint32_t() - handle = vm_pop_uint32_t() - dwms = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(handle), hex(dwms) - - t_start = time.time()*1000 - while True: - if dwms and dwms+t_start > time.time()*1000: - ret = 0x102 - break - for k, v in winobjs.events_pool.items(): - if k != handle: - continue - if winobjs.events_pool[k][1] == 1: - ret = 0 - break - time.sleep(0.1) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ret - vm_set_gpreg(regs) - - -def kernel32_SetFileAttributesA(): - ret_ad = vm_pop_uint32_t() - lpfilename = vm_pop_uint32_t() - dwfileattributes = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(lpfilename), hex(dwfileattributes) - - if lpfilename: - fname = get_str_ansi(lpfilename) - print "filename", repr(fname) - eax = 1 - else: - eax = 0 - vm_set_mem(seh_helper.FS_0_AD+0x34, pdw(3)) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = eax - vm_set_gpreg(regs) - -def ntdll_RtlMoveMemory(): - ret_ad = vm_pop_uint32_t() - dst = vm_pop_uint32_t() - src = vm_pop_uint32_t() - l = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(dst), hex(src), hex(l) - - - s = vm_get_str(src, l) - vm_set_mem(dst, s) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - -def ntdll_ZwQuerySystemInformation(): - ret_ad = vm_pop_uint32_t() - systeminformationclass = vm_pop_uint32_t() - systeminformation = vm_pop_uint32_t() - systeminformationl = vm_pop_uint32_t() - returnl = vm_pop_uint32_t() - print whoami(), hex(ret_ad), - print hex(systeminformationclass), hex(systeminformation), hex(systeminformationl), hex(returnl) - - if systeminformationclass == 2: - # SYSTEM_PERFORMANCE_INFORMATION - o = struct.pack('II', 0x22222222, 0x33333333) - o += "\x00"*systeminformationl - o = o[:systeminformationl] - vm_set_mem(systeminformation, o) - else: - raise ValueError('unknown sysinfo class', systeminformationclass) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def ntdll_ZwProtectVirtualMemory(): - ret_ad = vm_pop_uint32_t() - handle = vm_pop_uint32_t() - lppvoid = vm_pop_uint32_t() - pdwsize = vm_pop_uint32_t() - flnewprotect = vm_pop_uint32_t() - lpfloldprotect = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(handle), hex(lppvoid), hex(pdwsize), hex(flnewprotect), hex(lpfloldprotect), ')' - - ad = updw(vm_get_str(lppvoid, 4)) - dwsize = updw(vm_get_str(pdwsize, 4)) - print 'ad', hex(ad), 'size', hex(dwsize) - # XXX mask hpart - flnewprotect &= 0xFFF - - - if not flnewprotect in access_dict: - raise ValueError( 'unknown access dw!') - vm_set_mem_access(ad, access_dict[flnewprotect]) - - #XXX todo real old protect - vm_set_mem(lpfloldprotect, pdw(0x40)) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - dump_memory_page_pool_py() - - - -def ntdll_ZwAllocateVirtualMemory(): - ret_ad = vm_pop_uint32_t() - handle = vm_pop_uint32_t() - lppvoid = vm_pop_uint32_t() - zerobits = vm_pop_uint32_t() - pdwsize = vm_pop_uint32_t() - alloc_type = vm_pop_uint32_t() - flprotect = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', - print hex(lppvoid), hex(zerobits), hex(pdwsize), hex(alloc_type), hex(flprotect), ')' - ad = updw(vm_get_str(lppvoid, 4)) - dwsize = updw(vm_get_str(pdwsize, 4)) - print 'ad', hex(ad), 'size', hex(dwsize) - - - access_dict = { 0x0: 0, - 0x1: 0, - 0x2: PAGE_READ, - 0x4: PAGE_READ | PAGE_WRITE, - 0x10: PAGE_EXEC, - 0x20: PAGE_EXEC | PAGE_READ, - 0x40: PAGE_EXEC | PAGE_READ | PAGE_WRITE, - 0x100: 0 - } - - access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()]) - - - if not flprotect in access_dict: - raise ValueError( 'unknown access dw!') - - alloc_addr = get_next_alloc_addr(dwsize) - vm_add_memory_page(alloc_addr, access_dict[flprotect], "\x00"*dwsize) - vm_set_mem(lppvoid, pdw(alloc_addr)) - - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - dump_memory_page_pool_py() - print 'ret', hex(alloc_addr), hex(ret_ad) - -def ntdll_ZwFreeVirtualMemory(): - ret_ad = vm_pop_uint32_t() - handle = vm_pop_uint32_t() - lppvoid = vm_pop_uint32_t() - pdwsize = vm_pop_uint32_t() - alloc_type = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(handle), hex(lppvoid), hex(pdwsize), hex(alloc_type), ')' - ad = updw(vm_get_str(lppvoid, 4)) - dwsize = updw(vm_get_str(pdwsize, 4)) - print 'ad', hex(ad), 'size', hex(dwsize) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - vm_set_gpreg(regs) - - -def ntdll_RtlInitString(): - ret_ad = vm_pop_uint32_t() - pstring = vm_pop_uint32_t() - source = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(pstring), hex(source), ')' - s = get_str_ansi(source) - print "str", repr(s) - - l = len(s)+1 - - o = struct.pack('HHI', l, l, source) - vm_set_mem(pstring, o) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - vm_set_gpreg(regs) - - -def ntdll_RtlAnsiStringToUnicodeString(): - ret_ad = vm_pop_uint32_t() - dst = vm_pop_uint32_t() - src = vm_pop_uint32_t() - alloc_str = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(dst), hex(src), hex(alloc_str), ')' - - l1, l2, p_src = struct.unpack('HHI', vm_get_str(src, 0x8)) - print hex(l1), hex(l2), hex(p_src) - s = get_str_ansi(p_src) - print "str", repr(s) - s = ("\x00".join(s+"\x00")) - l = len(s)+1 - if alloc_str: - print 'alloc' - alloc_addr = get_next_alloc_addr(l) - vm_add_memory_page(alloc_addr, PAGE_READ | PAGE_WRITE, "\x00"*l) - else: - print 'use buf' - alloc_addr = p_src - vm_set_mem(alloc_addr, s) - o = struct.pack('HHI', l, l, alloc_addr) - vm_set_mem(dst, o) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def ntdll_LdrLoadDll(): - ret_ad = vm_pop_uint32_t() - path = vm_pop_uint32_t() - flags = vm_pop_uint32_t() - modname = vm_pop_uint32_t() - modhandle = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(path), hex(flags), hex(modname), hex(modhandle), ')' - l1, l2, p_src = struct.unpack('HHI', vm_get_str(modname, 0x8)) - print hex(l1), hex(l2), hex(p_src) - s = get_str_unic(p_src) - print repr(s) - libname = s[::2].lower() - print repr(libname) - - ad = winobjs.runtime_dll.lib_get_add_base(libname) - print "ret", hex(ad) - vm_set_mem(modhandle, pdw(ad)) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def ntdll_RtlFreeUnicodeString(): - ret_ad = vm_pop_uint32_t() - src = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(src), ')' - - l1, l2, p_src = struct.unpack('HHI', vm_get_str(src, 0x8)) - print hex(l1), hex(l2), hex(p_src) - s = get_str_unic(p_src) - print "str", repr(s) - print repr(s[::2]) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - - -def ntdll_LdrGetProcedureAddress(): - ret_ad = vm_pop_uint32_t() - libbase = vm_pop_uint32_t() - pfname = vm_pop_uint32_t() - opt = vm_pop_uint32_t() - p_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad), hex(libbase), hex(pfname), hex(opt), hex(p_ad) - - l1, l2, p_src = struct.unpack('HHI', vm_get_str(pfname, 0x8)) - print hex(l1), hex(l2), hex(p_src) - fname = get_str_ansi(p_src) - print "str", repr(fname) - - ad = winobjs.runtime_dll.lib_get_add_func(libbase, fname) - - vm_set_mem(p_ad, pdw(ad)) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def ntdll_memset(): - ret_ad = vm_pop_uint32_t() - arg_addr = vm_pop_uint32_t() - arg_c = vm_pop_uint32_t() - arg_size = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', hex(arg_addr), arg_c, arg_size, ')' - vm_set_mem(arg_addr, chr(arg_c)*arg_size) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = arg_addr - vm_set_gpreg(regs) - - - -def shlwapi_PathFindExtensionA(): - ret_ad = vm_pop_uint32_t() - path_ad = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(path_ad) - path = get_str_ansi(path_ad) - print repr(path) - i = path.rfind('.') - if i == -1: - i = path_ad + len(path) - else: - i = path_ad + i - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = i - vm_set_gpreg(regs) - -def shlwapi_PathIsPrefixW(): - ret_ad = vm_pop_uint32_t() - ptr_prefix = vm_pop_uint32_t() - ptr_path = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(ptr_prefix), hex(ptr_path) - prefix = get_str_unic(ptr_prefix) - path = get_str_unic(ptr_path) - print repr(prefix), repr(path) - - if path.startswith(prefix): - ret = 1 - else: - ret = 0 - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ret - vm_set_gpreg(regs) - - - -def shlwapi_PathIsFileSpec(funcname, get_str): - ret_ad = vm_pop_uint32_t() - path_ad = vm_pop_uint32_t() - - print funcname, hex(ret_ad), hex(path_ad) - path = get_str(path_ad) - print repr(path) - if path.find(':') != -1 and path.find('\\') != -1: - ret = 0 - else: - ret = 1 - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ret - vm_set_gpreg(regs) - -def shlwapi_PathGetDriveNumber(funcname, get_str): - ret_ad = vm_pop_uint32_t() - path_ad = vm_pop_uint32_t() - - print funcname, hex(ret_ad), hex(path_ad) - path = get_str(path_ad) - print repr(path) - l = ord(path[0].upper()) - ord('A') - if 0 <=l <=25: - ret = l - else: - ret = -1 - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ret - vm_set_gpreg(regs) - -def shlwapi_PathGetDriveNumberA(): - shlwapi_PathGetDriveNumber(whoami(), get_str_ansi) - -def shlwapi_PathGetDriveNumberW(): - shlwapi_PathGetDriveNumber(whoami(), get_str_unic) - - - -def shlwapi_PathIsFileSpecA(): - shlwapi_PathIsFileSpec(whoami(), get_str_ansi) - -def shlwapi_PathIsFileSpecW(): - shlwapi_PathIsFileSpec(whoami(), get_str_unic) - - -def shlwapi_StrToIntA(): - ret_ad = vm_pop_uint32_t() - i_str_ad = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(i_str_ad) - i_str = get_str_ansi(i_str_ad) - print repr(i_str) - try: - i = int(i_str) - except: - print 'WARNING cannot convert int' - i = 0 - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = i - vm_set_gpreg(regs) - -def shlwapi_StrToInt64Ex(funcname, get_str): - ret_ad = vm_pop_uint32_t() - pstr = vm_pop_uint32_t() - flags = vm_pop_uint32_t() - pret = vm_pop_uint32_t() - - print funcname, hex(ret_ad), hex(pstr), hex(flags), hex(pret) - i_str = get_str(pstr) - if get_str is get_str_unic: - i_str = i_str[::2] - print repr(i_str) - - if flags == 0: - r = int(i_str) - elif flags == 1: - r = int(i_str, 16) - else: - raise ValueError('cannot decode int') - - vm_set_mem(pret, struct.pack('q', r)) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - -def shlwapi_StrToInt64ExA(): - shlwapi_StrToInt64Ex(whoami(), get_str_ansi) -def shlwapi_StrToInt64ExW(): - shlwapi_StrToInt64Ex(whoami(), get_str_unic) - - - -def user32_IsCharAlpha(funcname, get_str): - ret_ad = vm_pop_uint32_t() - c = vm_pop_uint32_t() - - print funcname, hex(ret_ad), hex(c) - try: - c = chr(c) - except: - print 'bad char', c - c = "\x00" - if c.isalpha(): - ret = 1 - else: - ret = 0 - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ret - vm_set_gpreg(regs) - -def user32_IsCharAlphaA(): - user32_IsCharAlpha(whoami(), get_str_ansi) -def user32_IsCharAlphaW(): - user32_IsCharAlpha(whoami(), get_str_unic) - -def user32_IsCharAlphaNumericA(): - ret_ad = vm_pop_uint32_t() - c = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(c) - c = chr(c) - if c.isalnum(): - ret = 1 - else: - ret = 0 - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ret - vm_set_gpreg(regs) - - -def shlwapi_StrCmpNIA(): - ret_ad = vm_pop_uint32_t() - ptr_str1 = vm_pop_uint32_t() - ptr_str2 = vm_pop_uint32_t() - nchar = vm_pop_uint32_t() - print whoami(), hex(ptr_str1), hex(ptr_str2) - - s1 = get_str_ansi(ptr_str1).lower() - s2 = get_str_ansi(ptr_str2).lower() - s1 = s1[:nchar] - s2 = s2[:nchar] - - print repr(s1), repr(s2) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = cmp(s1, s2) - vm_set_gpreg(regs) - - -def advapi32_RegOpenKeyEx(funcname, get_str): - ret_ad = vm_pop_uint32_t() - hkey = vm_pop_uint32_t() - subkey = vm_pop_uint32_t() - reserved = vm_pop_uint32_t() - access = vm_pop_uint32_t() - phandle = vm_pop_uint32_t() - - print funcname, hex(hkey), hex(subkey), hex(reserved), hex(access), hex(phandle) - if subkey: - s_subkey = get_str(subkey).lower() - else: - s_subkey = "" - print repr(s_subkey) - - - ret_hkey = 0 - ret = 2 - if hkey in winobjs.hkey_handles: - if s_subkey: - if id(s_subkey) in winobjs.hkey_handles: - ret_hkey = id(s_subkey) - ret = 0 - - print 'set hkey', hex(ret_hkey) - vm_set_mem(phandle, pdw(ret_hkey)) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ret - vm_set_gpreg(regs) - -def advapi32_RegOpenKeyExA(): - advapi32_RegOpenKeyEx(whoami(), get_str_ansi) - -def advapi32_RegOpenKeyExW(): - advapi32_RegOpenKeyEx(whoami(), lambda x:get_str_unic(x)[::2]) - - -def advapi32_RegSetValue(funcname, get_str): - ret_ad = vm_pop_uint32_t() - hkey = vm_pop_uint32_t() - psubkey = vm_pop_uint32_t() - valuetype = vm_pop_uint32_t() - pvalue = vm_pop_uint32_t() - length = vm_pop_uint32_t() - - print funcname, hex(hkey), hex(psubkey), hex(valuetype), hex(pvalue), hex(length) - - if psubkey: - subkey = get_str(psubkey).lower() - else: - subkey = "" - print repr(subkey) - - if pvalue: - value = vm_get_str(pvalue, length) - else: - value = None - print repr(value) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def advapi32_RegSetValueA(): - advapi32_RegSetValue(whoami(), get_str_ansi) -def advapi32_RegSetValueW(): - advapi32_RegSetValue(whoami(), get_str_unic) - -def kernel32_GetThreadLocale(): - ret_ad = vm_pop_uint32_t() - - print whoami() - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0x40c - vm_set_gpreg(regs) - - -def kernel32_GetLocaleInfo(funcname, set_str): - ret_ad = vm_pop_uint32_t() - localeid = vm_pop_uint32_t() - lctype = vm_pop_uint32_t() - lplcdata = vm_pop_uint32_t() - cchdata = vm_pop_uint32_t() - - print funcname, hex(localeid), hex(lctype), hex(lplcdata), hex(cchdata) - - buf = None - ret = 0 - if localeid == 0x40c: - if lctype == 0x3: - buf = "ENGLISH" - buf = buf[:cchdata-1] - print 'SET', buf - vm_set_mem(lplcdata, set_str(buf)) - ret = len(buf) - else: - raise ValueError('unimpl localeid') - - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ret - vm_set_gpreg(regs) - -def kernel32_GetLocaleInfoA(): - kernel32_GetLocaleInfo(whoami(), set_str_ansi) - -def kernel32_GetLocaleInfoW(): - kernel32_GetLocaleInfo(whoami(), set_str_unic) - - - -def kernel32_TlsAlloc(): - ret_ad = vm_pop_uint32_t() - - print whoami(), hex(ret_ad) - - winobjs.tls_index += 1 - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = winobjs.tls_index - vm_set_gpreg(regs) - - -def kernel32_TlsSetValue(): - ret_ad = vm_pop_uint32_t() - tlsindex = vm_pop_uint32_t() - tlsvalue = vm_pop_uint32_t() - - print whoami(), hex(tlsindex), hex(tlsvalue) - - winobjs.tls_values[tlsindex] = tlsvalue - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - -def kernel32_TlsGetValue(): - ret_ad = vm_pop_uint32_t() - tlsindex = vm_pop_uint32_t() - - print whoami(), hex(tlsindex) - - if not tlsindex in winobjs.tls_values: - raise ValueError("unknown tls val", repr(tlsindex)) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = winobjs.tls_values[tlsindex] - vm_set_gpreg(regs) - - -def user32_GetKeyboardType(): - ret_ad = vm_pop_uint32_t() - typeflag = vm_pop_uint32_t() - - print whoami(), hex(typeflag) - - ret = 0 - if typeflag == 0: - ret = 4 - else: - raise ValueError('unimpl keyboard type') - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ret - vm_set_gpreg(regs) - -def kernel32_GetStartupInfo(funcname, set_str): - ret_ad = vm_pop_uint32_t() - ptr = vm_pop_uint32_t() - - print funcname, hex(ptr) - - - s = "\x00"*0x2c+"\x81\x00\x00\x00"+"\x0a" - - vm_set_mem(ptr, s) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ptr - vm_set_gpreg(regs) - - -def kernel32_GetStartupInfoA(): - kernel32_GetStartupInfo(whoami(), set_str_ansi) - -def kernel32_GetStartupInfoW(): - kernel32_GetStartupInfo(whoami(), set_str_unic) - -def kernel32_GetCurrentThreadId(): - ret_ad = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), '(', ')' - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0x113377 - vm_set_gpreg(regs) - - - -def kernel32_InitializeCriticalSection(): - ret_ad = vm_pop_uint32_t() - lpcritic = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(lpcritic) - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - - -def user32_GetSystemMetrics(): - ret_ad = vm_pop_uint32_t() - nindex = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(nindex) - - ret = 0 - if nindex in [0x2a, 0x4a]: - ret = 0 - else: - raise ValueError('unimpl index') - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ret - vm_set_gpreg(regs) - -def wsock32_WSAStartup(): - ret_ad = vm_pop_uint32_t() - version = vm_pop_uint32_t() - pwsadata = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(version), hex(pwsadata) - - - vm_set_mem(pwsadata, "\x01\x01\x02\x02WinSock 2.0\x00") - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 0 - vm_set_gpreg(regs) - -def kernel32_GetLocalTime(): - ret_ad = vm_pop_uint32_t() - lpsystemtime = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(lpsystemtime) - - s = struct.pack('HHHHHHHH', - 2011, # year - 10, # month - 5, # dayofweek - 7, # day - 13, # hour - 37, # minutes - 00, # seconds - 999, # millisec - ) - vm_set_mem(lpsystemtime, s) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = lpsystemtime - vm_set_gpreg(regs) - -def kernel32_GetSystemTime(): - ret_ad = vm_pop_uint32_t() - lpsystemtime = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(lpsystemtime) - - s = struct.pack('HHHHHHHH', - 2011, # year - 10, # month - 5, # dayofweek - 7, # day - 13, # hour - 37, # minutes - 00, # seconds - 999, # millisec - ) - vm_set_mem(lpsystemtime, s) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = lpsystemtime - vm_set_gpreg(regs) - -def kernel32_CreateFileMapping(funcname, get_str): - ret_ad = vm_pop_uint32_t() - hfile = vm_pop_uint32_t() - lpattr = vm_pop_uint32_t() - flprotect = vm_pop_uint32_t() - dwmaximumsizehigh = vm_pop_uint32_t() - dwmaximumsizelow = vm_pop_uint32_t() - lpname = vm_pop_uint32_t() - - print funcname, hex(ret_ad), hex(hfile), hex(lpattr), hex(flprotect), hex(dwmaximumsizehigh), hex(dwmaximumsizelow) - - if lpname: - f = get_str(lpname) - else: - f = None - print repr(f) - - - if not hfile in winobjs.handle_pool: - raise ValueError('unknown handle') - - eax = winobjs.handle_pool.add('filemapping', hfile) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = eax - vm_set_gpreg(regs) - -def kernel32_CreateFileMappingA(): - kernel32_CreateFileMapping(whoami(), get_str_ansi) - -def kernel32_CreateFileMappingW(): - kernel32_CreateFileMapping(whoami(), get_str_unic) - - - - -def kernel32_MapViewOfFile(): - ret_ad = vm_pop_uint32_t() - hfile = vm_pop_uint32_t() - flprotect = vm_pop_uint32_t() - dwfileoffsethigh = vm_pop_uint32_t() - dwfileoffsetlow = vm_pop_uint32_t() - length = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(hfile), hex(flprotect), hex(dwfileoffsethigh), hex(dwfileoffsetlow), hex(length) - - if not hfile in winobjs.handle_pool: - raise ValueError('unknown handle') - hmap = winobjs.handle_pool[hfile] - print hmap - if not hmap.info in winobjs.handle_pool: - raise ValueError('unknown file handle') - - hfile_o = winobjs.handle_pool[hmap.info] - print hfile_o - fd = hfile_o.info - fd.seek( (dwfileoffsethigh << 32) | dwfileoffsetlow) - if length: - data = fd.read(length) - else: - data = fd.read() - - print 'mapp total:', hex(len(data)) - access_dict = { 0x0: 0, - 0x1: 0, - 0x2: PAGE_READ, - 0x4: PAGE_READ | PAGE_WRITE, - 0x10: PAGE_EXEC, - 0x20: PAGE_EXEC | PAGE_READ, - 0x40: PAGE_EXEC | PAGE_READ | PAGE_WRITE, - 0x100: 0 - } - access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()]) - - - if not flprotect in access_dict: - raise ValueError( 'unknown access dw!') - - - alloc_addr = get_next_alloc_addr(len(data)) - vm_add_memory_page(alloc_addr, access_dict[flprotect], data) - - dump_memory_page_pool_py() - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = alloc_addr - vm_set_gpreg(regs) - - -def kernel32_UnmapViewOfFile(): - ret_ad = vm_pop_uint32_t() - ad = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(ad) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - - -def kernel32_GetDriveType(funcname, get_str): - ret_ad = vm_pop_uint32_t() - pathname = vm_pop_uint32_t() - - print funcname, hex(pathname) - - p = get_str(pathname) - print repr(p) - p = p.upper() - - ret = 0 - if p[0] == "C": - ret = 3 - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = ret - vm_set_gpreg(regs) - -def kernel32_GetDriveTypeA(): - kernel32_GetDriveType(whoami(), get_str_ansi) - -def kernel32_GetDriveTypeW(): - kernel32_GetDriveType(whoami(), get_str_unic) - - -def kernel32_GetDiskFreeSpace(funcname, get_str): - ret_ad = vm_pop_uint32_t() - lprootpathname = vm_pop_uint32_t() - lpsectorpercluster = vm_pop_uint32_t() - lpbytespersector = vm_pop_uint32_t() - lpnumberoffreeclusters = vm_pop_uint32_t() - lptotalnumberofclusters = vm_pop_uint32_t() - - print funcname, hex(ret_ad), hex(lprootpathname), hex(lpsectorpercluster), hex(lpbytespersector), hex(lpnumberoffreeclusters), hex(lptotalnumberofclusters) - - if lprootpathname: - rootpath = get_str(lprootpathname) - else: - rootpath = "" - print repr(rootpath) - - vm_set_mem(lpsectorpercluster, pdw(8)) - vm_set_mem(lpbytespersector, pdw(0x200)) - vm_set_mem(lpnumberoffreeclusters, pdw(0x222222)) - vm_set_mem(lptotalnumberofclusters, pdw(0x333333)) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) - -def kernel32_GetDiskFreeSpaceA(): - kernel32_GetDiskFreeSpace(whoami(), get_str_ansi) -def kernel32_GetDiskFreeSpaceW(): - kernel32_GetDiskFreeSpace(whoami(), get_str_unic) - -def kernel32_VirtualQuery(): - ret_ad = vm_pop_uint32_t() - ad = vm_pop_uint32_t() - lpbuffer = vm_pop_uint32_t() - dwl = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(ad), hex(lpbuffer), hex(dwl) - - access_dict = { 0x0: 0, - 0x1: 0, - 0x2: PAGE_READ, - 0x4: PAGE_READ | PAGE_WRITE, - 0x10: PAGE_EXEC, - 0x20: PAGE_EXEC | PAGE_READ, - 0x40: PAGE_EXEC | PAGE_READ | PAGE_WRITE, - 0x100: 0 - } - access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()]) - - - all_mem = vm_get_all_memory() - found = None - for basead, m in all_mem.items(): - if basead <= ad < basead + m['size']: - found = ad, m - break - if not found: - raise ValueError('cannot find mem', hex(ad)) - - if dwl != 0x1c: - raise ValueError('strange mem len', hex(dwl)) - s = struct.pack('IIIIIII', - ad, - basead, - access_dict_inv[m['access']], - m['size'], - 0x1000, - access_dict_inv[m['access']], - 0x01000000) - vm_set_mem(lpbuffer, s) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = dwl - vm_set_gpreg(regs) - -def kernel32_GetProcessAffinityMask(): - ret_ad = vm_pop_uint32_t() - hprocess = vm_pop_uint32_t() - procaffmask = vm_pop_uint32_t() - systemaffmask = vm_pop_uint32_t() - - print whoami(), hex(ret_ad), hex(hprocess), hex(procaffmask), hex(systemaffmask) - vm_set_mem(procaffmask, pdw(1)) - vm_set_mem(systemaffmask, pdw(1)) - - regs = vm_get_gpreg() - regs['eip'] = ret_ad - regs['eax'] = 1 - vm_set_gpreg(regs) |