diff options
| -rw-r--r-- | miasm2/os_dep/win_api_x86_32_seh.py | 279 |
1 files changed, 139 insertions, 140 deletions
diff --git a/miasm2/os_dep/win_api_x86_32_seh.py b/miasm2/os_dep/win_api_x86_32_seh.py index 53935db7..310fd283 100644 --- a/miasm2/os_dep/win_api_x86_32_seh.py +++ b/miasm2/os_dep/win_api_x86_32_seh.py @@ -142,43 +142,56 @@ def build_ldr_data(myjit, modules_info): +0x014 InMemoryOrderModuleList : _LIST_ENTRY +0x01C InInitializationOrderModuleList : _LIST_ENTRY """ - o = "" # ldr offset pad offset = LDR_AD + peb_ldr_data_offset + 0xC # get main pe info - m_e = None - for bname, (addr, e) in modules_info.items(): - if e == main_pe: - m_e = (e, bname, addr) - break - if not m_e: + main_pe = modules_info.name2module.get(main_pe_name, None) + if not main_pe: log.warn('No main pe, ldr data will be unconsistant') offset, data = offset + 8, "" else: - log.info('Ldr %x', m_e[2]) - data = pck32(m_e[2]) + pck32(0) - - # get ntdll - ntdll_e = None - for bname, (addr, e) in modules_info.items(): - if bname[::2].lower() == "ntdll.dll": - ntdll_e = (e, bname, addr) - continue - if not ntdll_e: + main_addr_entry = modules_info.module2entry[main_pe] + log.info('Ldr %x', main_addr_entry) + data = pck32(main_addr_entry) + pck32(0) + data += pck32(main_addr_entry + 0x8) + pck32(0) # XXX TODO fix prev + + ntdll_pe = modules_info.name2module.get("ntdll.dll", None) + if not ntdll_pe: log.warn('No ntdll, ldr data will be unconsistant') else: - data += pck32(ntdll_e[2] + 0x8) + pck32(0) # XXX TODO - data += pck32(ntdll_e[2] + 0x10) + pck32(0) + ntdll_addr_entry = modules_info.module2entry[ntdll_pe] + data += pck32(ntdll_addr_entry + 0x10) + pck32(0) # XXX TODO fix prev if data: myjit.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE, data) -dummy_e = pe_init.PE() -dummy_e.NThdr.ImageBase = 0 -dummy_e.Opthdr.AddressOfEntryPoint = 0 -dummy_e.NThdr.sizeofimage = 0 +class LoadedModules(object): + + """Class representing modules in memory""" + + def __init__(self): + self.modules = [] + self.name2module = {} + self.module2entry = {} + self.module2name = {} + + def add(self, name, module, module_entry): + """Track a new module + @name: module name (with extension) + @module: module object + @module_entry: addresse of the module entry + """ + + self.modules.append(module) + self.name2module[name] = module + self.module2entry[module] = module_entry + self.module2name[module] = name + + def __repr__(self): + out = self.name2module.iteritems() + return "\n".join(out) def create_modules_chain(myjit, modules_name): @@ -204,11 +217,16 @@ def create_modules_chain(myjit, modules_name): +0x04c PatchInformation : Ptr32 Void """ - modules_info = {} + modules_info = LoadedModules() base_addr = LDR_AD + modules_list_offset # XXXX offset_name = 0x500 offset_path = 0x600 + dummy_e = pe_init.PE() + dummy_e.NThdr.ImageBase = 0 + dummy_e.Opthdr.AddressOfEntryPoint = 0 + dummy_e.NThdr.sizeofimage = 0 + out = "" for i, m in enumerate([(main_pe_name, main_pe), ("", dummy_e)] + modules_name): @@ -234,7 +252,7 @@ def create_modules_chain(myjit, modules_name): continue log.info("Add module %x %r", e.NThdr.ImageBase, bname_str) - modules_info[bname] = addr, e + modules_info.add(bname_str, e, addr) m_o = "" m_o += pck32(0) @@ -267,131 +285,112 @@ def create_modules_chain(myjit, modules_name): return modules_info -def fix_InLoadOrderModuleList(myjit, modules_info): - log.debug("Fix InLoadOrderModuleList") - # first binary is PE - # last is dumm_e - olist = [] - m_e = None - d_e = None - for m in [main_pe_name, ""] + loaded_modules: - - if isinstance(m, tuple): - fname, e = m - else: - fname, e = m, None +def fix_InLoadOrderModuleList(jitter, modules_info): + """Fix InLoadOrderModuleList double link list. First module is the main pe, + then ntdll, kernel32. dummy is last pe. - if "/" in fname: - fname = fname[fname.rfind("/") + 1:] - bname_str = fname - bname = '\x00'.join(bname_str) + '\x00' - if not bname.lower() in modules_info: - log.warn('Module not found, ldr data will be unconsistant') - continue + @jitter: the jitter instance + @modules_info: the LoadedModules instance + """ - addr, e = modules_info[bname.lower()] - log.debug(bname_str) - if e == main_pe: - m_e = (e, bname, addr) - continue - elif e == dummy_e: - d_e = (e, bname, addr) - continue - olist.append((e, bname, addr)) - if not m_e or not d_e: + log.debug("Fix InLoadOrderModuleList") + main_pe = modules_info.name2module.get(main_pe_name, None) + kernel32_pe = modules_info.name2module.get("kernel32.dll", None) + ntdll_pe = modules_info.name2module.get("ntdll.dll", None) + dummy_pe = modules_info.name2module.get("", None) + special_modules = [main_pe, kernel32_pe, ntdll_pe, dummy_pe] + if not all(special_modules): log.warn('No main pe, ldr data will be unconsistant') + loaded_modules = modules_info.modules else: - olist[0:0] = [m_e] - olist.append(d_e) - - last_addr = 0 - for i in xrange(len(olist)): - e, bname, addr = olist[i] - p_e, p_bname, p_addr = olist[(i - 1) % len(olist)] - n_e, n_bname, n_addr = olist[(i + 1) % len(olist)] - myjit.vm.set_mem(addr + 0, pck32(n_addr) + pck32(p_addr)) - + loaded_modules = [module for module in modules_info.modules + if module not in special_modules] + loaded_modules[0:0] = [main_pe] + loaded_modules[1:1] = [ntdll_pe] + loaded_modules[2:2] = [kernel32_pe] + loaded_modules.append(dummy_pe) + + for i, module in enumerate(loaded_modules): + cur_module_entry = modules_info.module2entry[module] + prev_module = loaded_modules[(i - 1) % len(loaded_modules)] + next_module = loaded_modules[(i + 1) % len(loaded_modules)] + prev_module_entry = modules_info.module2entry[prev_module] + next_module_entry = modules_info.module2entry[next_module] + jitter.vm.set_mem(cur_module_entry, + (pck32(next_module_entry) + + pck32(prev_module_entry))) + + +def fix_InMemoryOrderModuleList(jitter, modules_info): + """Fix InMemoryOrderLinks double link list. First module is the main pe, + then ntdll, kernel32. dummy is last pe. + + @jitter: the jitter instance + @modules_info: the LoadedModules instance + """ -def fix_InMemoryOrderModuleList(myjit, modules_info): log.debug("Fix InMemoryOrderModuleList") - # first binary is PE - # last is dumm_e - olist = [] - m_e = None - d_e = None - for m in [main_pe_name, ""] + loaded_modules: + main_pe = modules_info.name2module.get(main_pe_name, None) + kernel32_pe = modules_info.name2module.get("kernel32.dll", None) + ntdll_pe = modules_info.name2module.get("ntdll.dll", None) + dummy_pe = modules_info.name2module.get("", None) + special_modules = [main_pe, kernel32_pe, ntdll_pe, dummy_pe] + if not all(special_modules): + log.warn('No main pe, ldr data will be unconsistant') + loaded_modules = modules_info.modules + else: + loaded_modules = [module for module in modules_info.modules + if module not in special_modules] + loaded_modules[0:0] = [main_pe] + loaded_modules[1:1] = [ntdll_pe] + loaded_modules[2:2] = [kernel32_pe] + loaded_modules.append(dummy_pe) + + for i, module in enumerate(loaded_modules): + cur_module_entry = modules_info.module2entry[module] + prev_module = loaded_modules[(i - 1) % len(loaded_modules)] + next_module = loaded_modules[(i + 1) % len(loaded_modules)] + prev_module_entry = modules_info.module2entry[prev_module] + next_module_entry = modules_info.module2entry[next_module] + jitter.vm.set_mem(cur_module_entry + 0x8, + (pck32(next_module_entry + 0x8) + + pck32(prev_module_entry + 0x8))) + + +def fix_InInitializationOrderModuleList(jitter, modules_info): + """Fix InInitializationOrderModuleList double link list. First module is the + ntdll, then kernel32. dummy is last pe. + + @jitter: the jitter instance + @modules_info: the LoadedModules instance - if isinstance(m, tuple): - fname, e = m - else: - fname, e = m, None + """ - if "/" in fname: - fname = fname[fname.rfind("/") + 1:] - bname_str = fname - bname = '\x00'.join(bname_str) + '\x00' - if not bname.lower() in modules_info: - log.warn('Module not found, ldr data will be unconsistant') - continue - addr, e = modules_info[bname.lower()] - log.debug(bname_str) - if e == main_pe: - m_e = (e, bname, addr) - continue - elif e == dummy_e: - d_e = (e, bname, addr) - continue - olist.append((e, bname, addr)) - if not m_e or not d_e: + log.debug("Fix InInitializationOrderModuleList") + main_pe = modules_info.name2module.get(main_pe_name, None) + kernel32_pe = modules_info.name2module.get("kernel32.dll", None) + ntdll_pe = modules_info.name2module.get("ntdll.dll", None) + dummy_pe = modules_info.name2module.get("", None) + special_modules = [main_pe, kernel32_pe, ntdll_pe, dummy_pe] + if not all(special_modules): log.warn('No main pe, ldr data will be unconsistant') + loaded_modules = modules_info.modules else: - olist[0:0] = [m_e] - olist.append(d_e) - - last_addr = 0 - - for i in xrange(len(olist)): - e, bname, addr = olist[i] - p_e, p_bname, p_addr = olist[(i - 1) % len(olist)] - n_e, n_bname, n_addr = olist[(i + 1) % len(olist)] - myjit.vm.set_mem( - addr + 0x8, pck32(n_addr + 0x8) + pck32(p_addr + 0x8)) - - -def fix_InInitializationOrderModuleList(myjit, modules_info): - # first binary is ntdll - # second binary is kernel32 - olist = [] - ntdll_e = None - kernel_e = None - for bname, (addr, e) in modules_info.items(): - if bname[::2].lower() == "ntdll.dll": - ntdll_e = (e, bname, addr) - continue - elif bname[::2].lower() == "kernel32.dll": - kernel_e = (e, bname, addr) - continue - elif e == dummy_e: - d_e = (e, bname, addr) - continue - elif e == main_pe: - continue - olist.append((e, bname, addr)) - if not ntdll_e or not kernel_e or not d_e: - log.warn('No kernel ntdll, ldr data will be unconsistant') - else: - olist[0:0] = [ntdll_e] - olist[1:1] = [kernel_e] - - olist.append(d_e) - - last_addr = 0 - for i in xrange(len(olist)): - e, bname, addr = olist[i] - p_e, p_bname, p_addr = olist[(i - 1) % len(olist)] - n_e, n_bname, n_addr = olist[(i + 1) % len(olist)] - myjit.vm.set_mem( - addr + 0x10, pck32(n_addr + 0x10) + pck32(p_addr + 0x10)) + loaded_modules = [module for module in modules_info.modules + if module not in special_modules] + loaded_modules[0:0] = [ntdll_pe] + loaded_modules[1:1] = [kernel32_pe] + loaded_modules.append(dummy_pe) + + for i, module in enumerate(loaded_modules): + cur_module_entry = modules_info.module2entry[module] + prev_module = loaded_modules[(i - 1) % len(loaded_modules)] + next_module = loaded_modules[(i + 1) % len(loaded_modules)] + prev_module_entry = modules_info.module2entry[prev_module] + next_module_entry = modules_info.module2entry[next_module] + jitter.vm.set_mem(cur_module_entry + 0x10, + (pck32(next_module_entry + 0x10) + + pck32(prev_module_entry + 0x10))) def add_process_env(myjit): |