diff options
| author | Caroline Leman <carolinele@users.noreply.github.com> | 2020-01-25 11:48:54 +0100 |
|---|---|---|
| committer | Caroline Leman <carolinele@users.noreply.github.com> | 2020-01-28 00:57:07 +0100 |
| commit | 78107cdcf06294f0e394806d852a610c08308761 (patch) | |
| tree | f3296fe43cf06620bb04c7c08d162c1e4cf672fb | |
| parent | 49c7dfc4714aaf4e6fd854bdde6cc1081c92453a (diff) | |
| download | miasm-78107cdcf06294f0e394806d852a610c08308761.tar.gz miasm-78107cdcf06294f0e394806d852a610c08308761.zip | |
Win_API: Fix VirtualProtect when splitting access rights
Diffstat (limited to '')
| -rw-r--r-- | miasm/os_dep/win_api_x86_32.py | 66 |
1 files changed, 46 insertions, 20 deletions
diff --git a/miasm/os_dep/win_api_x86_32.py b/miasm/os_dep/win_api_x86_32.py index 5e2fb680..7780a9e4 100644 --- a/miasm/os_dep/win_api_x86_32.py +++ b/miasm/os_dep/win_api_x86_32.py @@ -185,6 +185,7 @@ class c_winobjs(object): self.events_pool = {} self.find_data = None + self.allocated_pages = {} self.current_datetime = datetime.datetime( year=2017, month=8, day=21, hour=13, minute=37, @@ -757,31 +758,54 @@ def kernel32_VirtualProtect(jitter): old = jitter.vm.get_mem_access(args.lpvoid) jitter.vm.set_u32(args.lpfloldprotect, ACCESS_DICT_INV[old]) - protect_addr = args.lpvoid - (args.lpvoid % winobjs.alloc_align) - for addr, data in jitter.vm.get_all_memory().items(): - size = data["size"] - # Exact match - if addr == protect_addr and args.dwsize == size: + paddr = args.lpvoid - (args.lpvoid % winobjs.alloc_align) + psize = args.dwsize + for addr, items in list(winobjs.allocated_pages.items()): + alloc_addr, alloc_size = items + if not (alloc_addr <= paddr and + paddr + psize <= alloc_addr + alloc_size): + continue + size = jitter.vm.get_all_memory()[addr]["size"] + # Page is included in Protect area + if (paddr <= addr < addr + size <= paddr + psize): log.warn("set page %x %x", addr, ACCESS_DICT[flnewprotect]) jitter.vm.set_mem_access(addr, ACCESS_DICT[flnewprotect]) continue - # Split memory area - if addr <= protect_addr < protect_addr + args.dwsize <= addr + size: - part1 = jitter.vm.get_mem(addr, protect_addr + args.dwsize - addr) - part2 = jitter.vm.get_mem(protect_addr + args.dwsize, addr + size - protect_addr - args.dwsize) + + # Page is partly in Protect area: splitting is needed + if (addr <= paddr < addr + size or + addr <= paddr + psize < addr + size): + old_access = jitter.vm.get_mem_access(addr) + + # splits = [ + # addr -> max(paddr, addr) + # max(paddr, addr) -> min(addr + size, paddr + psize) + # min(addr + size, paddr + psize) -> addr + size + # ] + splits = [ + (addr, old_access, + jitter.vm.get_mem(addr, max(paddr, addr) - addr)), + (max(paddr, addr), ACCESS_DICT[flnewprotect], + jitter.vm.get_mem( + max(paddr, addr), + min(addr + size, paddr + psize) - max(paddr, addr))), + (min(addr + size, paddr + psize), old_access, + jitter.vm.get_mem( + min(addr + size, paddr + psize), + addr + size - min(addr + size, paddr + psize))) + ] + jitter.vm.remove_memory_page(addr) - log.warn("create page %x %x", addr, old_access) - log.warn("create page %x %x", protect_addr + args.dwsize, ACCESS_DICT[flnewprotect]) - jitter.vm.add_memory_page(addr, old_access, part1, "VirtualProtect split") - jitter.vm.add_memory_page(protect_addr + args.dwsize, ACCESS_DICT[flnewprotect], part2, "VirtualProtect split") - continue - # Multi page - if (addr <= protect_addr < addr + size or - addr < protect_addr + args.dwsize <= addr + size): - log.warn("set page %x %x", addr, ACCESS_DICT[flnewprotect]) - jitter.vm.set_mem_access(addr, ACCESS_DICT[flnewprotect]) - continue + for split_addr, split_access, split_data in splits: + if not split_data: + continue + log.warn("create page %x %x", split_addr, + ACCESS_DICT[flnewprotect]) + jitter.vm.add_memory_page( + split_addr, split_access, split_data, + "VirtualProtect split ret 0x%X" % ret_ad) + winobjs.allocated_pages[split_addr] = (alloc_addr, alloc_size) jitter.func_ret_stdcall(ret_ad, 1) @@ -795,6 +819,7 @@ def kernel32_VirtualAlloc(jitter): if args.lpvoid == 0: alloc_addr = winobjs.heap.next_addr(args.dwsize) + winobjs.allocated_pages[alloc_addr] = (alloc_addr, args.dwsize) jitter.vm.add_memory_page( alloc_addr, ACCESS_DICT[args.flprotect], b"\x00" * args.dwsize, "Alloc in %s ret 0x%X" % (whoami(), ret_ad)) @@ -805,6 +830,7 @@ def kernel32_VirtualAlloc(jitter): jitter.vm.set_mem_access(args.lpvoid, ACCESS_DICT[args.flprotect]) else: alloc_addr = winobjs.heap.next_addr(args.dwsize) + winobjs.allocated_pages[alloc_addr] = (alloc_addr, args.dwsize) # alloc_addr = args.lpvoid jitter.vm.add_memory_page( alloc_addr, ACCESS_DICT[args.flprotect], b"\x00" * args.dwsize, |