diff options
| -rw-r--r-- | miasm/tools/codenat.py | 24 | ||||
| -rw-r--r-- | miasm/tools/emul_lib/libcodenat.c | 90 | ||||
| -rw-r--r-- | miasm/tools/emul_lib/libcodenat.h | 36 | ||||
| -rw-r--r-- | miasm/tools/emul_lib/libcodenat_interface.c | 117 | ||||
| -rw-r--r-- | miasm/tools/to_c_helper.py | 1 |
5 files changed, 249 insertions, 19 deletions
diff --git a/miasm/tools/codenat.py b/miasm/tools/codenat.py index f1758752..6eebeef3 100644 --- a/miasm/tools/codenat.py +++ b/miasm/tools/codenat.py @@ -23,18 +23,23 @@ 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<<2) -EXCEPT_THROW_SEH = (1<<3) -EXCEPT_UNK_EIP = (1<<4) -EXCEPT_ACCESS_VIOL = (1<<5) -EXCEPT_INT_DIV_BY_ZERO = (1<<6) -EXCEPT_PRIV_INSN = (1<<7) -EXCEPT_ILLEGAL_INSN = (1<<8) +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) + @@ -46,10 +51,15 @@ 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: diff --git a/miasm/tools/emul_lib/libcodenat.c b/miasm/tools/emul_lib/libcodenat.c index ff6ab751..31a2be31 100644 --- a/miasm/tools/emul_lib/libcodenat.c +++ b/miasm/tools/emul_lib/libcodenat.c @@ -36,6 +36,8 @@ 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**************/ @@ -142,6 +144,7 @@ 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); @@ -153,6 +156,16 @@ static inline uint64_t memory_page_read(unsigned int my_size, uint64_t 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 */ @@ -220,6 +233,7 @@ static inline void memory_page_write(unsigned int my_size, { struct memory_page_node * mpn; unsigned char * addr; + struct memory_breakpoint_info * b; mpn = get_memory_page_from_address(ad); if (!mpn) @@ -231,6 +245,14 @@ static inline void memory_page_write(unsigned int my_size, 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 */ @@ -874,13 +896,17 @@ unsigned int cpuid(unsigned int a, unsigned int reg_num) else if (a == 1){ switch(reg_num){ case 0: - return 0x000006FB; + //return 0x000006FB; + return 0x00020652; case 1: - return 0x02040800; + //return 0x02040800; + return 0x00000800; case 2: - return 0x0004E3BD; + //return 0x0004E3BD; + return 0x00000209; case 3: - return 0xBFEBFBFF; + //return 0xBFEBFBFF; + return 0x078bf9ff; } } else{ @@ -1196,6 +1222,10 @@ void init_code_bloc_pool(void) code_bloc_pool_ad_max = 0; } +void init_memory_breakpoint(void) +{ + LIST_INIT(&memory_breakpoint_pool); +} void reset_memory_page_pool(void) @@ -1229,6 +1259,20 @@ void reset_code_bloc_pool(void) 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; @@ -1297,6 +1341,44 @@ void dump_memory_page_pool() } } +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); + } + +} diff --git a/miasm/tools/emul_lib/libcodenat.h b/miasm/tools/emul_lib/libcodenat.h index 026236cb..43d247e8 100644 --- a/miasm/tools/emul_lib/libcodenat.h +++ b/miasm/tools/emul_lib/libcodenat.h @@ -53,6 +53,12 @@ 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; @@ -259,6 +265,13 @@ struct code_bloc_node { }; +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 @@ -272,16 +285,17 @@ struct code_bloc_node { #define EXCEPT_CODE_AUTOMOD (1<<0) #define EXCEPT_SOFT_BP (1<<1) -#define EXCEPT_NUM_UDPT_EIP (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<<2) -#define EXCEPT_THROW_SEH (1<<3) -#define EXCEPT_UNK_EIP (1<<4) -#define EXCEPT_ACCESS_VIOL (1<<5) -#define EXCEPT_INT_DIV_BY_ZERO (1<<6) -#define EXCEPT_PRIV_INSN (1<<7) -#define EXCEPT_ILLEGAL_INSN (1<<8) +#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); @@ -407,10 +421,16 @@ 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); diff --git a/miasm/tools/emul_lib/libcodenat_interface.c b/miasm/tools/emul_lib/libcodenat_interface.c index 565bf8c9..e0307d37 100644 --- a/miasm/tools/emul_lib/libcodenat_interface.c +++ b/miasm/tools/emul_lib/libcodenat_interface.c @@ -803,6 +803,67 @@ PyObject* _vm_get_str(PyObject *addr, PyObject *item_len) 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(); @@ -982,6 +1043,23 @@ PyObject* init_code_bloc_pool_py(PyObject* self, PyObject* args) } +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; @@ -994,6 +1072,28 @@ PyObject* vm_add_memory_page(PyObject* self, PyObject* args) 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) @@ -1003,6 +1103,13 @@ PyObject* dump_memory_page_pool_py(PyObject* self, PyObject* args) 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; @@ -1377,6 +1484,8 @@ static PyMethodDef CodenatMethods[] = { {"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, @@ -1393,14 +1502,22 @@ static PyMethodDef CodenatMethods[] = { "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, diff --git a/miasm/tools/to_c_helper.py b/miasm/tools/to_c_helper.py index 9b764e15..b24a1754 100644 --- a/miasm/tools/to_c_helper.py +++ b/miasm/tools/to_c_helper.py @@ -1144,6 +1144,7 @@ def load_pe_in_vm(fname_in, options, all_imp_dll = None, **kargs): 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)) |