about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm/tools/codenat.py24
-rw-r--r--miasm/tools/emul_lib/libcodenat.c90
-rw-r--r--miasm/tools/emul_lib/libcodenat.h36
-rw-r--r--miasm/tools/emul_lib/libcodenat_interface.c117
-rw-r--r--miasm/tools/to_c_helper.py1
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))