about summary refs log tree commit diff stats
path: root/miasm/tools
diff options
context:
space:
mode:
Diffstat (limited to 'miasm/tools')
-rwxr-xr-xmiasm/tools/emul_helper.py16
-rw-r--r--miasm/tools/emul_lib/libcodenat.c52
-rw-r--r--miasm/tools/emul_lib/libcodenat.h34
-rw-r--r--miasm/tools/emul_lib/libcodenat_interface.c178
-rw-r--r--miasm/tools/to_c_helper.py30
5 files changed, 287 insertions, 23 deletions
diff --git a/miasm/tools/emul_helper.py b/miasm/tools/emul_helper.py
index 3b3f58c5..f89d3bf5 100755
--- a/miasm/tools/emul_helper.py
+++ b/miasm/tools/emul_helper.py
@@ -164,13 +164,6 @@ def get_instr_expr_args(name, modifs, mnemo_mode, args, my_eip):
         e = mnemo_func[name](*args)
     return e
 """
-###XXX for eval int 
-def get_instr_expr(l, my_eip, args = None):
-    if args==None:args = []
-    for x in l.arg:
-        args.append(dict_to_Expr(x, l.m.modifs, l.mnemo_mode))
-    l.arg_expr = args
-    return get_instr_expr_args(l.m.name, l.m.modifs, l.mnemo_mode, args, my_eip)
 
 
 #"""
@@ -194,11 +187,12 @@ def get_instr_expr_args(name, modifs, mnemo_mode, args, my_eip):
         e = mnemo_func[name](*args)
     return e
 #"""
+
 ###XXX for eval abs
-def get_instr_expr(l, my_eip, args = None):
+def get_instr_expr(l, my_eip, args = None, segm_to_do = {}):
     if args==None:args = []
     for x in l.arg:
-        args.append(dict_to_Expr(x, l.m.modifs, l.mnemo_mode))
+        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.m.name, l.m.modifs, l.mnemo_mode, args, my_eip)
 
@@ -625,7 +619,7 @@ def guess_func_destack(all_bloc):
     return False, a[x86_afs.imm]
 
 
-def digest_allbloc_instr(all_bloc):
+def digest_allbloc_instr(all_bloc, segm_to_do = {}):
     instrs = {}
     g = asmbloc.bloc2graph(all_bloc)
     open("graph_b.txt" , "w").write(g)
@@ -657,7 +651,7 @@ def digest_allbloc_instr(all_bloc):
                 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)
+            ex = get_instr_expr(l, ExprInt(uint32(l.offset+l.l)), args, segm_to_do = segm_to_do)
 
                 
             instrs[l.offset] = (l, ex)
diff --git a/miasm/tools/emul_lib/libcodenat.c b/miasm/tools/emul_lib/libcodenat.c
index ca9415a0..aca3a41d 100644
--- a/miasm/tools/emul_lib/libcodenat.c
+++ b/miasm/tools/emul_lib/libcodenat.c
@@ -323,24 +323,48 @@ void MEM_WRITE_08(uint64_t addr, unsigned char src)
 	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)
 {
@@ -356,6 +380,13 @@ unsigned char MEM_LOOKUP_08(uint64_t 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;
@@ -363,6 +394,13 @@ unsigned short MEM_LOOKUP_16(uint64_t 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;
@@ -370,6 +408,13 @@ unsigned int MEM_LOOKUP_32(uint64_t 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;
@@ -377,6 +422,13 @@ uint64_t MEM_LOOKUP_64(uint64_t 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;
diff --git a/miasm/tools/emul_lib/libcodenat.h b/miasm/tools/emul_lib/libcodenat.h
index 26d6b850..bb123096 100644
--- a/miasm/tools/emul_lib/libcodenat.h
+++ b/miasm/tools/emul_lib/libcodenat.h
@@ -116,7 +116,6 @@ typedef struct {
 
 	unsigned int cond;
 
-	unsigned int ds;
 	unsigned int vm_exception_flags;
 	unsigned int vm_exception_flags_new;
 	unsigned int vm_last_write_ad;
@@ -165,6 +164,21 @@ typedef struct {
 	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;
 
@@ -207,7 +221,7 @@ typedef struct {
 	uint64_t pfmem64_6;
 	uint64_t pfmem64_7;
 
-
+	uint32_t segm_base[0x10000];
 
 }vm_cpu_t;
 
@@ -270,6 +284,11 @@ 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);
@@ -277,6 +296,12 @@ 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);
@@ -340,6 +365,11 @@ typedef struct _reg_dict{
     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;
diff --git a/miasm/tools/emul_lib/libcodenat_interface.c b/miasm/tools/emul_lib/libcodenat_interface.c
index ce402e07..d43401dd 100644
--- a/miasm/tools/emul_lib/libcodenat_interface.c
+++ b/miasm/tools/emul_lib/libcodenat_interface.c
@@ -208,6 +208,105 @@ PyObject* _vm_set_gpreg(PyObject *dict)
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+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();
@@ -724,7 +823,24 @@ PyObject* vm_set_gpreg(PyObject *self, PyObject *args)
 	_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)
@@ -933,6 +1049,60 @@ unsigned int get_memory_page_from_min_ad_py(unsigned int size)
 }
 
 
+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;
@@ -1082,6 +1252,10 @@ static PyMethodDef CodenatMethods[] = {
      "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,
@@ -1136,6 +1310,10 @@ static PyMethodDef CodenatMethods[] = {
      "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"},
 
     {NULL, NULL, 0, NULL}        /* Sentinel */
 
diff --git a/miasm/tools/to_c_helper.py b/miasm/tools/to_c_helper.py
index 601d7feb..f82b83ca 100644
--- a/miasm/tools/to_c_helper.py
+++ b/miasm/tools/to_c_helper.py
@@ -138,6 +138,15 @@ my_C_id = [
     #vm_last_write_size,
     tsc1,
     tsc2,
+
+
+    es ,
+    cs ,
+    ss ,
+    ds ,
+    fs ,
+    gs ,
+
     float_st0,
     float_st1,
     float_st2,
@@ -390,8 +399,8 @@ def Exp2C(exprs, l = None, addr2label = None, gen_exception_code = False):
     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):
-    all_instrs = digest_allbloc_instr(all_bloc)
+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 = {}):
+    all_instrs = digest_allbloc_instr(all_bloc, segm_to_do)
 
     if not addr2label:
         addr2label = lambda x:"loc_%.16X"%(x&mask_int)
@@ -487,19 +496,20 @@ 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):
+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 = {}):
     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)
+    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
@@ -707,7 +717,7 @@ def asm2C(f_name, known_mems, dyn_func, in_str, x86_mn, symbol_pool, func_to_dis
     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 = [], **kargs):
+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 = {}, **kargs):
     if job_done == None:
         job_done = set()
 
@@ -720,7 +730,7 @@ def gen_C_from_asmbloc(in_str, offset, symbol_pool, dont_dis = [], job_done = No
                      **kargs)
     f_dec, out = bloc_gen_C_func([cur_bloc], f_name, None, True,
                                  log_mn, log_reg, log_lbl,
-                                 filtered_ad, tick_dbg)
+                                 filtered_ad, tick_dbg, segm_to_do)
     #print "\n".join(out)
     return f_name, f_dec, out, cur_bloc
 
@@ -997,10 +1007,10 @@ def updt_bloc_emul(known_blocs, in_str, my_eip, symbol_pool, code_blocs_mem_rang
 '''    
 
 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, **kargs):
+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 = {}, **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, **kargs)
+    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)