diff options
| author | Camille Mougey <commial@gmail.com> | 2016-09-01 11:09:21 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-09-01 11:09:21 +0200 |
| commit | 9f135c02e9bce299a700fa0191388542d141ea22 (patch) | |
| tree | d8ad86407e24ae9435ca4ca344ae7ec61e8568d2 /miasm2/jitter/vm_mngr.c | |
| parent | fb7501f4bb0bc77a0262ad4894732e4de6ccb2b2 (diff) | |
| parent | 2858e916f35f0469baeea23632ddd8befdd7ca5d (diff) | |
| download | miasm-9f135c02e9bce299a700fa0191388542d141ea22.tar.gz miasm-9f135c02e9bce299a700fa0191388542d141ea22.zip | |
Merge pull request #411 from serpilliere/fix_memory_breakpoint
Fix memory breakpoint
Diffstat (limited to 'miasm2/jitter/vm_mngr.c')
| -rw-r--r-- | miasm2/jitter/vm_mngr.c | 220 |
1 files changed, 141 insertions, 79 deletions
diff --git a/miasm2/jitter/vm_mngr.c b/miasm2/jitter/vm_mngr.c index 2b0ae1fd..df8326d9 100644 --- a/miasm2/jitter/vm_mngr.c +++ b/miasm2/jitter/vm_mngr.c @@ -76,7 +76,38 @@ const uint8_t parity_table[256] = { 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, }; -//#define DEBUG_MIASM_AUTOMOD_CODE +// #define DEBUG_MIASM_AUTOMOD_CODE + +void memory_access_list_init(struct memory_access_list * access) +{ + access->array = NULL; + access->allocated = 0; + access->num = 0; +} + +void memory_access_list_reset(struct memory_access_list * access) +{ + if (access->array) { + free(access->array); + access->array = NULL; + } + access->allocated = 0; + access->num = 0; +} + +void memory_access_list_add(struct memory_access_list * access, uint64_t start, uint64_t stop) +{ + if (access->num >= access->allocated) { + if (access->allocated == 0) + access->allocated = 1; + else + access->allocated *= 2; + access->array = realloc(access->array, access->allocated * sizeof(struct memory_access)); + } + access->array[access->num].start = start; + access->array[access->num].stop = stop; + access->num += 1; +} @@ -393,67 +424,56 @@ void dump_code_bloc(vm_mngr_t* vm_mngr) } -void code_bloc_add_write(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t size) +void add_range_to_list(struct memory_access_list * access, uint64_t addr1, uint64_t addr2) { - PyObject* range; - PyObject* element; - int list_size; - uint64_t addr_start, addr_stop; - - list_size = PyList_Size(vm_mngr->code_bloc_memory_w); - - if (list_size > 0) { - /* check match on upper bound */ - element = PyList_GetItem(vm_mngr->code_bloc_memory_w, list_size - 1); - - addr_start = (uint64_t)PyLong_AsUnsignedLongLong(PyTuple_GetItem(element, 0)); - addr_stop = (uint64_t)PyLong_AsUnsignedLongLong(PyTuple_GetItem(element, 1)); - - if (addr_stop == addr) { - range = PyTuple_New(2); - PyTuple_SetItem(range, 0, PyLong_FromUnsignedLongLong((uint64_t)addr_start)); - PyTuple_SetItem(range, 1, PyLong_FromUnsignedLongLong((uint64_t)addr+size)); - PyList_SetItem(vm_mngr->code_bloc_memory_w, list_size - 1, range); + if (access->num > 0) { + /* Check match on upper bound */ + if (access->array[access->num-1].stop == addr1) { + access->array[access->num-1].stop = addr2; return; - } - /* check match on lower bound */ - element = PyList_GetItem(vm_mngr->code_bloc_memory_w, 0); - addr_start = (uint64_t)PyLong_AsUnsignedLongLong(PyTuple_GetItem(element, 0)); - - if (addr_start == addr + size) { - range = PyTuple_New(2); - PyTuple_SetItem(range, 0, PyLong_FromUnsignedLongLong((uint64_t)addr)); - PyTuple_SetItem(range, 1, PyLong_FromUnsignedLongLong((uint64_t)addr_start)); - PyList_SetItem(vm_mngr->code_bloc_memory_w, 0, range); + /* Check match on lower bound */ + if (access->array[0].start == addr2) { + access->array[0].start = addr1; return; } - } - range = PyTuple_New(2); - PyTuple_SetItem(range, 0, PyLong_FromUnsignedLongLong((uint64_t)addr)); - PyTuple_SetItem(range, 1, PyLong_FromUnsignedLongLong((uint64_t)addr+size)); - PyList_Append(vm_mngr->code_bloc_memory_w, range); + /* No merge, add to the list */ + memory_access_list_add(access, addr1, addr2); } -void check_write_code_bloc(vm_mngr_t* vm_mngr, uint64_t my_size, uint64_t addr) + +void add_mem_read(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t size) { - struct code_bloc_node * cbp; + add_range_to_list(&(vm_mngr->memory_r), addr, addr + size); +} - if (vm_mngr->exception_flags & EXCEPT_CODE_AUTOMOD) - return; +void add_mem_write(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t size) +{ + add_range_to_list(&(vm_mngr->memory_w), addr, addr + size); +} + +void check_invalid_code_blocs(vm_mngr_t* vm_mngr) +{ + int i; + struct code_bloc_node * cbp; + for (i=0;i<vm_mngr->memory_w.num; i++) { + if (vm_mngr->exception_flags & EXCEPT_CODE_AUTOMOD) + break; + if (vm_mngr->memory_w.array[i].stop <= vm_mngr->code_bloc_pool_ad_min || + vm_mngr->memory_w.array[i].start >=vm_mngr->code_bloc_pool_ad_max) + continue; - 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)){ + if ((cbp->ad_start < vm_mngr->memory_w.array[i].stop) && + (vm_mngr->memory_w.array[i].start < cbp->ad_stop)){ #ifdef DEBUG_MIASM_AUTOMOD_CODE fprintf(stderr, "**********************************\n"); fprintf(stderr, "self modifying code %"PRIX64" %"PRIX64"\n", - addr, my_size); + vm_mngr->memory_w.array[i].start, + vm_mngr->memory_w.array[i].stop); fprintf(stderr, "**********************************\n"); #endif vm_mngr->exception_flags |= EXCEPT_CODE_AUTOMOD; @@ -463,27 +483,62 @@ void check_write_code_bloc(vm_mngr_t* vm_mngr, uint64_t my_size, uint64_t addr) } } -void reset_code_bloc_write(vm_mngr_t* vm_mngr) + +void check_memory_breakpoint(vm_mngr_t* vm_mngr) { int i; - int list_size; - PyObject* element; + struct memory_breakpoint_info * memory_bp; + + /* Check memory breakpoints */ + LIST_FOREACH(memory_bp, &vm_mngr->memory_breakpoint_pool, next) { + if (vm_mngr->exception_flags & EXCEPT_BREAKPOINT_INTERN) + break; + if (memory_bp->access & BREAKPOINT_READ) { + for (i=0;i<vm_mngr->memory_r.num; i++) { + if ((memory_bp->ad < vm_mngr->memory_r.array[i].stop) && + (vm_mngr->memory_r.array[i].start < memory_bp->ad + memory_bp->size)) { + vm_mngr->exception_flags |= EXCEPT_BREAKPOINT_INTERN; + break; + } + } + } + if (memory_bp->access & BREAKPOINT_WRITE) { + for (i=0;i<vm_mngr->memory_w.num; i++) { + if ((memory_bp->ad < vm_mngr->memory_w.array[i].stop) && + (vm_mngr->memory_w.array[i].start < memory_bp->ad + memory_bp->size)) { + vm_mngr->exception_flags |= EXCEPT_BREAKPOINT_INTERN; + break; + } + } + } + } +} - list_size = PyList_Size(vm_mngr->code_bloc_memory_w); - for (i=0;i<list_size; i++) { - element = PyList_GetItem(vm_mngr->code_bloc_memory_w, i); - Py_DECREF(element); +PyObject* get_memory_pylist(vm_mngr_t* vm_mngr, struct memory_access_list* memory_list) +{ + int i; + PyObject *pylist; + PyObject *range; + pylist = PyList_New(memory_list->num); + for (i=0;i<memory_list->num;i++) { + range = PyTuple_New(2); + PyTuple_SetItem(range, 0, PyLong_FromUnsignedLongLong((uint64_t)memory_list->array[i].start)); + PyTuple_SetItem(range, 1, PyLong_FromUnsignedLongLong((uint64_t)memory_list->array[i].stop)); + PyList_SetItem(pylist, i, range); } + return pylist; - Py_DECREF(vm_mngr->code_bloc_memory_w); - vm_mngr->code_bloc_memory_w = PyList_New(0); +} +PyObject* get_memory_read(vm_mngr_t* vm_mngr) +{ + return get_memory_pylist(vm_mngr, &vm_mngr->memory_r); } -PyObject* get_code_bloc_write(vm_mngr_t* vm_mngr) +PyObject* get_memory_write(vm_mngr_t* vm_mngr) { - return vm_mngr->code_bloc_memory_w; + return get_memory_pylist(vm_mngr, &vm_mngr->memory_w); } PyObject* addr2BlocObj(vm_mngr_t* vm_mngr, uint64_t addr) @@ -505,53 +560,53 @@ PyObject* addr2BlocObj(vm_mngr_t* vm_mngr, uint64_t addr) void vm_MEM_WRITE_08(vm_mngr_t* vm_mngr, uint64_t addr, unsigned char src) { - check_write_code_bloc(vm_mngr, 8, addr); - code_bloc_add_write(vm_mngr, addr, 1); + add_mem_write(vm_mngr, addr, 1); memory_page_write(vm_mngr, 8, addr, 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); - code_bloc_add_write(vm_mngr, addr, 2); + add_mem_write(vm_mngr, addr, 2); memory_page_write(vm_mngr, 16, addr, 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); - code_bloc_add_write(vm_mngr, addr, 4); + add_mem_write(vm_mngr, addr, 4); memory_page_write(vm_mngr, 32, addr, 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); - code_bloc_add_write(vm_mngr, addr, 8); + add_mem_write(vm_mngr, addr, 8); memory_page_write(vm_mngr, 64, addr, src); } 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 char ret; + add_mem_read(vm_mngr, addr, 1); + ret = memory_page_read(vm_mngr, 8, addr); + return ret; } 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 short ret; + add_mem_read(vm_mngr, addr, 2); + ret = memory_page_read(vm_mngr, 16, addr); + return ret; } 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; + unsigned int ret; + add_mem_read(vm_mngr, addr, 4); + ret = memory_page_read(vm_mngr, 32, addr); + return ret; } 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; + uint64_t ret; + add_mem_read(vm_mngr, addr, 8); + ret = memory_page_read(vm_mngr, 64, addr); + return ret; } @@ -592,8 +647,6 @@ 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, 1); @@ -1465,7 +1518,9 @@ void init_code_bloc_pool(vm_mngr_t* vm_mngr) vm_mngr->code_bloc_pool_ad_min = 0xffffffff; vm_mngr->code_bloc_pool_ad_max = 0; - vm_mngr->code_bloc_memory_w = PyList_New(0); + memory_access_list_init(&(vm_mngr->memory_r)); + memory_access_list_init(&(vm_mngr->memory_w)); + } @@ -1504,6 +1559,11 @@ void reset_code_bloc_pool(vm_mngr_t* vm_mngr) vm_mngr->code_bloc_pool_ad_max = 0; } +void reset_memory_access(vm_mngr_t* vm_mngr) +{ + memory_access_list_reset(&(vm_mngr->memory_r)); + memory_access_list_reset(&(vm_mngr->memory_w)); +} void reset_memory_breakpoint(vm_mngr_t* vm_mngr) { @@ -1517,6 +1577,8 @@ void reset_memory_breakpoint(vm_mngr_t* vm_mngr) } + + /* We don't use dichotomy here for the insertion */ int is_mpn_in_tab(vm_mngr_t* vm_mngr, struct memory_page_node* mpn_a) { |