diff options
Diffstat (limited to 'miasm/tools')
| -rwxr-xr-x | miasm/tools/emul_helper.py | 16 | ||||
| -rw-r--r-- | miasm/tools/emul_lib/libcodenat.c | 52 | ||||
| -rw-r--r-- | miasm/tools/emul_lib/libcodenat.h | 34 | ||||
| -rw-r--r-- | miasm/tools/emul_lib/libcodenat_interface.c | 178 | ||||
| -rw-r--r-- | miasm/tools/to_c_helper.py | 30 |
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) |