about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorserpilliere <devnull@localhost>2011-08-09 15:13:55 +0200
committerserpilliere <devnull@localhost>2011-08-09 15:13:55 +0200
commitaba3f7b9b637ebb1ce0463053e9185d6c0fca1fc (patch)
treeeb033395f1914e2b982aba4ad233a52b7b3b2dcd
parent9aa45f265e33cb7397c78470b7d1680f192c92df (diff)
downloadmiasm-aba3f7b9b637ebb1ce0463053e9185d6c0fca1fc.tar.gz
miasm-aba3f7b9b637ebb1ce0463053e9185d6c0fca1fc.zip
fix emulation on 64 bit
-rw-r--r--example/unpack_upx.py2
-rw-r--r--miasm/core/asmbloc.py19
-rw-r--r--miasm/expression/expression.py9
-rw-r--r--miasm/tools/codenat.py4
-rw-r--r--miasm/tools/emul_lib/libcodenat_interface.c21
-rw-r--r--miasm/tools/emul_lib/libcodenat_tcc.c12
-rw-r--r--miasm/tools/to_c_helper.py42
-rw-r--r--miasm/tools/win_api.py2
8 files changed, 69 insertions, 42 deletions
diff --git a/example/unpack_upx.py b/example/unpack_upx.py
index 890f7fc2..f3d941b5 100644
--- a/example/unpack_upx.py
+++ b/example/unpack_upx.py
@@ -254,7 +254,7 @@ print "base imp", hex(offset_imp)
 print 'decomp_buf_ad_out', hex(decomp_buf_ad_out)

 new_dll = []

 

-offset_imp = offset_imp - decomp_buf_ad_out - struct.unpack('L', e.virt[ad_tmp:ad_tmp+4])[0]

+offset_imp = offset_imp - decomp_buf_ad_out - struct.unpack('I', e.virt[ad_tmp:ad_tmp+4])[0]

 print "read ofset imp", hex(offset_imp)

 

 #XXXXX 

diff --git a/miasm/core/asmbloc.py b/miasm/core/asmbloc.py
index 7b92fdb6..bdbd2f8e 100644
--- a/miasm/core/asmbloc.py
+++ b/miasm/core/asmbloc.py
@@ -38,14 +38,20 @@ tab_int_size = {int8:8,
                 }
 
 
+def is_int(a):
+    t = [int, long,
+         int8, int16, int32, int64,
+         uint8, uint16, uint32, uint64]
+    return any([isinstance(a, x) for x in t])
+
 class asm_label:
     def __init__(self, name = "", offset = None):
 
         self.next = "next"
         self.noattrib = "noattrib"
         self.fixedblocs = False
-        if type(name) in [int, long]+tab_int_size.keys():
-            name = "loc_%.8X"%int(name)
+        if is_int(name):
+            name = "loc_%.16X"%(int(name)&0xFFFFFFFFFFFFFFFF)
         self.name = name
         self.attrib = self.noattrib
         if offset == None:
@@ -259,7 +265,6 @@ def dis_bloc(mnemo, pool_bin, cur_bloc, offset, job_done, symbol_pool, dont_dis
         if not instr.breakflow():
             continue
 
-        
         if instr.splitflow() and not (instr.is_subcall() and dontdis_retcall):
             n = instr.getnextflow()
             l = symbol_pool.getby_offset_create(n)
@@ -270,7 +275,7 @@ def dis_bloc(mnemo, pool_bin, cur_bloc, offset, job_done, symbol_pool, dont_dis
             dst = instr.getdstflow()
             dstn = []
             for d in dst:
-                if type(d) in [int, long]+tab_int_size.keys():
+                if is_int(d):
                     d = symbol_pool.getby_offset_create(d)
                 dstn.append(d)
             dst = dstn
@@ -450,7 +455,7 @@ def group_blocs(all_bloc):
     for l in groups_bloc:
         l.total_max_l = reduce(lambda x,y: x+y.blen_max, groups_bloc[l], 0)
         log_asmbloc.debug(("offset totalmax l", l.offset, l.total_max_l))
-        if type(l.offset) in [int, long]+tab_int_size.keys():
+        if is_int(l.offset):
             hof = hex(int(l.offset))
         else:
             hof = l.name
@@ -515,7 +520,7 @@ def gen_non_free_mapping(group_bloc, dont_erase = []):
         #if a label in the group is fixed
         diff_offset = 0
         for b in group_bloc[g]:
-            if not type(b.label.offset) in [int, long]+tab_int_size.keys():
+            if not is_int(b.label.offset):
                 diff_offset+=b.blen_max
                 continue
             g.fixedblocs = True
@@ -766,7 +771,7 @@ def calc_symbol_offset(symbol_pool):
     s_dependent = {}
 
     for l in symbol_pool.s:
-        if not type(symbol_pool.s[l].offset_g) in [int, long]+tab_int_size.keys():
+        if not is_int(symbol_pool.s[l].offset_g):
             s_to_fix.add(l)
 
             if not l in symbol_pool.s or symbol_pool.s[l].offset_g == None:
diff --git a/miasm/expression/expression.py b/miasm/expression/expression.py
index 4e4563c7..e472fb48 100644
--- a/miasm/expression/expression.py
+++ b/miasm/expression/expression.py
@@ -46,6 +46,12 @@ tab_int_size = {int8:8,
 my_size_mask = {1:1, 8:0xFF, 16:0xFFFF, 32:0xFFFFFFFF,  64:0xFFFFFFFFFFFFFFFFL}
 
 
+def is_int(a):
+    t = [int8, int16, int32, int64,
+         uint8, uint16, uint32, uint64]
+    return any([isinstance(a, x) for x in t])
+
+
 
 def get_missing_interval(all_intervals, i_min = 0, i_max = 32):
     my_intervals = all_intervals[:]
@@ -136,7 +142,7 @@ class ExprTop(Expr):
 
 class ExprInt(Expr):
     def __init__(self, arg):
-        if not type(arg) in tab_int_size:
+        if not is_int(arg):
             raise 'arg must by numpy int! %s'%str(arg)
         self.arg = arg
     def __str__(self):
@@ -370,6 +376,7 @@ class ExprMem(Expr):
 
     def toC(self):
         return "MEM_LOOKUP_%.2d(%s)"%(self.size, self.arg.toC())
+        
 
     
 class ExprOp(Expr):
diff --git a/miasm/tools/codenat.py b/miasm/tools/codenat.py
index 6711f802..a601ffae 100644
--- a/miasm/tools/codenat.py
+++ b/miasm/tools/codenat.py
@@ -131,7 +131,7 @@ def codenat_tcc_load():
     print libpath
     print libdir
     libcntcc.tcc_set_emul_lib_path(libdir, libpath, get_python_inc())
-    
+
 def codenat_tcc_init():
     global libcntcc
     if libcntcc == None:
@@ -156,5 +156,5 @@ class tcc_code():
         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)    
+    mcode = codenat_tcc_compil(f_name, c_source)
     return tcc_code(mcode)
diff --git a/miasm/tools/emul_lib/libcodenat_interface.c b/miasm/tools/emul_lib/libcodenat_interface.c
index 17910a09..5482d931 100644
--- a/miasm/tools/emul_lib/libcodenat_interface.c
+++ b/miasm/tools/emul_lib/libcodenat_interface.c
@@ -786,7 +786,7 @@ PyObject* _vm_exec_blocs(PyObject* self, PyObject* args)
 	PyObject* module;
 	PyObject* func;
 	PyObject* meip;
-	unsigned int tmp;
+	unsigned long tmp;
 
 	PyObject* my_eip;
 	PyObject* known_blocs;
@@ -799,25 +799,30 @@ PyObject* _vm_exec_blocs(PyObject* self, PyObject* args)
 		RAISE(PyExc_TypeError, "arg must be dict");
 
 	if (PyInt_Check(my_eip)){
-		tmp = (unsigned int)PyInt_AsLong(my_eip);
+		tmp = (unsigned long)PyInt_AsLong(my_eip);
 	}
 	else if (PyLong_Check(my_eip)){
-		tmp = (unsigned int)PyInt_AsUnsignedLongLongMask(my_eip);
+		tmp = (unsigned long)PyInt_AsUnsignedLongLongMask(my_eip);
 	}
 	else{
 		RAISE(PyExc_TypeError,"arg1 must be int");
 	}
-	meip = PyInt_FromLong((long)tmp);
+	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)
-			return meip;
+		if (module == NULL){
+			printf("assert eip module_c in pyobject\n");
+			exit(0);
+		}
 		func = PyObject_GetAttrString(module, "func");
-		if (func == NULL)
-			return meip;
+		if (func == NULL){
+			printf("assert func module_c in pyobject\n");
+			exit(0);
+		}
 
 		Py_DECREF(module);
 		if (!PyCallable_Check (func)) {
diff --git a/miasm/tools/emul_lib/libcodenat_tcc.c b/miasm/tools/emul_lib/libcodenat_tcc.c
index 60f00566..371db4a8 100644
--- a/miasm/tools/emul_lib/libcodenat_tcc.c
+++ b/miasm/tools/emul_lib/libcodenat_tcc.c
@@ -17,6 +17,7 @@
 */
 #include <Python.h>
 
+#include <inttypes.h>
 #include <libtcc.h>
 
 
@@ -55,7 +56,6 @@ void tcc_init_state(void)
 	tcc_set_output_type(tcc_state, TCC_OUTPUT_MEMORY);
 
 	tcc_add_include_path(tcc_state, emul_libpython_dir);
-	tcc_add_include_path(tcc_state, emul_lib_dir);
 	tcc_add_file(tcc_state, emul_lib_path);
 }
 
@@ -64,13 +64,13 @@ void tcc_init_state(void)
 
 PyObject*  tcc_exec_bloc(PyObject* self, PyObject* args)
 {
-	int (*func)(void);
+	uint64_t (*func)(void);
 
 	unsigned long ret;
 	if (!PyArg_ParseTuple(args, "i", &func))
 		return NULL;
 	ret = func();
-	return PyInt_FromLong((long)ret);
+	return PyLong_FromUnsignedLong(ret);
 }
 
 PyObject* tcc_compil(PyObject* self, PyObject* args)
@@ -85,12 +85,18 @@ PyObject* tcc_compil(PyObject* self, PyObject* args)
 	tcc_init_state();
 	if (tcc_compile_string(tcc_state, func_code) != 0) {
 		printf("Erreur de compilation !\n");
+		printf("%s\n", func_code);
 		exit(0);
 	}
 	/* XXX use tinycc devel with -fPIC patch in makefile */
 	if (tcc_relocate(tcc_state) < 0)
 		exit(0);
 	entry = tcc_get_symbol(tcc_state, func_name);
+	if (!entry){
+		printf("Erreur de symbole !\n");
+		printf("%s\n", func_name);
+		exit(0);
+	}
 
 	return PyInt_FromLong((long)entry);
 
diff --git a/miasm/tools/to_c_helper.py b/miasm/tools/to_c_helper.py
index d5573f40..be19ee8c 100644
--- a/miasm/tools/to_c_helper.py
+++ b/miasm/tools/to_c_helper.py
@@ -35,7 +35,7 @@ import ctypes
 def id2new(i):
     return str(i)+'_new'
 
-
+mask_int = 0xffffffffffffffff
 
 
 my_C_id = [
@@ -134,18 +134,19 @@ def patch_c_id(e):
 code_deal_exception_at_instr = r"""
 if (vmcpu.vm_exception_flags > EXCEPT_NUM_UDPT_EIP) {
     %s = 0x%X; 
-    return (unsigned int)vmcpu.eip; 
+    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 (unsigned int)vmcpu.eip; 
+    return vmcpu.eip; 
 }
 """
 
     
 def Exp2C(exprs, l = None, addr2label = None, gen_exception_code = False):
+    my_size_mask = {1:1, 8:0xFF, 16:0xFFFF, 32:0xFFFFFFFF,  64:0xFFFFFFFFFFFFFFFFL}
     if not addr2label:
         addr2label = lambda x:x
     id_to_update = []
@@ -204,7 +205,8 @@ def Exp2C(exprs, l = None, addr2label = None, gen_exception_code = False):
             if isinstance(dst, ExprId):
                 id_to_update.append(dst)
                 str_dst = id2new(patch_c_id(dst))
-                out.append('%s = %s;'%(str_dst, str_src))
+                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))
@@ -225,7 +227,7 @@ def Exp2C(exprs, l = None, addr2label = None, gen_exception_code = False):
                     if l.is_subcall():
                         out_eip.append("GOTO_STATIC_SUB(%s);"%(addr2label(e.src.arg)))
                     else:
-                        out_eip.append("GOTO_STATIC(0x%.8X);"%(e.src.arg))
+                        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()))
@@ -239,10 +241,11 @@ def Exp2C(exprs, l = None, addr2label = None, gen_exception_code = False):
     out+=out_mem
 
     if gen_exception_code:
-        out.append(code_deal_exception_at_instr % (patch_c_id(eip), l.offset))
+        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))))
+                            
 
 
 
@@ -252,9 +255,9 @@ def Exp2C(exprs, l = None, addr2label = None, gen_exception_code = False):
     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 (unsigned int)vmcpu.eip; }"%(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, l.offset + l.l))
+            post_instr.append(code_deal_exception_post_instr % (patch_c_id(eip), (l.offset&mask_int), (l.offset + l.l)&mask_int))
     
     """
     print "1"
@@ -275,7 +278,7 @@ def bloc2C(all_bloc, addr2label = None, gen_exception_code = False, dbg_instr =
     all_instrs = digest_allbloc_instr(all_bloc)
 
     if not addr2label:
-        addr2label = lambda x:"loc_%.8X"%x
+        addr2label = lambda x:"loc_%.16X"%(x&mask_int)
 
 
     out = []
@@ -297,7 +300,7 @@ def bloc2C(all_bloc, addr2label = None, gen_exception_code = False, dbg_instr =
             if addr2label:
                 out.append("%s:"%addr2label(l.offset))
             else:
-                out.append("loc_%.8X:"%l.offset)
+                out.append("loc_%.16X:"%(l.offset&mask_int))
                 
             o, post_instr = Exp2C(ex, l, addr2label, gen_exception_code)
             
@@ -314,7 +317,7 @@ def bloc2C(all_bloc, addr2label = None, gen_exception_code = False, dbg_instr =
                 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, l.offset))
+                my_o.append(code_deal_exception_post_instr % (patch_c_id(eip), (l.offset&mask_int), (l.offset&mask_int)))
 
 
                 #my_o.append(r'printf("ecx %.8X\n", ecx );')            
@@ -352,7 +355,7 @@ def bloc2C(all_bloc, addr2label = None, gen_exception_code = False, dbg_instr =
         
         for c in b.bto:
             if c.c_t == asmbloc.asm_constraint.c_next:
-                out.append("GOTO_STATIC(0x%.8X);"%(c.label.offset))
+                out.append("GOTO_STATIC(0x%.16X);"%(c.label.offset&mask_int))
         
         """
         #in case of bad disasm, no next, so default next instr
@@ -369,7 +372,7 @@ def bloc2C(all_bloc, addr2label = None, gen_exception_code = False, dbg_instr =
 
 
 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):
-    f_dec = 'unsigned int %s(void)'%funcname
+    f_dec = 'uint64_t %s(void)'%funcname
     out = []
     out+=[f_dec,
           '{',
@@ -566,7 +569,7 @@ def asm2C(f_name, known_mems, dyn_func, in_str, x86_mn, symbol_pool, func_to_dis
 
 
     for f, f_code in dyn_func.items():
-        l_name = "loc_%.8X"%f
+        l_name = "loc_%.16X"%(f&mask_int)
         funcs_code[-1:-1] = [l_name+":"]
         funcs_code[-1:-1] = f_code.split('\n')
         l = asmbloc.asm_label(l_name, f)
@@ -592,7 +595,7 @@ def gen_C_from_asmbloc(in_str, offset, symbol_pool, dont_dis = [], job_done = No
     if job_done == None:
         job_done = set()
 
-    f_name = "bloc_%.8X"%offset
+    f_name = "bloc_%.16X"%(offset&mask_int)
     l = symbol_pool.getby_offset_create(offset)
     cur_bloc = asmbloc.asm_bloc(l)
         
@@ -601,7 +604,7 @@ def gen_C_from_asmbloc(in_str, offset, symbol_pool, dont_dis = [], job_done = No
 
     f_dec, out = bloc_gen_C_func([cur_bloc], f_name, None, True, log_mn, log_reg, log_lbl, filtered_ad, tick_dbg)
     #print "\n".join(out)
-    return f_dec, out, cur_bloc
+    return f_name, f_dec, out, cur_bloc
 
     
     
@@ -614,7 +617,7 @@ def dispatch_table_from_f_blocs(all_f_b):
     for b in all_f_b:
         dispatch_table[b.label.offset] = b.label.name
         for l in b.lines:
-            dispatch_table[l.offset] = "loc_%.8X"%l.offset
+            dispatch_table[l.offset] = "loc_%.16X"%(l.offset&mask_int)
 
     return dispatch_table
 
@@ -882,7 +885,7 @@ 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):
     if job_done == None:
         job_done = set()
-    f_dec, funcs_code, cur_bloc = gen_C_from_asmbloc(in_str, my_eip, symbol_pool, dont_dis, job_done, log_mn, log_regs)
+    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)
 
     dyn_dispatcher = """
     #define GOTO_DYNAMIC do {return %s;} while(0)
@@ -896,8 +899,7 @@ def updt_bloc_emul(known_blocs, in_str, my_eip, symbol_pool, code_blocs_mem_rang
     c_source = "#include <Python.h>\n"+c_source
     #c_source = '#include "emul_lib/libcodenat.h"\n'+c_source
     #print c_source
-
-    a = gen_C_module_tcc(f_dec[13:-6], c_source)
+    a = gen_C_module_tcc(fname, c_source)
     bn = bloc_nat(my_eip, cur_bloc, a, log_mn, log_regs)
 
     bn.c_source = c_source
diff --git a/miasm/tools/win_api.py b/miasm/tools/win_api.py
index 13ec5934..1169bb7c 100644
--- a/miasm/tools/win_api.py
+++ b/miasm/tools/win_api.py
@@ -642,6 +642,8 @@ def kernel32_VirtualProtect():
                        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
                        }