diff options
28 files changed, 1103 insertions, 1154 deletions
diff --git a/example/samples/x86_32_automod.S b/example/samples/x86_32_automod.S new file mode 100644 index 00000000..ea61a772 --- /dev/null +++ b/example/samples/x86_32_automod.S @@ -0,0 +1,40 @@ +main: + XOR EDX, EDX + JZ lbl_start + +lbl_start: + INC EDX + INC EDX + INC EDX + JZ dum + + INC EDX + INC EDX + INC EDX + JZ dum + + INC EDX + INC EDX + INC EDX + JZ dum + +lbl_stop: + + MOV ESI, exit_code + MOV EDI, lbl_start + MOV AL, 0x90 + MOV ECX, 24 + REPE MOVSB + JMP lbl_start + +exit_code: + MOV EAX, 0x11223344 + MOV EAX, 0x11223344 + MOV EAX, 0x11223344 + CMP EDX, 0x12 + JZ dum + RET + +dum: + INT 0x3 + RET diff --git a/miasm2/analysis/debugging.py b/miasm2/analysis/debugging.py index 57f30181..4e6982b3 100644 --- a/miasm2/analysis/debugging.py +++ b/miasm2/analysis/debugging.py @@ -1,5 +1,6 @@ import cmd from miasm2.core.utils import hexdump +from miasm2.core.interval import interval import miasm2.jitter.csts as csts from miasm2.jitter.jitload import ExceptionHandle @@ -152,7 +153,8 @@ class Debugguer(object): "Step in jit" self.myjit.jit.set_options(jit_maxline=1) - self.myjit.jit.updt_automod_code(self.myjit.vm, self.myjit.pc, 8) + self.myjit.jit.addr_mod = interval([(self.myjit.pc, self.myjit.pc)]) + self.myjit.jit.updt_automod_code(self.myjit.vm) res = self.myjit.continue_run(step=True) self.handle_exception(res) diff --git a/miasm2/ir/ir2C.py b/miasm2/ir/ir2C.py index 4c9dff8c..6cf3b4e6 100644 --- a/miasm2/ir/ir2C.py +++ b/miasm2/ir/ir2C.py @@ -28,12 +28,12 @@ for size in [8, 16, 32, 64]: def init_arch_C(arch): arch.id2Cid = {} for x in arch.regs.all_regs_ids + prefetch_id: - arch.id2Cid[x] = m2_expr.ExprId('vmcpu->' + str(x), x.size) + arch.id2Cid[x] = m2_expr.ExprId('((vm_cpu_t*)jitcpu->cpu)->' + str(x), x.size) arch.id2newCid = {} for x in arch.regs.all_regs_ids + prefetch_id: - arch.id2newCid[x] = m2_expr.ExprId('vmcpu->%s_new' % x, x.size) + arch.id2newCid[x] = m2_expr.ExprId('((vm_cpu_t*)jitcpu->cpu)->%s_new' % x, x.size) def patch_c_id(arch, e): @@ -49,7 +49,7 @@ mask_int = 0xffffffffffffffff pre_instr_test_exception = r""" // pre instruction test exception -if (vm_mngr->exception_flags) { +if (VM_exception_flag) { %s; return; } @@ -58,14 +58,14 @@ if (vm_mngr->exception_flags) { code_exception_fetch_mem_at_instr = r""" // except fetch mem at instr -if (vm_mngr->exception_flags & EXCEPT_DO_NOT_UPDATE_PC) { +if (VM_exception_flag & EXCEPT_DO_NOT_UPDATE_PC) { %s; return; } """ code_exception_fetch_mem_post_instr = r""" // except fetch mem post instr -if (vm_mngr->exception_flags) { +if (VM_exception_flag) { %s; return; } @@ -74,14 +74,14 @@ if (vm_mngr->exception_flags) { code_exception_fetch_mem_at_instr_noautomod = r""" // except fetch mem at instr noauto -if ((vm_mngr->exception_flags & ~EXCEPT_CODE_AUTOMOD) & EXCEPT_DO_NOT_UPDATE_PC) { +if ((VM_exception_flag & ~EXCEPT_CODE_AUTOMOD) & EXCEPT_DO_NOT_UPDATE_PC) { %s; return; } """ code_exception_fetch_mem_post_instr_noautomod = r""" // except post instr noauto -if (vm_mngr->exception_flags & ~EXCEPT_CODE_AUTOMOD) { +if (VM_exception_flag & ~EXCEPT_CODE_AUTOMOD) { %s; return; } @@ -90,7 +90,7 @@ if (vm_mngr->exception_flags & ~EXCEPT_CODE_AUTOMOD) { code_exception_at_instr = r""" // except at instr -if (vmcpu->exception_flags && vmcpu->exception_flags > EXCEPT_NUM_UPDT_EIP) { +if (CPU_exception_flag && CPU_exception_flag > EXCEPT_NUM_UPDT_EIP) { %s; return; } @@ -98,8 +98,8 @@ if (vmcpu->exception_flags && vmcpu->exception_flags > EXCEPT_NUM_UPDT_EIP) { code_exception_post_instr = r""" // except post instr -if (vmcpu->exception_flags) { - if (vmcpu->exception_flags > EXCEPT_NUM_UPDT_EIP) { +if (CPU_exception_flag) { + if (CPU_exception_flag > EXCEPT_NUM_UPDT_EIP) { %s; } else { @@ -111,15 +111,15 @@ if (vmcpu->exception_flags) { code_exception_at_instr_noautomod = r""" -if ((vmcpu->exception_flags & ~EXCEPT_CODE_AUTOMOD) && vmcpu->exception_flags > EXCEPT_NUM_UPDT_EIP) { +if ((CPU_exception_flag & ~EXCEPT_CODE_AUTOMOD) && (CPU_exception_flag > EXCEPT_NUM_UPDT_EIP)) { %s; return; } """ code_exception_post_instr_noautomod = r""" -if (vmcpu->exception_flags & ~EXCEPT_CODE_AUTOMOD) { - if (vmcpu->exception_flags > EXCEPT_NUM_UPDT_EIP) { +if (CPU_exception_flag & ~EXCEPT_CODE_AUTOMOD) { + if (CPU_exception_flag > EXCEPT_NUM_UPDT_EIP) { %s; } else { @@ -326,7 +326,7 @@ def Expr2C(ir_arch, l, exprs, gen_exception_code=False): if gen_exception_code: if set_exception_flags: if pc_is_dst: - post_instr.append("if (vm_mngr->exception_flags) { " + + post_instr.append("if (VM_exception_flag) { " + "/*pc = 0x%X; */return; }" % (l.offset)) else: e = set_pc(ir_arch, l.offset & mask_int) @@ -391,7 +391,7 @@ def ir2C(ir_arch, irbloc, lbl_done, lbl_done.add(l.offset) if log_regs: - out.append([r'dump_gpregs(vmcpu);']) + out.append([r'dump_gpregs(jitcpu->cpu);']) if log_mn: out.append(['printf("%.8X %s\\n");' % (l.offset, str(l))]) diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py index 8ec4af7a..4018454b 100644 --- a/miasm2/ir/translators/C.py +++ b/miasm2/ir/translators/C.py @@ -45,8 +45,8 @@ class TranslatorC(Translator): (expr.cond, expr.src1, expr.src2))) def from_ExprMem(self, expr): - return "MEM_LOOKUP_%.2d(vm_mngr, %s)" % (expr.size, - self.from_expr(expr.arg)) + return "MEM_LOOKUP_%.2d(jitcpu, %s)" % (expr.size, + self.from_expr(expr.arg)) def from_ExprOp(self, expr): if len(expr.args) == 1: @@ -106,13 +106,13 @@ class TranslatorC(Translator): return "%s(%s, %s)" % (expr.op, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif expr.op == "segm": - return "segm2addr(vmcpu, %s, %s)" % ( + return "segm2addr(jitcpu, %s, %s)" % ( self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif expr.op in ['udiv', 'umod', 'idiv', 'imod']: - return '%s%d(vmcpu, %s, %s)' % (expr.op, - expr.args[0].size, - self.from_expr(expr.args[0]), - self.from_expr(expr.args[1])) + return '%s%d(jitcpu, %s, %s)' % (expr.op, + expr.args[0].size, + self.from_expr(expr.args[0]), + self.from_expr(expr.args[1])) elif expr.op in ["bcdadd", "bcdadd_cf"]: return "%s_%d(%s, %s)" % (expr.op, expr.args[0].size, self.from_expr(expr.args[0]), diff --git a/miasm2/jitter/JitCore.c b/miasm2/jitter/JitCore.c new file mode 100644 index 00000000..25134869 --- /dev/null +++ b/miasm2/jitter/JitCore.c @@ -0,0 +1,126 @@ +#include <Python.h> +#include "structmember.h" +#include <stdint.h> +#include <inttypes.h> +#include "queue.h" +#include "vm_mngr.h" +#include "vm_mngr_py.h" +#include "JitCore.h" + + +void JitCpu_dealloc(JitCpu* self) +{ + self->ob_type->tp_free((PyObject*)self); +} + + +PyObject * JitCpu_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + JitCpu *self; + + self = (JitCpu *)type->tp_alloc(type, 0); + return (PyObject *)self; +} + +PyObject * JitCpu_get_vmmngr(JitCpu *self, void *closure) +{ + return self->pyvm; +} + +PyObject * JitCpu_set_vmmngr(JitCpu *self, PyObject *value, void *closure) +{ + self->pyvm = value; + return 0; +} + +PyObject * JitCpu_get_jitter(JitCpu *self, void *closure) +{ + return self->jitter; +} + +PyObject * JitCpu_set_jitter(JitCpu *self, PyObject *value, void *closure) +{ + self->jitter = value; + return 0; +} + + +void Resolve_dst(block_id* b, uint64_t addr, uint64_t is_local) +{ + b->address = addr; + b->is_local = is_local; +} + + + + +uint8_t __attribute__((weak)) MEM_LOOKUP_08(JitCpu* jitcpu, uint64_t addr) +{ + return vm_MEM_LOOKUP_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr); +} + +uint16_t __attribute__((weak)) MEM_LOOKUP_16(JitCpu* jitcpu, uint64_t addr) +{ + return vm_MEM_LOOKUP_16(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr); +} + +uint32_t __attribute__((weak)) MEM_LOOKUP_32(JitCpu* jitcpu, uint64_t addr) +{ + return vm_MEM_LOOKUP_32(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr); +} + +uint64_t __attribute__((weak)) MEM_LOOKUP_64(JitCpu* jitcpu, uint64_t addr) +{ + return vm_MEM_LOOKUP_64(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr); +} + +void __attribute__((weak)) MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src) +{ + vm_MEM_WRITE_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); +} + +void __attribute__((weak)) MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src) +{ + vm_MEM_WRITE_16(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); +} + +void __attribute__((weak)) MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src) +{ + vm_MEM_WRITE_32(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); +} + +void __attribute__((weak)) MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src) +{ + vm_MEM_WRITE_64(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); +} + + + + +PyObject* __attribute__((weak)) vm_get_mem(JitCpu *self, PyObject* args) +{ + PyObject *py_addr; + PyObject *py_len; + + uint64_t addr; + uint64_t size; + PyObject *obj_out; + char * buf_out; + int ret; + + if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_len)) + return NULL; + + PyGetInt(py_addr, addr); + PyGetInt(py_len, size); + + ret = vm_read_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, &buf_out, size); + if (ret < 0) { + PyErr_SetString(PyExc_RuntimeError, "cannot find address"); + return NULL; + } + + obj_out = PyString_FromStringAndSize(buf_out, size); + free(buf_out); + return obj_out; +} diff --git a/miasm2/jitter/JitCore.h b/miasm2/jitter/JitCore.h new file mode 100644 index 00000000..af87a9cb --- /dev/null +++ b/miasm2/jitter/JitCore.h @@ -0,0 +1,134 @@ +#ifndef JITCORE_H +#define JITCORE_H + +#define RAISE(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return p;} +#define RAISE_ret0(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return 0;} + + +#define PyGetInt(item, value) \ + if (PyInt_Check(item)){ \ + value = (uint64_t)PyInt_AsLong(item); \ + } \ + else if (PyLong_Check(item)){ \ + value = (uint64_t)PyLong_AsUnsignedLongLong(item); \ + } \ + else{ \ + RAISE(PyExc_TypeError,"arg must be int"); \ + } \ + + +#define PyGetInt_ret0(item, value) \ + if (PyInt_Check(item)){ \ + value = (uint64_t)PyInt_AsLong(item); \ + } \ + else if (PyLong_Check(item)){ \ + value = (uint64_t)PyLong_AsUnsignedLongLong(item); \ + } \ + else{ \ + printf("error\n"); return 0; \ + } \ + + + +#define getset_reg_u64(regname) \ + static PyObject *JitCpu_get_ ## regname (JitCpu *self, void *closure) \ + { \ + return PyLong_FromUnsignedLongLong((uint64_t)(((vm_cpu_t*)(self->cpu))-> regname )); \ + } \ + static int JitCpu_set_ ## regname (JitCpu *self, PyObject *value, void *closure) \ + { \ + uint64_t val; \ + PyGetInt_ret0(value, val); \ + ((vm_cpu_t*)(self->cpu))-> regname = val; \ + return 0; \ + } + +#define getset_reg_u32(regname) \ + static PyObject *JitCpu_get_ ## regname (JitCpu *self, void *closure) \ + { \ + return PyLong_FromUnsignedLongLong((uint32_t)(((vm_cpu_t*)(self->cpu))-> regname )); \ + } \ + static int JitCpu_set_ ## regname (JitCpu *self, PyObject *value, void *closure) \ + { \ + uint32_t val; \ + PyGetInt_ret0(value, val); \ + ((vm_cpu_t*)(self->cpu))-> regname = val; \ + return 0; \ + } + + +#define getset_reg_u16(regname) \ + static PyObject *JitCpu_get_ ## regname (JitCpu *self, void *closure) \ + { \ + return PyLong_FromUnsignedLongLong((uint16_t)(((vm_cpu_t*)(self->cpu))-> regname )); \ + } \ + static int JitCpu_set_ ## regname (JitCpu *self, PyObject *value, void *closure) \ + { \ + uint16_t val; \ + PyGetInt_ret0(value, val); \ + ((vm_cpu_t*)(self->cpu))-> regname = val; \ + return 0; \ + } + + +#define get_reg(reg) do { \ + o = PyLong_FromUnsignedLongLong((uint64_t)((vm_cpu_t*)(self->cpu))->reg); \ + PyDict_SetItemString(dict, #reg, o); \ + Py_DECREF(o); \ + } while(0); + + +#define get_reg_off(reg) do { \ + o = PyLong_FromUnsignedLongLong((uint64_t)offsetof(vm_cpu_t, reg)); \ + PyDict_SetItemString(dict, #reg, o); \ + Py_DECREF(o); \ + } while(0); + + +typedef struct { + uint8_t is_local; + uint64_t address; +} block_id; + +typedef struct { + PyObject_HEAD + PyObject *pyvm; + PyObject *jitter; + void* cpu; +} JitCpu; + + +typedef struct _reg_dict{ + char* name; + size_t offset; +} reg_dict; + + + +void JitCpu_dealloc(JitCpu* self); +PyObject * JitCpu_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +PyObject * JitCpu_get_vmmngr(JitCpu *self, void *closure); +PyObject * JitCpu_set_vmmngr(JitCpu *self, PyObject *value, void *closure); +PyObject * JitCpu_get_jitter(JitCpu *self, void *closure); +PyObject * JitCpu_set_jitter(JitCpu *self, PyObject *value, void *closure); +void Resolve_dst(block_id* BlockDst, uint64_t addr, uint64_t is_local); + + + +uint8_t MEM_LOOKUP_08(JitCpu* jitcpu, uint64_t addr); +uint16_t MEM_LOOKUP_16(JitCpu* jitcpu, uint64_t addr); +uint32_t MEM_LOOKUP_32(JitCpu* jitcpu, uint64_t addr); +uint64_t MEM_LOOKUP_64(JitCpu* jitcpu, uint64_t addr); +void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src); +void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src); +void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src); +void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src); +PyObject* vm_get_mem(JitCpu *self, PyObject* args); + + + + +#define VM_exception_flag (((VmMngr*)jitcpu->pyvm)->vm_mngr.exception_flags) +#define CPU_exception_flag (((vm_cpu_t*)jitcpu->cpu)->exception_flags) + +#endif diff --git a/miasm2/jitter/Jittcc.c b/miasm2/jitter/Jittcc.c index 49035fc4..d146aaf4 100644 --- a/miasm2/jitter/Jittcc.c +++ b/miasm2/jitter/Jittcc.c @@ -127,14 +127,13 @@ typedef struct { PyObject* tcc_exec_bloc(PyObject* self, PyObject* args) { - void (*func)(block_id*, void*, void*); - uint64_t vm; - uint64_t cpu; + void (*func)(block_id*, PyObject*); + PyObject* jitcpu; block_id BlockDst = {0, 0}; - if (!PyArg_ParseTuple(args, "KKK", &func, &cpu, &vm)) + if (!PyArg_ParseTuple(args, "KO", &func, &jitcpu)) return NULL; - func(&BlockDst, (void*)cpu, (void*)vm); + func(&BlockDst, jitcpu); if (BlockDst.is_local == 1) { fprintf(stderr, "return on local label!\n"); diff --git a/miasm2/jitter/arch/JitCore.c b/miasm2/jitter/arch/JitCore.c deleted file mode 100644 index 6d3b0df4..00000000 --- a/miasm2/jitter/arch/JitCore.c +++ /dev/null @@ -1,8 +0,0 @@ -#include <Python.h> -#include "JitCore.h" - -void Resolve_dst(block_id* b, uint64_t addr, uint64_t is_local) -{ - b->address = addr; - b->is_local = is_local; -} diff --git a/miasm2/jitter/arch/JitCore.h b/miasm2/jitter/arch/JitCore.h deleted file mode 100644 index 735cbd27..00000000 --- a/miasm2/jitter/arch/JitCore.h +++ /dev/null @@ -1,73 +0,0 @@ - -#define PyGetInt(item, value) \ - if (PyInt_Check(item)){ \ - value = (uint64_t)PyInt_AsLong(item); \ - } \ - else if (PyLong_Check(item)){ \ - value = (uint64_t)PyLong_AsUnsignedLongLong(item); \ - } \ - else{ \ - RAISE(PyExc_TypeError,"arg must be int"); \ - } \ - - -#define PyGetInt_ret0(item, value) \ - if (PyInt_Check(item)){ \ - value = (uint64_t)PyInt_AsLong(item); \ - } \ - else if (PyLong_Check(item)){ \ - value = (uint64_t)PyLong_AsUnsignedLongLong(item); \ - } \ - else{ \ - printf("error\n"); return 0; \ - } \ - - - -#define getset_reg_u64(regname) \ - static PyObject *JitCpu_get_ ## regname (JitCpu *self, void *closure) \ - { \ - return PyLong_FromUnsignedLongLong((uint64_t)(self->vmcpu. regname )); \ - } \ - static int JitCpu_set_ ## regname (JitCpu *self, PyObject *value, void *closure) \ - { \ - uint64_t val; \ - PyGetInt_ret0(value, val); \ - self->vmcpu. regname = val; \ - return 0; \ - } - -#define getset_reg_u32(regname) \ - static PyObject *JitCpu_get_ ## regname (JitCpu *self, void *closure) \ - { \ - return PyLong_FromUnsignedLongLong((uint32_t)(self->vmcpu. regname )); \ - } \ - static int JitCpu_set_ ## regname (JitCpu *self, PyObject *value, void *closure) \ - { \ - uint32_t val; \ - PyGetInt_ret0(value, val); \ - self->vmcpu. regname = val; \ - return 0; \ - } - - -#define getset_reg_u16(regname) \ - static PyObject *JitCpu_get_ ## regname (JitCpu *self, void *closure) \ - { \ - return PyLong_FromUnsignedLongLong((uint16_t)(self->vmcpu. regname )); \ - } \ - static int JitCpu_set_ ## regname (JitCpu *self, PyObject *value, void *closure) \ - { \ - uint16_t val; \ - PyGetInt_ret0(value, val); \ - self->vmcpu. regname = val; \ - return 0; \ - } - - -typedef struct { - uint8_t is_local; - uint64_t address; -} block_id; - -void Resolve_dst(block_id* BlockDst, uint64_t addr, uint64_t is_local); diff --git a/miasm2/jitter/arch/JitCore_arm.c b/miasm2/jitter/arch/JitCore_arm.c index 46cff736..92027c25 100644 --- a/miasm2/jitter/arch/JitCore_arm.c +++ b/miasm2/jitter/arch/JitCore_arm.c @@ -1,28 +1,14 @@ #include <Python.h> -#include "JitCore.h" +#include "../JitCore.h" #include "structmember.h" #include <stdint.h> #include <inttypes.h> +#include "../queue.h" +#include "../vm_mngr.h" +#include "../vm_mngr_py.h" #include "JitCore_arm.h" -#define RAISE(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return p;} -typedef struct _reg_dict{ - char* name; - unsigned long offset; -} reg_dict; - - -#define PyGetInt(item, value) \ - if (PyInt_Check(item)){ \ - value = (uint64_t)PyInt_AsLong(item); \ - } \ - else if (PyLong_Check(item)){ \ - value = (uint64_t)PyLong_AsUnsignedLongLong(item); \ - } \ - else{ \ - RAISE(PyExc_TypeError,"arg must be int"); \ - } \ reg_dict gpreg_dict[] = { {.name = "R0", .offset = offsetof(vm_cpu_t, R0)}, {.name = "R1", .offset = offsetof(vm_cpu_t, R1)}, @@ -49,19 +35,6 @@ reg_dict gpreg_dict[] = { {.name = "R0", .offset = offsetof(vm_cpu_t, R0)}, /************************** JitCpu object **************************/ -typedef struct { - PyObject_HEAD - PyObject *cpu; /* cpu */ - vm_cpu_t vmcpu; -} JitCpu; - - - -#define get_reg(reg) do { \ - o = PyLong_FromUnsignedLongLong((uint64_t)self->vmcpu.reg); \ - PyDict_SetItemString(dict, #reg, o); \ - Py_DECREF(o); \ - } while(0); @@ -95,13 +68,18 @@ PyObject* cpu_get_gpreg(JitCpu* self) return dict; } -PyObject* _vm_set_gpreg(JitCpu* self, PyObject *dict) + + +PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) { + PyObject* dict; PyObject *d_key, *d_value = NULL; Py_ssize_t pos = 0; uint64_t val; unsigned int i, found; + if (!PyArg_ParseTuple(args, "O", &dict)) + return NULL; if(!PyDict_Check(dict)) RAISE(PyExc_TypeError, "arg must be dict"); while(PyDict_Next(dict, &pos, &d_key, &d_value)){ @@ -110,12 +88,11 @@ PyObject* _vm_set_gpreg(JitCpu* self, PyObject *dict) PyGetInt(d_value, val); - found = 0; for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){ if (strcmp(PyString_AsString(d_key), gpreg_dict[i].name)) continue; - *((uint32_t*)(((char*)&(self->vmcpu)) + gpreg_dict[i].offset)) = val; + *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val; found = 1; break; } @@ -125,48 +102,17 @@ PyObject* _vm_set_gpreg(JitCpu* self, PyObject *dict) fprintf(stderr, "unkown key: %s\n", PyString_AsString(d_key)); RAISE(PyExc_ValueError, "unkown reg"); } - return NULL; -} - -PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) -{ - PyObject* dict; - if (!PyArg_ParseTuple(args, "O", &dict)) - return NULL; - _vm_set_gpreg(self, dict); - Py_INCREF(Py_None); - return Py_None; -} - - -PyObject* cpu_set_exception(JitCpu* self, PyObject* args) -{ - PyObject *item1; - uint64_t i; - - if (!PyArg_ParseTuple(args, "O", &item1)) - return NULL; - - PyGetInt(item1, i); - - self->vmcpu.exception_flags = i; - Py_INCREF(Py_None); - return Py_None; -} - -PyObject* cpu_get_exception(JitCpu* self, PyObject* args) -{ - return PyLong_FromUnsignedLongLong((uint64_t)self->vmcpu.exception_flags); + Py_INCREF(Py_None); + return Py_None; } PyObject * cpu_init_regs(JitCpu* self) { - memset(&self->vmcpu, 0, sizeof(vm_cpu_t)); + memset(self->cpu, 0, sizeof(vm_cpu_t)); Py_INCREF(Py_None); return Py_None; - } void dump_gpregs(vm_cpu_t* vmcpu) @@ -188,41 +134,106 @@ PyObject * cpu_dump_gpregs(JitCpu* self, PyObject* args) { vm_cpu_t* vmcpu; - vmcpu = &self->vmcpu; + vmcpu = self->cpu; dump_gpregs(vmcpu); Py_INCREF(Py_None); return Py_None; } +PyObject* cpu_set_exception(JitCpu* self, PyObject* args) +{ + PyObject *item1; + uint64_t i; + + if (!PyArg_ParseTuple(args, "O", &item1)) + return NULL; + + PyGetInt(item1, i); + + ((vm_cpu_t*)self->cpu)->exception_flags = i; + Py_INCREF(Py_None); + return Py_None; +} + +PyObject* cpu_get_exception(JitCpu* self, PyObject* args) +{ + return PyLong_FromUnsignedLongLong((uint64_t)(((vm_cpu_t*)self->cpu)->exception_flags)); +} + + + -static void -JitCpu_dealloc(JitCpu* self) + +void check_automod(JitCpu* jitcpu, uint64_t addr, int size) { - self->ob_type->tp_free((PyObject*)self); + PyObject *result; + + if (!(((VmMngr*)jitcpu->pyvm)->vm_mngr.exception_flags & EXCEPT_CODE_AUTOMOD)) + return; + result = PyObject_CallMethod(jitcpu->jitter, "automod_cb", "LL", addr, size); + Py_DECREF(result); + } +void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src) +{ + vm_MEM_WRITE_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); + check_automod(jitcpu, addr, 8); +} -static PyObject * -JitCpu_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src) { - JitCpu *self; + vm_MEM_WRITE_16(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); + check_automod(jitcpu, addr, 16); +} - self = (JitCpu *)type->tp_alloc(type, 0); - return (PyObject *)self; +void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src) +{ + vm_MEM_WRITE_32(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); + check_automod(jitcpu, addr, 32); } -static PyObject * -JitCpu_get_cpu(JitCpu *self, void *closure) +void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src) { - return PyLong_FromUnsignedLongLong((uint64_t)&(self->vmcpu)); + vm_MEM_WRITE_64(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); + check_automod(jitcpu, addr, 64); } -static int -JitCpu_set_cpu(JitCpu *self, PyObject *value, void *closure) + + + + + +PyObject* vm_set_mem(JitCpu *self, PyObject* args) { - PyErr_SetString(PyExc_TypeError, "immutable cpu"); - return -1; + PyObject *py_addr; + PyObject *py_buffer; + Py_ssize_t py_length; + + char * buffer; + uint64_t size; + uint64_t addr; + int ret = 0x1337; + + if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_buffer)) + return NULL; + + PyGetInt(py_addr, addr); + + if(!PyString_Check(py_buffer)) + RAISE(PyExc_TypeError,"arg must be str"); + + size = PyString_Size(py_buffer); + PyString_AsStringAndSize(py_buffer, &buffer, &py_length); + + ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size); + if (ret < 0) + RAISE(PyExc_TypeError,"arg must be str"); + check_automod(self, addr, size*8); + + Py_INCREF(Py_None); + return Py_None; } static PyMemberDef JitCpu_members[] = { @@ -242,12 +253,21 @@ static PyMethodDef JitCpu_methods[] = { "X"}, {"set_exception", (PyCFunction)cpu_set_exception, METH_VARARGS, "X"}, + {"set_mem", (PyCFunction)vm_set_mem, METH_VARARGS, + "X"}, + {"get_mem", (PyCFunction)vm_get_mem, METH_VARARGS, + "X"}, {NULL} /* Sentinel */ }; static int JitCpu_init(JitCpu *self, PyObject *args, PyObject *kwds) { + self->cpu = malloc(sizeof(vm_cpu_t)); + if (self->cpu == NULL) { + fprintf(stderr, "cannot alloc vm_cpu_t\n"); + exit(0); + } return 0; } @@ -274,13 +294,6 @@ getset_reg_u32(of); getset_reg_u32(cf); - -#define get_reg_off(reg) do { \ - o = PyLong_FromUnsignedLongLong((uint64_t)offsetof(vm_cpu_t, reg)); \ - PyDict_SetItemString(dict, #reg, o); \ - Py_DECREF(o); \ - } while(0); - PyObject* get_gpreg_offset_all(void) { PyObject *dict = PyDict_New(); @@ -428,11 +441,18 @@ PyObject* get_gpreg_offset_all(void) static PyGetSetDef JitCpu_getseters[] = { - {"cpu", - (getter)JitCpu_get_cpu, (setter)JitCpu_set_cpu, - "first name", + {"vmmngr", + (getter)JitCpu_get_vmmngr, (setter)JitCpu_set_vmmngr, + "vmmngr", + NULL}, + + {"jitter", + (getter)JitCpu_get_jitter, (setter)JitCpu_set_jitter, + "jitter", NULL}, + + {"R0" , (getter)JitCpu_get_R0 , (setter)JitCpu_set_R0 , "R0" , NULL}, {"R1" , (getter)JitCpu_get_R1 , (setter)JitCpu_set_R1 , "R1" , NULL}, {"R2" , (getter)JitCpu_get_R2 , (setter)JitCpu_set_R2 , "R2" , NULL}, diff --git a/miasm2/jitter/arch/JitCore_arm.h b/miasm2/jitter/arch/JitCore_arm.h index cf985ea7..dde112ef 100644 --- a/miasm2/jitter/arch/JitCore_arm.h +++ b/miasm2/jitter/arch/JitCore_arm.h @@ -137,9 +137,6 @@ typedef struct { uint64_t pfmem64_18; uint64_t pfmem64_19; - - uint32_t segm_base[0x10000]; - }vm_cpu_t; diff --git a/miasm2/jitter/arch/JitCore_mips32.c b/miasm2/jitter/arch/JitCore_mips32.c index a1e938ba..4cd016cf 100644 --- a/miasm2/jitter/arch/JitCore_mips32.c +++ b/miasm2/jitter/arch/JitCore_mips32.c @@ -1,29 +1,13 @@ #include <Python.h> -#include "JitCore.h" +#include "../JitCore.h" #include "structmember.h" #include <stdint.h> #include <inttypes.h> +#include "../queue.h" +#include "../vm_mngr.h" +#include "../vm_mngr_py.h" #include "JitCore_mips32.h" -#define RAISE(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return p;} - -typedef struct _reg_dict{ - char* name; - unsigned long offset; -} reg_dict; - - -#define PyGetInt(item, value) \ - if (PyInt_Check(item)){ \ - value = (uint64_t)PyInt_AsLong(item); \ - } \ - else if (PyLong_Check(item)){ \ - value = (uint64_t)PyLong_AsUnsignedLongLong(item); \ - } \ - else{ \ - RAISE(PyExc_TypeError,"arg must be int"); \ - } \ - reg_dict gpreg_dict[] = { {.name = "ZERO", .offset = offsetof(vm_cpu_t, ZERO)}, @@ -66,20 +50,6 @@ reg_dict gpreg_dict[] = { {.name = "ZERO", .offset = offsetof(vm_cpu_t, ZERO)}, /************************** JitCpu object **************************/ -typedef struct { - PyObject_HEAD - PyObject *cpu; /* cpu */ - vm_cpu_t vmcpu; -} JitCpu; - - - -#define get_reg(reg) do { \ - o = PyLong_FromUnsignedLongLong((uint32_t)self->vmcpu.reg); \ - PyDict_SetItemString(dict, #reg, o); \ - Py_DECREF(o); \ - } while(0); - PyObject* cpu_get_gpreg(JitCpu* self) @@ -127,13 +97,19 @@ PyObject* cpu_get_gpreg(JitCpu* self) return dict; } -PyObject* _vm_set_gpreg(JitCpu* self, PyObject *dict) + + + +PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) { + PyObject* dict; PyObject *d_key, *d_value = NULL; Py_ssize_t pos = 0; uint64_t val; unsigned int i, found; + if (!PyArg_ParseTuple(args, "O", &dict)) + return NULL; if(!PyDict_Check(dict)) RAISE(PyExc_TypeError, "arg must be dict"); while(PyDict_Next(dict, &pos, &d_key, &d_value)){ @@ -142,12 +118,11 @@ PyObject* _vm_set_gpreg(JitCpu* self, PyObject *dict) PyGetInt(d_value, val); - found = 0; for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){ if (strcmp(PyString_AsString(d_key), gpreg_dict[i].name)) continue; - *((uint32_t*)(((char*)&(self->vmcpu)) + gpreg_dict[i].offset)) = val; + *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val; found = 1; break; } @@ -157,50 +132,23 @@ PyObject* _vm_set_gpreg(JitCpu* self, PyObject *dict) fprintf(stderr, "unkown key: %s\n", PyString_AsString(d_key)); RAISE(PyExc_ValueError, "unkown reg"); } - return NULL; + Py_INCREF(Py_None); + return Py_None; } -PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) -{ - PyObject* dict; - if (!PyArg_ParseTuple(args, "O", &dict)) - return NULL; - _vm_set_gpreg(self, dict); - Py_INCREF(Py_None); - return Py_None; -} -PyObject* cpu_set_exception(JitCpu* self, PyObject* args) -{ - PyObject *item1; - uint64_t i; - - if (!PyArg_ParseTuple(args, "O", &item1)) - return NULL; - - PyGetInt(item1, i); - - self->vmcpu.exception_flags = i; - Py_INCREF(Py_None); - return Py_None; -} - -PyObject* cpu_get_exception(JitCpu* self, PyObject* args) -{ - return PyLong_FromUnsignedLongLong((uint32_t)self->vmcpu.exception_flags); -} - PyObject * cpu_init_regs(JitCpu* self) { - memset(&self->vmcpu, 0, sizeof(vm_cpu_t)); + memset(self->cpu, 0, sizeof(vm_cpu_t)); Py_INCREF(Py_None); return Py_None; } + void dump_gpregs(vm_cpu_t* vmcpu) { @@ -229,41 +177,103 @@ PyObject * cpu_dump_gpregs(JitCpu* self, PyObject* args) { vm_cpu_t* vmcpu; - vmcpu = &self->vmcpu; + vmcpu = self->cpu; dump_gpregs(vmcpu); Py_INCREF(Py_None); return Py_None; } +PyObject* cpu_set_exception(JitCpu* self, PyObject* args) +{ + PyObject *item1; + uint64_t i; + + if (!PyArg_ParseTuple(args, "O", &item1)) + return NULL; + + PyGetInt(item1, i); + + ((vm_cpu_t*)self->cpu)->exception_flags = i; + Py_INCREF(Py_None); + return Py_None; +} + +PyObject* cpu_get_exception(JitCpu* self, PyObject* args) +{ + return PyLong_FromUnsignedLongLong((uint64_t)(((vm_cpu_t*)self->cpu)->exception_flags)); +} + + -static void -JitCpu_dealloc(JitCpu* self) + + + +void check_automod(JitCpu* jitcpu, uint64_t addr, int size) { - self->ob_type->tp_free((PyObject*)self); + PyObject *result; + + if (!(((VmMngr*)jitcpu->pyvm)->vm_mngr.exception_flags & EXCEPT_CODE_AUTOMOD)) + return; + result = PyObject_CallMethod(jitcpu->jitter, "automod_cb", "LL", addr, size); + Py_DECREF(result); + } +void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src) +{ + vm_MEM_WRITE_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); + check_automod(jitcpu, addr, 8); +} -static PyObject * -JitCpu_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src) { - JitCpu *self; + vm_MEM_WRITE_16(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); + check_automod(jitcpu, addr, 16); +} - self = (JitCpu *)type->tp_alloc(type, 0); - return (PyObject *)self; +void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src) +{ + vm_MEM_WRITE_32(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); + check_automod(jitcpu, addr, 32); } -static PyObject * -JitCpu_get_cpu(JitCpu *self, void *closure) +void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src) { - return PyLong_FromUnsignedLongLong((uint64_t)&(self->vmcpu)); + vm_MEM_WRITE_64(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); + check_automod(jitcpu, addr, 64); } -static int -JitCpu_set_cpu(JitCpu *self, PyObject *value, void *closure) + +PyObject* vm_set_mem(JitCpu *self, PyObject* args) { - PyErr_SetString(PyExc_TypeError, "immutable cpu"); - return -1; + PyObject *py_addr; + PyObject *py_buffer; + Py_ssize_t py_length; + + char * buffer; + uint64_t size; + uint64_t addr; + int ret = 0x1337; + + if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_buffer)) + return NULL; + + PyGetInt(py_addr, addr); + + if(!PyString_Check(py_buffer)) + RAISE(PyExc_TypeError,"arg must be str"); + + size = PyString_Size(py_buffer); + PyString_AsStringAndSize(py_buffer, &buffer, &py_length); + + ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size); + if (ret < 0) + RAISE(PyExc_TypeError,"arg must be str"); + check_automod(self, addr, size*8); + + Py_INCREF(Py_None); + return Py_None; } static PyMemberDef JitCpu_members[] = { @@ -283,12 +293,22 @@ static PyMethodDef JitCpu_methods[] = { "X"}, {"set_exception", (PyCFunction)cpu_set_exception, METH_VARARGS, "X"}, + {"set_mem", (PyCFunction)vm_set_mem, METH_VARARGS, + "X"}, + {"get_mem", (PyCFunction)vm_get_mem, METH_VARARGS, + "X"}, {NULL} /* Sentinel */ }; + static int JitCpu_init(JitCpu *self, PyObject *args, PyObject *kwds) { + self->cpu = malloc(sizeof(vm_cpu_t)); + if (self->cpu == NULL) { + fprintf(stderr, "cannot alloc vm_cpu_t\n"); + exit(0); + } return 0; } @@ -330,13 +350,6 @@ getset_reg_u32(R_LO); getset_reg_u32(R_HI); - -#define get_reg_off(reg) do { \ - o = PyLong_FromUnsignedLongLong((uint64_t)offsetof(vm_cpu_t, reg)); \ - PyDict_SetItemString(dict, #reg, o); \ - Py_DECREF(o); \ - } while(0); - PyObject* get_gpreg_offset_all(void) { PyObject *dict = PyDict_New(); @@ -514,9 +527,14 @@ PyObject* get_gpreg_offset_all(void) static PyGetSetDef JitCpu_getseters[] = { - {"cpu", - (getter)JitCpu_get_cpu, (setter)JitCpu_set_cpu, - "first name", + {"vmmngr", + (getter)JitCpu_get_vmmngr, (setter)JitCpu_set_vmmngr, + "vmmngr", + NULL}, + + {"jitter", + (getter)JitCpu_get_jitter, (setter)JitCpu_set_jitter, + "jitter", NULL}, {"ZERO" , (getter)JitCpu_get_ZERO , (setter)JitCpu_set_ZERO , "ZERO" , NULL}, diff --git a/miasm2/jitter/arch/JitCore_mips32.h b/miasm2/jitter/arch/JitCore_mips32.h index ac128250..6b7a6200 100644 --- a/miasm2/jitter/arch/JitCore_mips32.h +++ b/miasm2/jitter/arch/JitCore_mips32.h @@ -235,7 +235,6 @@ typedef struct { double F30_new; double F31_new; - }vm_cpu_t; diff --git a/miasm2/jitter/arch/JitCore_msp430.c b/miasm2/jitter/arch/JitCore_msp430.c index b52ad5d0..e4f26de1 100644 --- a/miasm2/jitter/arch/JitCore_msp430.c +++ b/miasm2/jitter/arch/JitCore_msp430.c @@ -1,62 +1,13 @@ #include <Python.h> -#include "JitCore.h" +#include "../JitCore.h" #include "structmember.h" #include <stdint.h> #include <inttypes.h> +#include "../queue.h" +#include "../vm_mngr.h" +#include "../vm_mngr_py.h" #include "JitCore_msp430.h" -#define RAISE(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return p;} - -/* -void check_align(uint64_t addr) -{ - if (addr & 1) { - printf("unaligned mem lookup %X\n", addr); - exit(0); - } -} - -void VM_MEM_WRITE_08(vm_mngr_t* vm_mngr, uint64_t addr, unsigned char src) -{ - //check_align(addr); - MEM_WRITE_08(vm_mngr, addr, src); -} - -void VM_MEM_WRITE_16(vm_mngr_t* vm_mngr, uint64_t addr, unsigned short src) -{ - check_align(addr); - MEM_WRITE_16(vm_mngr, addr, src); -} - -void VM_MEM_WRITE_32(vm_mngr_t* vm_mngr, uint64_t addr, unsigned int src) -{ - check_align(addr); - MEM_WRITE_32(vm_mngr, addr, src); -} - -void VM_MEM_WRITE_64(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t src) -{ - check_align(addr); - MEM_WRITE_64(vm_mngr, addr, src); -} -*/ - -typedef struct _reg_dict{ - char* name; - unsigned long offset; -} reg_dict; - - -#define PyGetInt(item, value) \ - if (PyInt_Check(item)){ \ - value = (uint64_t)PyInt_AsLong(item); \ - } \ - else if (PyLong_Check(item)){ \ - value = (uint64_t)PyLong_AsUnsignedLongLong(item); \ - } \ - else{ \ - RAISE(PyExc_TypeError,"arg must be int"); \ - } \ reg_dict gpreg_dict[] = { {.name = "PC", .offset = offsetof(vm_cpu_t, PC)}, {.name = "SP", .offset = offsetof(vm_cpu_t, SP)}, @@ -91,20 +42,6 @@ reg_dict gpreg_dict[] = { {.name = "PC", .offset = offsetof(vm_cpu_t, PC)}, /************************** JitCpu object **************************/ -typedef struct { - PyObject_HEAD - PyObject *cpu; /* cpu */ - vm_cpu_t vmcpu; -} JitCpu; - - - -#define get_reg(reg) do { \ - o = PyLong_FromUnsignedLongLong((uint64_t)self->vmcpu.reg); \ - PyDict_SetItemString(dict, #reg, o); \ - Py_DECREF(o); \ - } while(0); - PyObject* cpu_get_gpreg(JitCpu* self) @@ -145,11 +82,234 @@ PyObject* cpu_get_gpreg(JitCpu* self) return dict; } -#define get_reg_off(reg) do { \ - o = PyLong_FromUnsignedLongLong((uint64_t)offsetof(vm_cpu_t, reg)); \ - PyDict_SetItemString(dict, #reg, o); \ - Py_DECREF(o); \ - } while(0); + +PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) +{ + PyObject* dict; + PyObject *d_key, *d_value = NULL; + Py_ssize_t pos = 0; + uint64_t val; + unsigned int i, found; + + if (!PyArg_ParseTuple(args, "O", &dict)) + return NULL; + 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"); + + PyGetInt(d_value, val); + + found = 0; + for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){ + if (strcmp(PyString_AsString(d_key), gpreg_dict[i].name)) + continue; + *((uint32_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val; + found = 1; + break; + } + + if (found) + continue; + fprintf(stderr, "unkown key: %s\n", PyString_AsString(d_key)); + RAISE(PyExc_ValueError, "unkown reg"); + } + Py_INCREF(Py_None); + return Py_None; +} + + + + +PyObject * cpu_init_regs(JitCpu* self) +{ + memset(self->cpu, 0, sizeof(vm_cpu_t)); + + Py_INCREF(Py_None); + return Py_None; + +} + +void dump_gpregs(vm_cpu_t* vmcpu) +{ + + printf("PC %.4"PRIX32" SP %.4"PRIX32" R3 %.4"PRIX32" ", + vmcpu->PC, vmcpu->SP, vmcpu->R3); + printf("R4 %.4"PRIX32" R5 %.4"PRIX32" R6 %.4"PRIX32" R7 %.4"PRIX32"\n", + vmcpu->R4, vmcpu->R5, vmcpu->R6, vmcpu->R7); + printf("R8 %.4"PRIX32" R9 %.4"PRIX32" R10 %.4"PRIX32" R11 %.4"PRIX32" ", + vmcpu->R8, vmcpu->R9, vmcpu->R10, vmcpu->R11); + printf("R12 %.4"PRIX32" R13 %.4"PRIX32" R14 %.4"PRIX32" R15 %.4"PRIX32"\n", + vmcpu->R12, vmcpu->R13, vmcpu->R14, vmcpu->R15); + printf("zf %.4"PRIX32" nf %.4"PRIX32" of %.4"PRIX32" cf %.4"PRIX32"\n", + vmcpu->zf, vmcpu->nf, vmcpu->of, vmcpu->cf); +} + + +PyObject * cpu_dump_gpregs(JitCpu* self, PyObject* args) +{ + vm_cpu_t* vmcpu; + + vmcpu = self->cpu; + dump_gpregs(vmcpu); + Py_INCREF(Py_None); + return Py_None; +} + + +PyObject* cpu_set_exception(JitCpu* self, PyObject* args) +{ + PyObject *item1; + uint64_t i; + + if (!PyArg_ParseTuple(args, "O", &item1)) + return NULL; + + PyGetInt(item1, i); + + ((vm_cpu_t*)self->cpu)->exception_flags = i; + Py_INCREF(Py_None); + return Py_None; +} + +PyObject* cpu_get_exception(JitCpu* self, PyObject* args) +{ + return PyLong_FromUnsignedLongLong((uint64_t)(((vm_cpu_t*)self->cpu)->exception_flags)); +} + + + + + +void check_automod(JitCpu* jitcpu, uint64_t addr, int size) +{ + PyObject *result; + + if (!(((VmMngr*)jitcpu->pyvm)->vm_mngr.exception_flags & EXCEPT_CODE_AUTOMOD)) + return; + result = PyObject_CallMethod(jitcpu->jitter, "automod_cb", "LL", addr, size); + Py_DECREF(result); + +} + +void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src) +{ + vm_MEM_WRITE_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); + check_automod(jitcpu, addr, 8); +} + +void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src) +{ + vm_MEM_WRITE_16(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); + check_automod(jitcpu, addr, 16); +} + +void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src) +{ + vm_MEM_WRITE_32(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); + check_automod(jitcpu, addr, 32); +} + +void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src) +{ + vm_MEM_WRITE_64(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); + check_automod(jitcpu, addr, 64); +} + + +PyObject* vm_set_mem(JitCpu *self, PyObject* args) +{ + PyObject *py_addr; + PyObject *py_buffer; + Py_ssize_t py_length; + + char * buffer; + uint64_t size; + uint64_t addr; + int ret = 0x1337; + + if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_buffer)) + return NULL; + + PyGetInt(py_addr, addr); + + if(!PyString_Check(py_buffer)) + RAISE(PyExc_TypeError,"arg must be str"); + + size = PyString_Size(py_buffer); + PyString_AsStringAndSize(py_buffer, &buffer, &py_length); + + ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size); + if (ret < 0) + RAISE(PyExc_TypeError,"arg must be str"); + check_automod(self, addr, size*8); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyMemberDef JitCpu_members[] = { + {NULL} /* Sentinel */ +}; + +static PyMethodDef JitCpu_methods[] = { + {"init_regs", (PyCFunction)cpu_init_regs, METH_NOARGS, + "X"}, + {"dump_gpregs", (PyCFunction)cpu_dump_gpregs, METH_NOARGS, + "X"}, + {"get_gpreg", (PyCFunction)cpu_get_gpreg, METH_NOARGS, + "X"}, + {"set_gpreg", (PyCFunction)cpu_set_gpreg, METH_VARARGS, + "X"}, + {"get_exception", (PyCFunction)cpu_get_exception, METH_VARARGS, + "X"}, + {"set_exception", (PyCFunction)cpu_set_exception, METH_VARARGS, + "X"}, + {"set_mem", (PyCFunction)vm_set_mem, METH_VARARGS, + "X"}, + {"get_mem", (PyCFunction)vm_get_mem, METH_VARARGS, + "X"}, + {NULL} /* Sentinel */ +}; + +static int +JitCpu_init(JitCpu *self, PyObject *args, PyObject *kwds) +{ + self->cpu = malloc(sizeof(vm_cpu_t)); + if (self->cpu == NULL) { + fprintf(stderr, "cannot alloc vm_cpu_t\n"); + exit(0); + } + return 0; +} + +getset_reg_u16(PC); +getset_reg_u16(SP); +getset_reg_u16(R3); +getset_reg_u16(R4); +getset_reg_u16(R5); +getset_reg_u16(R6); +getset_reg_u16(R7); +getset_reg_u16(R8); +getset_reg_u16(R9); +getset_reg_u16(R10); +getset_reg_u16(R11); +getset_reg_u16(R12); +getset_reg_u16(R13); +getset_reg_u16(R14); +getset_reg_u16(R15); +getset_reg_u16(zf); +getset_reg_u16(nf); +getset_reg_u16(of); +getset_reg_u16(cf); +getset_reg_u16(cpuoff); +getset_reg_u16(gie); +getset_reg_u16(osc); +getset_reg_u16(scg0); +getset_reg_u16(scg1); +getset_reg_u16(res); + PyObject* get_gpreg_offset_all(void) @@ -293,290 +453,17 @@ PyObject* get_gpreg_offset_all(void) } -PyObject* _vm_set_gpreg(JitCpu* self, PyObject *dict) -{ - PyObject *d_key, *d_value = NULL; - Py_ssize_t pos = 0; - uint64_t 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"); - - PyGetInt(d_value, val); - - - found = 0; - for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){ - if (strcmp(PyString_AsString(d_key), gpreg_dict[i].name)) - continue; - *((uint32_t*)(((char*)&(self->vmcpu)) + gpreg_dict[i].offset)) = val; - found = 1; - break; - } - - if (found) - continue; - fprintf(stderr, "unkown key: %s\n", PyString_AsString(d_key)); - RAISE(PyExc_ValueError, "unkown reg"); - } - return NULL; -} -/* -uint8_t const bcd2bin_data[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0, 0, 0, 0, 0, 0, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 0, 0, 0, 0, 0, 0, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 0, 0, 0, 0, 0, 0, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 0, 0, 0, 0, 0, 0, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, 0, 0, 0, 0, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 0, 0, 0, 0, 0, 0, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 -}; - -uint8_t const bin2bcd_data[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99 -}; - -uint16_t bcdadd_16(uint16_t a, uint16_t b) -{ - int carry = 0; - int i,j = 0; - uint16_t res = 0; - int nib_a, nib_b; - for (i = 0; i < 16; i += 4) { - nib_a = (a >> i) & (0xF); - nib_b = (b >> i) & (0xF); - - j = (carry + nib_a + nib_b); - if (j >= 10) { - carry = 1; - j -= 10; - j &=0xf; - } - else { - carry = 0; - } - res += j << i; - } - return res; -} - -uint16_t bcdadd_cf_16(uint16_t a, uint16_t b) -{ - int carry = 0; - int i,j = 0; - int nib_a, nib_b; - for (i = 0; i < 16; i += 4) { - nib_a = (a >> i) & (0xF); - nib_b = (b >> i) & (0xF); - - j = (carry + nib_a + nib_b); - if (j >= 10) { - carry = 1; - j -= 10; - j &=0xf; - } - else { - carry = 0; - } - } - return carry; -} - - -uint16_t hex2bcd_16(uint16_t a) -{ - return bcd2bin_data[a & 0xFF] + (bcd2bin_data[(a >> 8) & 0xFF] * 100); -} - -uint8_t hex2bcd_8(uint8_t a) -{ - return bcd2bin_data[a & 0xFF]; -} - -uint8_t bcd2hex_8(uint8_t a) -{ - return bin2bcd_data[a & 0xFF]; -} - -uint16_t bcd2hex_16(uint16_t a) -{ - return bcd2bin_data[a % 100] | (bcd2bin_data[(a / 100)] << 8); -} -*/ - -PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) -{ - PyObject* dict; - if (!PyArg_ParseTuple(args, "O", &dict)) - return NULL; - _vm_set_gpreg(self, dict); - Py_INCREF(Py_None); - return Py_None; -} - - -PyObject* cpu_set_exception(JitCpu* self, PyObject* args) -{ - PyObject *item1; - uint64_t i; - - if (!PyArg_ParseTuple(args, "O", &item1)) - return NULL; - - PyGetInt(item1, i); - - self->vmcpu.exception_flags = i; - Py_INCREF(Py_None); - return Py_None; -} - -PyObject* cpu_get_exception(JitCpu* self, PyObject* args) -{ - return PyLong_FromUnsignedLongLong((uint64_t)self->vmcpu.exception_flags); -} - - -PyObject * cpu_init_regs(JitCpu* self) -{ - memset(&self->vmcpu, 0, sizeof(vm_cpu_t)); - - Py_INCREF(Py_None); - return Py_None; - -} - -void dump_gpregs(vm_cpu_t* vmcpu) -{ - - printf("PC %.4"PRIX32" SP %.4"PRIX32" R3 %.4"PRIX32" ", - vmcpu->PC, vmcpu->SP, vmcpu->R3); - printf("R4 %.4"PRIX32" R5 %.4"PRIX32" R6 %.4"PRIX32" R7 %.4"PRIX32"\n", - vmcpu->R4, vmcpu->R5, vmcpu->R6, vmcpu->R7); - printf("R8 %.4"PRIX32" R9 %.4"PRIX32" R10 %.4"PRIX32" R11 %.4"PRIX32" ", - vmcpu->R8, vmcpu->R9, vmcpu->R10, vmcpu->R11); - printf("R12 %.4"PRIX32" R13 %.4"PRIX32" R14 %.4"PRIX32" R15 %.4"PRIX32"\n", - vmcpu->R12, vmcpu->R13, vmcpu->R14, vmcpu->R15); - printf("zf %.4"PRIX32" nf %.4"PRIX32" of %.4"PRIX32" cf %.4"PRIX32"\n", - vmcpu->zf, vmcpu->nf, vmcpu->of, vmcpu->cf); -} - - -PyObject * cpu_dump_gpregs(JitCpu* self, PyObject* args) -{ - vm_cpu_t* vmcpu; - - vmcpu = &self->vmcpu; - dump_gpregs(vmcpu); - Py_INCREF(Py_None); - return Py_None; -} - - - -static void -JitCpu_dealloc(JitCpu* self) -{ - self->ob_type->tp_free((PyObject*)self); -} - - -static PyObject * -JitCpu_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - JitCpu *self; - - self = (JitCpu *)type->tp_alloc(type, 0); - return (PyObject *)self; -} - -static PyObject * -JitCpu_get_cpu(JitCpu *self, void *closure) -{ - return PyLong_FromUnsignedLongLong((uint64_t)&(self->vmcpu)); -} - -static int -JitCpu_set_cpu(JitCpu *self, PyObject *value, void *closure) -{ - PyErr_SetString(PyExc_TypeError, "immutable cpu"); - return -1; -} - -static PyMemberDef JitCpu_members[] = { - {NULL} /* Sentinel */ -}; - -static PyMethodDef JitCpu_methods[] = { - {"init_regs", (PyCFunction)cpu_init_regs, METH_NOARGS, - "X"}, - {"dump_gpregs", (PyCFunction)cpu_dump_gpregs, METH_NOARGS, - "X"}, - {"get_gpreg", (PyCFunction)cpu_get_gpreg, METH_NOARGS, - "X"}, - {"set_gpreg", (PyCFunction)cpu_set_gpreg, METH_VARARGS, - "X"}, - {"get_exception", (PyCFunction)cpu_get_exception, METH_VARARGS, - "X"}, - {"set_exception", (PyCFunction)cpu_set_exception, METH_VARARGS, - "X"}, - {NULL} /* Sentinel */ -}; - -static int -JitCpu_init(JitCpu *self, PyObject *args, PyObject *kwds) -{ - return 0; -} - -getset_reg_u16(PC); -getset_reg_u16(SP); -getset_reg_u16(R3); -getset_reg_u16(R4); -getset_reg_u16(R5); -getset_reg_u16(R6); -getset_reg_u16(R7); -getset_reg_u16(R8); -getset_reg_u16(R9); -getset_reg_u16(R10); -getset_reg_u16(R11); -getset_reg_u16(R12); -getset_reg_u16(R13); -getset_reg_u16(R14); -getset_reg_u16(R15); -getset_reg_u16(zf); -getset_reg_u16(nf); -getset_reg_u16(of); -getset_reg_u16(cf); -getset_reg_u16(cpuoff); -getset_reg_u16(gie); -getset_reg_u16(osc); -getset_reg_u16(scg0); -getset_reg_u16(scg1); -getset_reg_u16(res); - - static PyGetSetDef JitCpu_getseters[] = { - {"cpu", - (getter)JitCpu_get_cpu, (setter)JitCpu_set_cpu, - "first name", + {"vmmngr", + (getter)JitCpu_get_vmmngr, (setter)JitCpu_set_vmmngr, + "vmmngr", + NULL}, + + {"jitter", + (getter)JitCpu_get_jitter, (setter)JitCpu_set_jitter, + "jitter", NULL}, diff --git a/miasm2/jitter/arch/JitCore_msp430.h b/miasm2/jitter/arch/JitCore_msp430.h index e1c001b7..179554ad 100644 --- a/miasm2/jitter/arch/JitCore_msp430.h +++ b/miasm2/jitter/arch/JitCore_msp430.h @@ -152,8 +152,6 @@ typedef struct { uint64_t pfmem64_19; - uint32_t segm_base[0x10000]; - }vm_cpu_t; //#define RETURN_PC return PyLong_FromUnsignedLongLong(vmcpu->PC); diff --git a/miasm2/jitter/arch/JitCore_x86.c b/miasm2/jitter/arch/JitCore_x86.c index 5c7b9c02..a5bbb7bc 100644 --- a/miasm2/jitter/arch/JitCore_x86.c +++ b/miasm2/jitter/arch/JitCore_x86.c @@ -1,19 +1,13 @@ #include <Python.h> -#include "JitCore.h" +#include "../JitCore.h" #include "structmember.h" #include <stdint.h> #include <inttypes.h> #include "../queue.h" #include "../vm_mngr.h" +#include "../vm_mngr_py.h" #include "JitCore_x86.h" -#define RAISE(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return p;} -#define RAISE_ret0(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return 0;} - -typedef struct _reg_dict{ - char* name; - size_t offset; -} reg_dict; reg_dict gpreg_dict[] = { {.name = "RAX", .offset = offsetof(vm_cpu_t, RAX)}, @@ -57,19 +51,8 @@ reg_dict gpreg_dict[] = { {.name = "RAX", .offset = offsetof(vm_cpu_t, RAX)}, /************************** JitCpu object **************************/ -typedef struct { - PyObject_HEAD - PyObject *cpu; /* cpu */ - vm_cpu_t vmcpu; -} JitCpu; - -#define get_reg(reg) do { \ - o = PyLong_FromUnsignedLongLong((uint64_t)self->vmcpu.reg); \ - PyDict_SetItemString(dict, #reg, o); \ - Py_DECREF(o); \ - } while(0); PyObject* cpu_get_gpreg(JitCpu* self) @@ -119,13 +102,17 @@ PyObject* cpu_get_gpreg(JitCpu* self) -PyObject* _vm_set_gpreg(JitCpu* self, PyObject *dict) + +PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) { + PyObject* dict; PyObject *d_key, *d_value = NULL; Py_ssize_t pos = 0; uint64_t val; unsigned int i, found; + if (!PyArg_ParseTuple(args, "O", &dict)) + return NULL; if(!PyDict_Check(dict)) RAISE(PyExc_TypeError, "arg must be dict"); while(PyDict_Next(dict, &pos, &d_key, &d_value)){ @@ -138,7 +125,7 @@ PyObject* _vm_set_gpreg(JitCpu* self, PyObject *dict) for (i=0; i < sizeof(gpreg_dict)/sizeof(reg_dict); i++){ if (strcmp(PyString_AsString(d_key), gpreg_dict[i].name)) continue; - *((uint64_t*)(((char*)&(self->vmcpu)) + gpreg_dict[i].offset)) = val; + *((uint64_t*)(((char*)(self->cpu)) + gpreg_dict[i].offset)) = val; found = 1; break; } @@ -148,27 +135,17 @@ PyObject* _vm_set_gpreg(JitCpu* self, PyObject *dict) fprintf(stderr, "unkown key: %s\n", PyString_AsString(d_key)); RAISE(PyExc_ValueError, "unkown reg"); } - return NULL; -} - -PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) -{ - PyObject* dict; - if (!PyArg_ParseTuple(args, "O", &dict)) - return NULL; - _vm_set_gpreg(self, dict); - Py_INCREF(Py_None); - return Py_None; + Py_INCREF(Py_None); + return Py_None; } - PyObject * cpu_init_regs(JitCpu* self) { - memset(&self->vmcpu, 0, sizeof(vm_cpu_t)); + memset(self->cpu, 0, sizeof(vm_cpu_t)); - self->vmcpu.tsc1 = 0x22222222; - self->vmcpu.tsc2 = 0x11111111; - self->vmcpu.i_f = 1; + ((vm_cpu_t*)self->cpu)->tsc1 = 0x22222222; + ((vm_cpu_t*)self->cpu)->tsc2 = 0x11111111; + ((vm_cpu_t*)self->cpu)->i_f = 1; Py_INCREF(Py_None); return Py_None; @@ -193,13 +170,37 @@ PyObject * cpu_dump_gpregs(JitCpu* self, PyObject* args) { vm_cpu_t* vmcpu; - vmcpu = &self->vmcpu; + vmcpu = self->cpu; dump_gpregs(vmcpu); Py_INCREF(Py_None); return Py_None; } +PyObject* cpu_set_exception(JitCpu* self, PyObject* args) +{ + PyObject *item1; + uint64_t i; + + if (!PyArg_ParseTuple(args, "O", &item1)) + return NULL; + + PyGetInt(item1, i); + + ((vm_cpu_t*)self->cpu)->exception_flags = i; + Py_INCREF(Py_None); + return Py_None; +} + +PyObject* cpu_get_exception(JitCpu* self, PyObject* args) +{ + return PyLong_FromUnsignedLongLong((uint64_t)(((vm_cpu_t*)self->cpu)->exception_flags)); +} + + + + + PyObject* cpu_set_segm_base(JitCpu* self, PyObject* args) { PyObject *item1, *item2; @@ -210,7 +211,7 @@ PyObject* cpu_set_segm_base(JitCpu* self, PyObject* args) PyGetInt(item1, segm_num); PyGetInt(item2, segm_base); - self->vmcpu.segm_base[segm_num] = segm_base; + ((vm_cpu_t*)self->cpu)->segm_base[segm_num] = segm_base; Py_INCREF(Py_None); return Py_None; @@ -225,38 +226,16 @@ PyObject* cpu_get_segm_base(JitCpu* self, PyObject* args) if (!PyArg_ParseTuple(args, "O", &item1)) return NULL; PyGetInt(item1, segm_num); - v = PyInt_FromLong((long)self->vmcpu.segm_base[segm_num]); + v = PyInt_FromLong((long)(((vm_cpu_t*)self->cpu)->segm_base[segm_num])); return v; } -uint64_t segm2addr(vm_cpu_t* vmcpu, uint64_t segm, uint64_t addr) +uint64_t segm2addr(JitCpu* jitcpu, uint64_t segm, uint64_t addr) { - return addr + vmcpu->segm_base[segm]; + return addr + ((vm_cpu_t*)jitcpu->cpu)->segm_base[segm]; } -PyObject* cpu_set_exception(JitCpu* self, PyObject* args) -{ - PyObject *item1; - uint64_t i; - - if (!PyArg_ParseTuple(args, "O", &item1)) - return NULL; - - PyGetInt(item1, i); - - self->vmcpu.exception_flags = i; - Py_INCREF(Py_None); - return Py_None; -} - -PyObject* cpu_get_exception(JitCpu* self, PyObject* args) -{ - return PyLong_FromUnsignedLongLong((uint64_t)self->vmcpu.exception_flags); -} - - - #define UDIV(sizeA) \ uint ## sizeA ## _t udiv ## sizeA (vm_cpu_t* vmcpu, uint ## sizeA ## _t a, uint ## sizeA ## _t b) \ { \ @@ -328,33 +307,72 @@ IMOD(64) -static void -JitCpu_dealloc(JitCpu* self) +void check_automod(JitCpu* jitcpu, uint64_t addr, int size) { - self->ob_type->tp_free((PyObject*)self); + PyObject *result; + + if (!(((VmMngr*)jitcpu->pyvm)->vm_mngr.exception_flags & EXCEPT_CODE_AUTOMOD)) + return; + result = PyObject_CallMethod(jitcpu->jitter, "automod_cb", "LL", addr, size); + Py_DECREF(result); + } +void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src) +{ + vm_MEM_WRITE_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); + check_automod(jitcpu, addr, 8); +} -static PyObject * -JitCpu_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src) { - JitCpu *self; + vm_MEM_WRITE_16(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); + check_automod(jitcpu, addr, 16); +} - self = (JitCpu *)type->tp_alloc(type, 0); - return (PyObject *)self; +void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src) +{ + vm_MEM_WRITE_32(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); + check_automod(jitcpu, addr, 32); } -static PyObject * -JitCpu_get_cpu(JitCpu *self, void *closure) +void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src) { - return PyLong_FromUnsignedLongLong((uint64_t)&(self->vmcpu)); + vm_MEM_WRITE_64(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); + check_automod(jitcpu, addr, 64); } -static int -JitCpu_set_cpu(JitCpu *self, PyObject *value, void *closure) + + +PyObject* vm_set_mem(JitCpu *self, PyObject* args) { - PyErr_SetString(PyExc_TypeError, "immutable cpu"); - return -1; + PyObject *py_addr; + PyObject *py_buffer; + Py_ssize_t py_length; + + char * buffer; + uint64_t size; + uint64_t addr; + int ret = 0x1337; + + if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_buffer)) + return NULL; + + PyGetInt(py_addr, addr); + + if(!PyString_Check(py_buffer)) + RAISE(PyExc_TypeError,"arg must be str"); + + size = PyString_Size(py_buffer); + PyString_AsStringAndSize(py_buffer, &buffer, &py_length); + + ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size); + if (ret < 0) + RAISE(PyExc_TypeError,"arg must be str"); + check_automod(self, addr, size*8); + + Py_INCREF(Py_None); + return Py_None; } static PyMemberDef JitCpu_members[] = { @@ -378,12 +396,21 @@ static PyMethodDef JitCpu_methods[] = { "X"}, {"set_exception", (PyCFunction)cpu_set_exception, METH_VARARGS, "X"}, + {"set_mem", (PyCFunction)vm_set_mem, METH_VARARGS, + "X"}, + {"get_mem", (PyCFunction)vm_get_mem, METH_VARARGS, + "X"}, {NULL} /* Sentinel */ }; static int JitCpu_init(JitCpu *self, PyObject *args, PyObject *kwds) { + self->cpu = malloc(sizeof(vm_cpu_t)); + if (self->cpu == NULL) { + fprintf(stderr, "cannot alloc vm_cpu_t\n"); + exit(0); + } return 0; } @@ -391,15 +418,15 @@ JitCpu_init(JitCpu *self, PyObject *args, PyObject *kwds) #define getset_reg_E_u32(regname) \ static PyObject *JitCpu_get_E ## regname (JitCpu *self, void *closure) \ { \ - return PyLong_FromUnsignedLongLong((uint32_t)(self->vmcpu.R ## regname & 0xFFFFFFFF )); \ + return PyLong_FromUnsignedLongLong((uint32_t)(((vm_cpu_t*)(self->cpu))->R ## regname & 0xFFFFFFFF )); \ } \ static int JitCpu_set_E ## regname (JitCpu *self, PyObject *value, void *closure) \ { \ uint64_t val; \ PyGetInt_ret0(value, val); \ val &= 0xFFFFFFFF; \ - val |= self->vmcpu.R ##regname & 0xFFFFFFFF00000000ULL; \ - self->vmcpu.R ## regname = val; \ + val |= ((vm_cpu_t*)(self->cpu))->R ##regname & 0xFFFFFFFF00000000ULL; \ + ((vm_cpu_t*)(self->cpu))->R ## regname = val; \ return 0; \ } @@ -408,15 +435,15 @@ JitCpu_init(JitCpu *self, PyObject *args, PyObject *kwds) #define getset_reg_R_u16(regname) \ static PyObject *JitCpu_get_ ## regname (JitCpu *self, void *closure) \ { \ - return PyLong_FromUnsignedLongLong((uint16_t)(self->vmcpu.R ## regname & 0xFFFF )); \ + return PyLong_FromUnsignedLongLong((uint16_t)(((vm_cpu_t*)(self->cpu))->R ## regname & 0xFFFF )); \ } \ static int JitCpu_set_ ## regname (JitCpu *self, PyObject *value, void *closure) \ { \ uint64_t val; \ PyGetInt_ret0(value, val); \ val &= 0xFFFF; \ - val |= self->vmcpu.R ##regname & 0xFFFFFFFFFFFF0000ULL; \ - self->vmcpu.R ## regname = val; \ + val |= ((vm_cpu_t*)(self->cpu))->R ##regname & 0xFFFFFFFFFFFF0000ULL; \ + ((vm_cpu_t*)(self->cpu))->R ## regname = val; \ return 0; \ } @@ -479,12 +506,6 @@ getset_reg_R_u16(BP); getset_reg_R_u16(IP); -#define get_reg_off(reg) do { \ - o = PyLong_FromUnsignedLongLong((uint64_t)offsetof(vm_cpu_t, reg)); \ - PyDict_SetItemString(dict, #reg, o); \ - Py_DECREF(o); \ - } while(0); - PyObject* get_gpreg_offset_all(void) { @@ -697,11 +718,17 @@ PyObject* get_gpreg_offset_all(void) static PyGetSetDef JitCpu_getseters[] = { - {"cpu", - (getter)JitCpu_get_cpu, (setter)JitCpu_set_cpu, - "first name", + {"vmmngr", + (getter)JitCpu_get_vmmngr, (setter)JitCpu_set_vmmngr, + "vmmngr", + NULL}, + + {"jitter", + (getter)JitCpu_get_jitter, (setter)JitCpu_set_jitter, + "jitter", NULL}, + {"RAX", (getter)JitCpu_get_RAX, (setter)JitCpu_set_RAX, "RAX", NULL}, {"RBX", (getter)JitCpu_get_RBX, (setter)JitCpu_set_RBX, "RBX", NULL}, {"RCX", (getter)JitCpu_get_RCX, (setter)JitCpu_set_RCX, "RCX", NULL}, diff --git a/miasm2/jitter/arch/JitCore_x86.h b/miasm2/jitter/arch/JitCore_x86.h index 844c13c0..7e518395 100644 --- a/miasm2/jitter/arch/JitCore_x86.h +++ b/miasm2/jitter/arch/JitCore_x86.h @@ -271,8 +271,9 @@ typedef struct { + void dump_gpregs(vm_cpu_t* vmcpu); -uint64_t segm2addr(vm_cpu_t* vmcpu, uint64_t segm, uint64_t addr); +uint64_t segm2addr(JitCpu* jitcpu, uint64_t segm, uint64_t addr); uint64_t udiv64(vm_cpu_t* vmcpu, uint64_t a, uint64_t b); diff --git a/miasm2/jitter/jitcore.py b/miasm2/jitter/jitcore.py index 16f201c9..a3a91d76 100644 --- a/miasm2/jitter/jitcore.py +++ b/miasm2/jitter/jitcore.py @@ -51,6 +51,7 @@ class JitCore(object): self.blocs_mem_interval = interval() self.disasm_cb = None self.split_dis = set() + self.addr_mod = interval() self.options = {"jit_maxline": 50 # Maximum number of line jitted } @@ -160,7 +161,7 @@ class JitCore(object): """ fc_ptr = self.lbl2jitbloc[label] - return self.exec_wrapper(fc_ptr, cpu.cpu, vmmngr.vmmngr) + return self.exec_wrapper(fc_ptr, cpu) def runbloc(self, cpu, vm, lbl): """Run the bloc starting at lbl. @@ -249,13 +250,15 @@ class JitCore(object): return modified_blocs - def updt_automod_code(self, vm, addr, size): - """Remove code jitted in range [addr, addr + size] + def updt_automod_code(self, vm): + """Remove code jitted in range self.addr_mod @vm: VmMngr instance - @addr: Address of modified code in sandbox - @size: Modification range size (in bits) """ - - self.del_bloc_in_range(addr, addr + size / 8) + for addr_start, addr_stop in self.addr_mod: + self.del_bloc_in_range(addr_start, addr_stop + 1) self.__updt_jitcode_mem_range(vm) + self.addr_mod = interval() + def automod_cb(self, addr=0, size=0): + self.addr_mod += interval([(addr, addr + size / 8 - 1)]) + return None diff --git a/miasm2/jitter/jitcore_python.py b/miasm2/jitter/jitcore_python.py index 0df9f615..150e3906 100644 --- a/miasm2/jitter/jitcore_python.py +++ b/miasm2/jitter/jitcore_python.py @@ -71,7 +71,7 @@ class JitCore_Python(jitcore.JitCore): addr = expr_mem.arg.arg.arg size = expr_mem.size / 8 - value = self.vmmngr.get_mem(addr, size) + value = self.cpu.get_mem(addr, size) return m2_expr.ExprInt_fromsize(expr_mem.size, int(value[::-1].encode("hex"), 16)) @@ -97,7 +97,7 @@ class JitCore_Python(jitcore.JitCore): content = content.decode("hex")[::-1] # Write in VmMngr context - self.vmmngr.set_mem(addr, content) + self.cpu.set_mem(addr, content) def jitirblocs(self, label, irblocs): """Create a python function corresponding to an irblocs' group. @@ -193,8 +193,7 @@ class JitCore_Python(jitcore.JitCore): # Get Python function corresponding to @label fc_ptr = self.lbl2jitbloc[label] - # Update memory state - self.vmmngr = vmmngr + self.cpu = cpu # Execute the function return fc_ptr(cpu, vmmngr) diff --git a/miasm2/jitter/jitcore_tcc.py b/miasm2/jitter/jitcore_tcc.py index 2f8ad23b..573572d8 100644 --- a/miasm2/jitter/jitcore_tcc.py +++ b/miasm2/jitter/jitcore_tcc.py @@ -30,7 +30,8 @@ def gen_core(arch, attrib): txt = "" txt += '#include "%s/queue.h"\n' % lib_dir txt += '#include "%s/vm_mngr.h"\n' % lib_dir - txt += '#include "%s/arch/JitCore.h"\n' % lib_dir + txt += '#include "%s/vm_mngr_py.h"\n' % lib_dir + txt += '#include "%s/JitCore.h"\n' % lib_dir txt += '#include "%s/arch/JitCore_%s.h"\n' % (lib_dir, arch.name) txt += r''' @@ -137,7 +138,7 @@ class JitCore_Tcc(jitcore.JitCore): def jitirblocs(self, label, irblocs): f_name = "bloc_%s" % label.name - f_declaration = 'void %s(block_id * BlockDst, vm_cpu_t* vmcpu, vm_mngr_t* vm_mngr)' % f_name + f_declaration = 'void %s(block_id * BlockDst, JitCpu* jitcpu)' % f_name out = irblocs2C(self.ir_arch, self.resolver, label, irblocs, gen_exception_code=True, log_mn=self.log_mn, diff --git a/miasm2/jitter/jitload.py b/miasm2/jitter/jitload.py index 97fd3c80..6faa3a9f 100644 --- a/miasm2/jitter/jitload.py +++ b/miasm2/jitter/jitload.py @@ -217,9 +217,12 @@ class jitter: self.vm.set_addr2obj(self.jit.addr2obj) self.jit.load() + self.cpu.vmmngr = self.vm + self.cpu.jitter = self.jit self.stack_size = 0x10000 self.stack_base = 0x1230000 + # Init callback handler self.breakpoints_handler = CallbackHandler() self.exceptions_handler = CallbackHandlerBitflag() @@ -231,10 +234,8 @@ class jitter: def exception_automod(jitter): "Tell the JiT backend to update blocs modified" - addr = self.vm.get_last_write_ad() - size = self.vm.get_last_write_size() - self.jit.updt_automod_code(self.vm, addr, size) + self.jit.updt_automod_code(jitter.vm) self.vm.set_exception(0) return True diff --git a/miasm2/jitter/vm_mngr.c b/miasm2/jitter/vm_mngr.c index f74830fd..ec7fa01c 100644 --- a/miasm2/jitter/vm_mngr.c +++ b/miasm2/jitter/vm_mngr.c @@ -395,13 +395,7 @@ void dump_code_bloc(vm_mngr_t* vm_mngr) void check_write_code_bloc(vm_mngr_t* vm_mngr, uint64_t my_size, uint64_t addr) { struct code_bloc_node * cbp; - vm_mngr->last_write_ad = addr; - vm_mngr->last_write_size = my_size; - - - //if(vmmngr.my_tick> my_tick) - // printf("M_WRITE %2d %.8X %.8X\n", my_size, addr, src); if (!(addr + my_size/8 <= vm_mngr->code_bloc_pool_ad_min || addr >=vm_mngr->code_bloc_pool_ad_max)){ LIST_FOREACH(cbp, &vm_mngr->code_bloc_pool, next){ @@ -444,99 +438,114 @@ PyObject* addr2BlocObj(vm_mngr_t* vm_mngr, uint64_t addr) return b; } -/* -PyObject* add_code_resolver(vm_mngr_t* vm_mngr, uint64_t addr) -{ - pyaddr = PyLong_FromUnsignedLongLong(addr); - func_resolver* f = malloc(sizeof(func_resolver)); - f->func = addr2blocobj; - fsdfsd - return f; -} -*/ -/* -void MEM_WRITE(vm_mngr_t* vm_mngr, unsigned int my_size, uint64_t addr, unsigned int src) -{ - struct code_bloc_node * cbp; - - vm_mngr->last_write_ad = addr; - vm_mngr->last_write_size = my_size; - - //if(vmmngr.my_tick> my_tick) - // printf("M_WRITE %2d %.8X %.8X\n", my_size, addr, src); - if (!(addr + my_size/8 <= vm_mngr->code_bloc_pool_ad_min || - addr >= vm_mngr->code_bloc_pool_ad_max)){ - LIST_FOREACH(cbp, &vm_mngr->code_bloc_pool, next){ - if ((cbp->ad_start <= addr + my_size/8) && - (addr < cbp->ad_stop)){ -#ifdef DEBUG_MIASM_AUTOMOD_CODE - fprintf(stderr, "self modifying code %"PRIX64" %.8X\n", - addr, my_size); -#endif - vm_mngr->exception_flags |= EXCEPT_CODE_AUTOMOD; - break; - } - } - } - - memory_page_write(vm_mngr, my_size, addr, src); -} -*/ -void MEM_WRITE_08(vm_mngr_t* vm_mngr, uint64_t addr, unsigned char src) +void vm_MEM_WRITE_08(vm_mngr_t* vm_mngr, uint64_t addr, unsigned char src) { check_write_code_bloc(vm_mngr, 8, addr); memory_page_write(vm_mngr, 8, addr, src); } -void MEM_WRITE_16(vm_mngr_t* vm_mngr, uint64_t addr, unsigned short src) +void vm_MEM_WRITE_16(vm_mngr_t* vm_mngr, uint64_t addr, unsigned short src) { check_write_code_bloc(vm_mngr, 16, addr); memory_page_write(vm_mngr, 16, addr, src); } -void MEM_WRITE_32(vm_mngr_t* vm_mngr, uint64_t addr, unsigned int src) +void vm_MEM_WRITE_32(vm_mngr_t* vm_mngr, uint64_t addr, unsigned int src) { check_write_code_bloc(vm_mngr, 32, addr); memory_page_write(vm_mngr, 32, addr, src); } -void MEM_WRITE_64(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t src) +void vm_MEM_WRITE_64(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t src) { check_write_code_bloc(vm_mngr, 64, addr); memory_page_write(vm_mngr, 64, addr, src); } -unsigned int MEM_LOOKUP(vm_mngr_t* vm_mngr, unsigned int my_size, uint64_t addr) -{ - unsigned int ret; - ret = memory_page_read(vm_mngr, my_size, addr); - return ret; -} - -unsigned char MEM_LOOKUP_08(vm_mngr_t* vm_mngr, uint64_t addr) +unsigned char vm_MEM_LOOKUP_08(vm_mngr_t* vm_mngr, uint64_t addr) { unsigned char ret; ret = memory_page_read(vm_mngr, 8, addr); return ret; } -unsigned short MEM_LOOKUP_16(vm_mngr_t* vm_mngr, uint64_t addr) +unsigned short vm_MEM_LOOKUP_16(vm_mngr_t* vm_mngr, uint64_t addr) { unsigned short ret; ret = memory_page_read(vm_mngr, 16, addr); return ret; } -unsigned int MEM_LOOKUP_32(vm_mngr_t* vm_mngr, uint64_t addr) +unsigned int vm_MEM_LOOKUP_32(vm_mngr_t* vm_mngr, uint64_t addr) { unsigned int ret; ret = memory_page_read(vm_mngr, 32, addr); return ret; } -uint64_t MEM_LOOKUP_64(vm_mngr_t* vm_mngr, uint64_t addr) +uint64_t vm_MEM_LOOKUP_64(vm_mngr_t* vm_mngr, uint64_t addr) { uint64_t ret; ret = memory_page_read(vm_mngr, 64, addr); return ret; } + +int vm_read_mem(vm_mngr_t* vm_mngr, uint64_t addr, char** buffer_ptr, uint64_t size) +{ + char* buffer; + uint64_t len; + struct memory_page_node * mpn; + + buffer = malloc(size); + *buffer_ptr = buffer; + if (!buffer){ + fprintf(stderr, "cannot alloc read\n"); + exit(-1); + } + + /* read is multiple page wide */ + while (size){ + mpn = get_memory_page_from_address(vm_mngr, addr); + if (!mpn){ + free(*buffer_ptr); + PyErr_SetString(PyExc_RuntimeError, "cannot find address"); + return -1; + } + + len = MIN(size, mpn->size - (addr - mpn->ad)); + memcpy(buffer, (char*)(mpn->ad_hp + (addr - mpn->ad)), len); + buffer += len; + addr += len; + size -= len; + } + + return 0; +} + +int vm_write_mem(vm_mngr_t* vm_mngr, uint64_t addr, char *buffer, uint64_t size) +{ + uint64_t len; + struct memory_page_node * mpn; + + check_write_code_bloc(vm_mngr, size * 8, addr); + + /* write is multiple page wide */ + while (size){ + mpn = get_memory_page_from_address(vm_mngr, addr); + if (!mpn){ + PyErr_SetString(PyExc_RuntimeError, "cannot find address"); + return -1; + } + + len = MIN(size, mpn->size - (addr - mpn->ad)); + memcpy(mpn->ad_hp + (addr-mpn->ad), buffer, len); + buffer += len; + addr += len; + size -= len; + } + + return 0; +} + + + unsigned int parity(unsigned int a) { #if defined(__builtin_parity) diff --git a/miasm2/jitter/vm_mngr.h b/miasm2/jitter/vm_mngr.h index e365bcee..72c64319 100644 --- a/miasm2/jitter/vm_mngr.h +++ b/miasm2/jitter/vm_mngr.h @@ -79,9 +79,6 @@ typedef struct { uint64_t exception_flags; uint64_t exception_flags_new; - uint64_t last_write_ad; - uint64_t last_write_size ; - PyObject *cb_automod; PyObject *addr2obj; }vm_mngr_t; @@ -150,20 +147,19 @@ struct memory_breakpoint_info { int is_mem_mapped(vm_mngr_t* vm_mngr, uint64_t ad); uint64_t get_mem_base_addr(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t *addr_base); -void MEM_WRITE(vm_mngr_t* vm_mngr, unsigned int my_size, uint64_t addr, unsigned int src); unsigned int MEM_LOOKUP(vm_mngr_t* vm_mngr, unsigned int my_size, uint64_t addr); -void MEM_WRITE_08(vm_mngr_t* vm_mngr, uint64_t addr, unsigned char src); -void MEM_WRITE_16(vm_mngr_t* vm_mngr, uint64_t addr, unsigned short src); -void MEM_WRITE_32(vm_mngr_t* vm_mngr, uint64_t addr, unsigned int src); -void MEM_WRITE_64(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t src); +void vm_MEM_WRITE_08(vm_mngr_t* vm_mngr, uint64_t addr, unsigned char src); +void vm_MEM_WRITE_16(vm_mngr_t* vm_mngr, uint64_t addr, unsigned short src); +void vm_MEM_WRITE_32(vm_mngr_t* vm_mngr, uint64_t addr, unsigned int src); +void vm_MEM_WRITE_64(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t src); -unsigned char MEM_LOOKUP_08(vm_mngr_t* vm_mngr, uint64_t addr); -unsigned short MEM_LOOKUP_16(vm_mngr_t* vm_mngr, uint64_t addr); -unsigned int MEM_LOOKUP_32(vm_mngr_t* vm_mngr, uint64_t addr); -uint64_t MEM_LOOKUP_64(vm_mngr_t* vm_mngr, uint64_t addr); +unsigned char vm_MEM_LOOKUP_08(vm_mngr_t* vm_mngr, uint64_t addr); +unsigned short vm_MEM_LOOKUP_16(vm_mngr_t* vm_mngr, uint64_t addr); +unsigned int vm_MEM_LOOKUP_32(vm_mngr_t* vm_mngr, uint64_t addr); +uint64_t vm_MEM_LOOKUP_64(vm_mngr_t* vm_mngr, uint64_t addr); void MEM_WRITE_08_PASSTHROUGH(uint64_t addr, unsigned char src); @@ -175,6 +171,9 @@ unsigned short MEM_LOOKUP_16_PASSTHROUGH(uint64_t addr); unsigned int MEM_LOOKUP_32_PASSTHROUGH(uint64_t addr); uint64_t MEM_LOOKUP_64_PASSTHROUGH(uint64_t addr); +int vm_read_mem(vm_mngr_t* vm_mngr, uint64_t addr, char** buffer_ptr, uint64_t size); +int vm_write_mem(vm_mngr_t* vm_mngr, uint64_t addr, char *buffer, uint64_t size); + unsigned int parity(unsigned int a); unsigned int my_imul08(unsigned int a, unsigned int b); diff --git a/miasm2/jitter/vm_mngr_py.c b/miasm2/jitter/vm_mngr_py.c index 952e620f..78d636f6 100644 --- a/miasm2/jitter/vm_mngr_py.c +++ b/miasm2/jitter/vm_mngr_py.c @@ -22,6 +22,7 @@ #include <signal.h> #include "queue.h" #include "vm_mngr.h" +#include "vm_mngr_py.h" #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) @@ -33,12 +34,6 @@ extern struct code_bloc_list_head code_bloc_pool; -typedef struct { - PyObject_HEAD - PyObject *vmmngr; - vm_mngr_t vm_mngr; -} VmMngr; - /* XXX POC signals */ VmMngr* global_vmmngr; @@ -172,49 +167,6 @@ PyObject* vm_add_memory_page(VmMngr* self, PyObject* args) - -PyObject* vm_set_mem(VmMngr* self, PyObject* args) -{ - PyObject *addr; - PyObject *item_str; - - uint64_t buf_size; - char* buf_data; - Py_ssize_t length; - int ret = 0x1337; - uint64_t val; - uint64_t l; - struct memory_page_node * mpn; - - if (!PyArg_ParseTuple(args, "OO", &addr, &item_str)) - return NULL; - - PyGetInt(addr, val); - - if(!PyString_Check(item_str)) - RAISE(PyExc_TypeError,"arg must be str"); - - buf_size = PyString_Size(item_str); - PyString_AsStringAndSize(item_str, &buf_data, &length); - - - check_write_code_bloc(&self->vm_mngr, buf_size*8, val); - /* write is multiple page wide */ - while (buf_size){ - mpn = get_memory_page_from_address(&self->vm_mngr, val); - if (!mpn){ - PyErr_SetString(PyExc_RuntimeError, "cannot find address"); - return 0; - } - l = MIN(buf_size, mpn->size - (val-mpn->ad)); - memcpy(mpn->ad_hp + (val-mpn->ad), buf_data, l); - buf_data += l; - val += l; - buf_size -= l; - } - return PyLong_FromUnsignedLongLong((uint64_t)ret); -} - PyObject* vm_set_mem_access(VmMngr* self, PyObject* args) { PyObject *addr; @@ -241,64 +193,70 @@ PyObject* vm_set_mem_access(VmMngr* self, PyObject* args) return PyLong_FromUnsignedLongLong((uint64_t)ret); } +PyObject* vm_set_mem(VmMngr* self, PyObject* args) +{ + PyObject *py_addr; + PyObject *py_buffer; + Py_ssize_t py_length; + + char * buffer; + uint64_t size; + uint64_t addr; + int ret = 0x1337; + + if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_buffer)) + return NULL; + + PyGetInt(py_addr, addr); + + if(!PyString_Check(py_buffer)) + RAISE(PyExc_TypeError,"arg must be str"); + + size = PyString_Size(py_buffer); + PyString_AsStringAndSize(py_buffer, &buffer, &py_length); + + ret = vm_write_mem(&self->vm_mngr, addr, buffer, size); + if (ret < 0) + RAISE(PyExc_TypeError,"arg must be str"); + + check_write_code_bloc(&self->vm_mngr, size*8, addr); + + Py_INCREF(Py_None); + return Py_None; +} + PyObject* vm_get_mem(VmMngr* self, PyObject* args) { - PyObject *item; - PyObject *item_len; + PyObject *py_addr; + PyObject *py_len; - uint64_t buf_addr; - uint64_t buf_len; - PyObject *obj_out; - struct memory_page_node * mpn; - char * buf_out; - char * addr_tmp; - char * addr_out; - uint64_t off; - uint64_t l; - uint64_t my_size; - - if (!PyArg_ParseTuple(args, "OO", &item, &item_len)) - return NULL; + uint64_t addr; + uint64_t size; + PyObject *obj_out; + char * buf_out; + int ret; - PyGetInt(item, buf_addr); - PyGetInt(item_len, buf_len); + if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_len)) + return NULL; - my_size = buf_len; - buf_out = malloc(buf_len); - if (!buf_out){ - fprintf(stderr, "cannot alloc read\n"); - exit(-1); - } + PyGetInt(py_addr, addr); + PyGetInt(py_len, size); - addr_out = buf_out; - - /* read is multiple page wide */ - while (my_size){ - mpn = get_memory_page_from_address(&self->vm_mngr, buf_addr); - if (!mpn){ - free(buf_out); - PyErr_SetString(PyExc_RuntimeError, "cannot find address"); - return 0; - } - - off = buf_addr - mpn->ad; - addr_tmp = &((char*)mpn->ad_hp)[off]; - - l = MIN(my_size, mpn->size - off); - memcpy(addr_out, addr_tmp, l); - my_size -= l; - addr_out +=l; - buf_addr +=l; - } + ret = vm_read_mem(&self->vm_mngr, addr, &buf_out, size); + if (ret < 0) { + PyErr_SetString(PyExc_RuntimeError, "cannot find address"); + return NULL; + } - obj_out = PyString_FromStringAndSize(buf_out, buf_len); - free(buf_out); - return obj_out; + obj_out = PyString_FromStringAndSize(buf_out, size); + free(buf_out); + return obj_out; } + PyObject* vm_add_memory_breakpoint(VmMngr* self, PyObject* args) { PyObject *ad; @@ -341,16 +299,6 @@ PyObject* vm_remove_memory_breakpoint(VmMngr* self, PyObject* args) } -PyObject* vm_get_last_write_ad(VmMngr* self, PyObject* args) -{ - return PyInt_FromLong((uint64_t)self->vm_mngr.last_write_ad); -} - -PyObject* vm_get_last_write_size(VmMngr* self, PyObject* args) -{ - return PyLong_FromUnsignedLongLong((uint64_t)self->vm_mngr.last_write_size); -} - PyObject* vm_set_exception(VmMngr* self, PyObject* args) { PyObject *item1; @@ -477,60 +425,6 @@ PyObject* vm_reset_code_bloc_pool(VmMngr* self, PyObject* args) } - - - - -PyObject* vm_call_pyfunc_from_globals(VmMngr* self, PyObject* args) -{ - char* funcname; - PyObject *mod, *func, *rslt, *globals, *func_globals; - - - if (!PyArg_ParseTuple(args, "s", &funcname)) - return NULL; - - - fprintf(stderr, "getting pyfunc %s\n", funcname); - mod = PyEval_GetBuiltins(); - - if (!mod) { - fprintf(stderr, "cannot find module\n"); - exit(0); - } - - func_globals = PyDict_GetItemString(mod, "globals"); - if (!func_globals) { - fprintf(stderr, "cannot find function globals\n"); - exit(0); - } - - if (!PyCallable_Check (func_globals)) { - fprintf(stderr, "function not callable\n"); - exit(0); - } - - globals = PyObject_CallObject (func_globals, NULL); - if (!globals) { - fprintf(stderr, "cannot get globals\n"); - exit(0); - } - - func = PyDict_GetItemString (globals, funcname); - if (!func) { - fprintf(stderr, "cannot find function %s\n", funcname); - exit(0); - } - - if (!PyCallable_Check (func)) { - fprintf(stderr, "function not callable\n"); - exit(0); - } - - rslt = PyObject_CallObject (func, NULL); - return rslt; -} - PyObject* vm_add_code_bloc(VmMngr *self, PyObject *args) { PyObject *item1; @@ -563,138 +457,6 @@ PyObject* vm_dump_code_bloc_pool(VmMngr* self) } -PyObject* vm_exec_blocs(VmMngr* self, PyObject* args) -{ - PyObject* my_eip; - PyObject* b; - PyObject* module; - PyObject* func; - PyObject* meip; - uint64_t tmp; - - PyObject* known_blocs; - PyObject* e; - - if (!PyArg_ParseTuple(args, "OO", &my_eip, &known_blocs)) - return NULL; - - if(!PyDict_Check(known_blocs)) - RAISE(PyExc_TypeError, "arg must be dict"); - - PyGetInt(my_eip, tmp); - meip = PyLong_FromUnsignedLongLong((uint64_t)tmp); - while (1){ - b = PyDict_GetItem(known_blocs, meip); - if (b == NULL) - return meip; - - module = PyObject_GetAttrString(b, "module_c"); - if (module == NULL){ - fprintf(stderr, "assert eip module_c in pyobject\n"); - exit(0); - } - func = PyObject_GetAttrString(module, "func"); - if (func == NULL){ - fprintf(stderr, "assert func module_c in pyobject\n"); - exit(0); - } - - Py_DECREF(module); - if (!PyCallable_Check (func)) { - fprintf(stderr, "function not callable\n"); - exit(0); - } - Py_DECREF(meip); - //printf("exec bloc %"PRIX64"\n", tmp); - meip = PyObject_CallObject (func, NULL); - - Py_DECREF(func); - e = PyErr_Occurred (); - if (e){ - fprintf(stderr, "exception\n"); - return meip; - } - - if (self->vm_mngr.exception_flags) - return meip; - - } -} - - - -PyObject* vm_exec_bloc(PyObject* self, PyObject* args) -{ - PyObject* b; - PyObject* module; - PyObject* func; - PyObject* meip; - uint64_t tmp; - - PyObject* my_eip; - PyObject* known_blocs; - PyObject* e; - - if (!PyArg_ParseTuple(args, "OO", &my_eip, &known_blocs)) - return NULL; - - - if (PyInt_Check(my_eip)){ - tmp = (uint64_t)PyInt_AsLong(my_eip); - } - else if (PyLong_Check(my_eip)){ - tmp = (uint64_t)PyLong_AsUnsignedLongLong(my_eip); - } - else{ - RAISE(PyExc_TypeError,"arg1 must be int"); - } - - meip = PyInt_FromLong((long)tmp); - b = PyDict_GetItem(known_blocs, my_eip); - if (b == NULL) - return meip; - module = PyObject_GetAttrString(b, "module_c"); - if (module == NULL) - return meip; - func = PyObject_GetAttrString(module, "func"); - if (func == NULL) - return meip; - Py_DECREF(module); - if (!PyCallable_Check (func)) { - fprintf(stderr, "function not callable\n"); - exit(0); - } - Py_DECREF(meip); - meip = PyObject_CallObject (func, NULL); - - Py_DECREF(func); - e = PyErr_Occurred (); - if (e){ - fprintf(stderr, "exception\n"); - return meip; - } - - return meip; -} - - -PyObject* vm_set_automod_cb(VmMngr* self, PyObject* args) -{ - PyObject* cb_automod; - - if (!PyArg_ParseTuple(args, "O", &cb_automod)) - return NULL; - - if (self->vm_mngr.cb_automod != NULL){ - Py_DECREF(self->vm_mngr.cb_automod); - } - - Py_INCREF(cb_automod); - self->vm_mngr.cb_automod = cb_automod; - Py_INCREF(Py_None); - return Py_None; -} - PyObject* vm_set_addr2obj(VmMngr* self, PyObject* args) { PyObject* addr2obj; @@ -738,7 +500,7 @@ PyObject* add_jitbloc(VmMngr* self, PyObject* args) if (!PyArg_ParseTuple(args, "O", &addr2obj)) return NULL; - + Py_INCREF(Py_None); return Py_None; @@ -795,16 +557,10 @@ static PyMethodDef VmMngr_methods[] = { "X"}, {"set_mem", (PyCFunction)vm_set_mem, METH_VARARGS, "X"}, - {"set_automod_cb", (PyCFunction)vm_set_automod_cb, METH_VARARGS, - "X"}, {"set_addr2obj", (PyCFunction)vm_set_addr2obj, METH_VARARGS, "X"}, {"add_code_bloc",(PyCFunction)vm_add_code_bloc, METH_VARARGS, "X"}, - {"exec_bloc",(PyCFunction)vm_exec_bloc, METH_VARARGS, - "X"}, - {"exec_blocs",(PyCFunction)vm_exec_blocs, METH_VARARGS, - "X"}, {"get_mem", (PyCFunction)vm_get_mem, METH_VARARGS, "X"}, {"add_memory_page",(PyCFunction)vm_add_memory_page, METH_VARARGS, @@ -829,17 +585,10 @@ static PyMethodDef VmMngr_methods[] = { "X"}, {"set_alarm", (PyCFunction)set_alarm, METH_VARARGS, "X"}, - {"call_pyfunc_from_globals",(PyCFunction)vm_call_pyfunc_from_globals, METH_VARARGS, - "X"}, - {"get_exception",(PyCFunction)vm_get_exception, METH_VARARGS, "X"}, {"get_exception",(PyCFunction)vm_get_exception, METH_VARARGS, "X"}, - {"get_last_write_ad", (PyCFunction)vm_get_last_write_ad, METH_VARARGS, - "X"}, - {"get_last_write_size",(PyCFunction)vm_get_last_write_size, METH_VARARGS, - "X"}, {"set_big_endian",(PyCFunction)vm_set_big_endian, METH_VARARGS, "X"}, diff --git a/miasm2/jitter/vm_mngr_py.h b/miasm2/jitter/vm_mngr_py.h new file mode 100644 index 00000000..3c7c487b --- /dev/null +++ b/miasm2/jitter/vm_mngr_py.h @@ -0,0 +1,13 @@ +#ifndef VM_MNGR_PY_H +#define VM_MNGR_PY_H + + + +typedef struct { + PyObject_HEAD + PyObject *vmmngr; + vm_mngr_t vm_mngr; +} VmMngr; + + +#endif// VM_MNGR_PY_H diff --git a/setup.py b/setup.py index 8c2b100a..f4618abc 100755 --- a/setup.py +++ b/setup.py @@ -28,16 +28,20 @@ def buil_all(): ["miasm2/jitter/vm_mngr.c", "miasm2/jitter/vm_mngr_py.c"]), Extension("miasm2.jitter.arch.JitCore_x86", - ["miasm2/jitter/arch/JitCore.c", + ["miasm2/jitter/JitCore.c", + "miasm2/jitter/vm_mngr.c", "miasm2/jitter/arch/JitCore_x86.c"]), Extension("miasm2.jitter.arch.JitCore_arm", - ["miasm2/jitter/arch/JitCore.c", + ["miasm2/jitter/JitCore.c", + "miasm2/jitter/vm_mngr.c", "miasm2/jitter/arch/JitCore_arm.c"]), Extension("miasm2.jitter.arch.JitCore_msp430", - ["miasm2/jitter/arch/JitCore.c", + ["miasm2/jitter/JitCore.c", + "miasm2/jitter/vm_mngr.c", "miasm2/jitter/arch/JitCore_msp430.c"]), Extension("miasm2.jitter.arch.JitCore_mips32", - ["miasm2/jitter/arch/JitCore.c", + ["miasm2/jitter/JitCore.c", + "miasm2/jitter/vm_mngr.c", "miasm2/jitter/arch/JitCore_mips32.c"]), Extension("miasm2.jitter.Jitllvm", ["miasm2/jitter/Jitllvm.c"]), @@ -48,16 +52,20 @@ def buil_all(): ["miasm2/jitter/vm_mngr.c", "miasm2/jitter/vm_mngr_py.c"]), Extension("miasm2.jitter.arch.JitCore_x86", - ["miasm2/jitter/arch/JitCore.c", + ["miasm2/jitter/JitCore.c", + "miasm2/jitter/vm_mngr.c", "miasm2/jitter/arch/JitCore_x86.c"]), Extension("miasm2.jitter.arch.JitCore_arm", - ["miasm2/jitter/arch/JitCore.c", + ["miasm2/jitter/JitCore.c", + "miasm2/jitter/vm_mngr.c", "miasm2/jitter/arch/JitCore_arm.c"]), Extension("miasm2.jitter.arch.JitCore_msp430", - ["miasm2/jitter/arch/JitCore.c", + ["miasm2/jitter/JitCore.c", + "miasm2/jitter/vm_mngr.c", "miasm2/jitter/arch/JitCore_msp430.c"]), Extension("miasm2.jitter.arch.JitCore_mips32", - ["miasm2/jitter/arch/JitCore.c", + ["miasm2/jitter/JitCore.c", + "miasm2/jitter/vm_mngr.c", "miasm2/jitter/arch/JitCore_mips32.c"]), Extension("miasm2.jitter.Jitllvm", ["miasm2/jitter/Jitllvm.c"]), diff --git a/test/ir/ir2C.py b/test/ir/ir2C.py index 48518c50..3a89b328 100644 --- a/test/ir/ir2C.py +++ b/test/ir/ir2C.py @@ -46,9 +46,9 @@ class TestIrIr2C(unittest.TestCase): self.translationTest( ExprOp('fadd', *args[:2]), r'fadd(0x0, 0x1)') self.translationTest( - ExprOp('segm', *args[:2]), r'segm2addr(vmcpu, 0x0, 0x1)') + ExprOp('segm', *args[:2]), r'segm2addr(jitcpu, 0x0, 0x1)') self.translationTest( - ExprOp('imod', *args[:2]), r'imod32(vmcpu, 0x0, 0x1)') + ExprOp('imod', *args[:2]), r'imod32(jitcpu, 0x0, 0x1)') self.translationTest( ExprOp('bcdadd', *args[:2]), r'bcdadd_32(0x0, 0x1)') self.assertRaises(NotImplementedError, translator.from_expr, diff --git a/test/test_all.py b/test/test_all.py index 9abbe85b..aefd0196 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -196,7 +196,7 @@ class ExampleShellcode(ExampleAssembler): testset += ExampleShellcode(['x86_32', 'x86_32_manip_ptr.S', "demo_x86_32.bin"]) test_box = {} -test_box_names = ["mod", "mod_self", "repmod", "simple", "enc", "pop_esp"] +test_box_names = ["mod", "mod_self", "repmod", "simple", "enc", "pop_esp", "automod"] for source in test_box_names: sample_base = "x86_32_" + source args = ["x86_32", sample_base + ".S", sample_base + ".bin", "--PE"] |