def load_target_proc(self, proc_obj: EmuProcess): _pe_ = proc_obj.parsed_pe if _pe_.DOS_HEADER.e_magic != struct.unpack("<H", b'MZ')[0]: # pylint: disable=no-member raise Exception("Target file is not PE") image_base = _pe_.OPTIONAL_HEADER.ImageBase size_of_image = _pe_.OPTIONAL_HEADER.SizeOfImage ep = image_base + _pe_.OPTIONAL_HEADER.AddressOfEntryPoint image_pages = self.mem_manager.alloc_page( pid=proc_obj.pid, size=size_of_image, allocation_type=PageAllocationType.MEM_COMMIT | PageAllocationType.MEM_RESERVE, alloc_base=image_base, protect=PageProtect.PAGE_EXECUTE_READWRITE, page_type=PageType.MEM_IMAGE) image_base = image_pages.get_base_addr() proc_obj.set_image_base(image_base) proc_obj.set_ep(ep) pe_image = _pe_.get_memory_mapped_image(ImageBase=image_base) self.mem_manager.write_process_memory(proc_obj.pid, image_base, pe_image) del pe_image
def setup_emulated_dllobj(self, mod_name, proc_obj: EmuProcess): def igetattr(obj, attr): for a in dir(obj): if a.lower() == attr.lower(): return getattr(obj, a) raise AttributeError if mod_name not in sys.modules: mod_obj = importlib.import_module("pydll." + mod_name) if mod_name not in proc_obj.e_dllobj: proc_obj.add_e_dll_obj(mod_name, igetattr(mod_obj, mod_name)(self)) pass
def setup_import_tab(self, proc_obj: EmuProcess): def rewrite_iat_table(uc, first_thunk_etry, addr): addr = struct.pack("I", addr) uc.mem_write(first_thunk_etry, addr) for dll in proc_obj.parsed_pe.DIRECTORY_ENTRY_IMPORT: # pylint: disable=no-member dll_name = dll.dll.decode("ascii").lower().split(".")[0] proc_obj.set_imports(dll_name, []) if dll_name not in pydll.SYSTEM_DLL_BASE: dll_name = self.api_handler.api_set_schema(dll_name) try: dll_base = pydll.SYSTEM_DLL_BASE[dll_name] except: raise Exception("Unsupported DLL") for imp_api in dll.imports: api_name = imp_api.name.decode("ascii") if "msvcp" in dll_name: # MS cpp runtime lib if not proc_obj.pid in self.api_handler.cpp_procedure: self.api_handler.cpp_procedure[proc_obj.pid] = {} self.api_handler.cpp_procedure[proc_obj.pid][ imp_api.address] = api_name else: if dll_name not in proc_obj.imports: proc_obj.set_imports( dll_name, [(api_name, dll_base + imp_api.hint)]) proc_obj.add_imports(dll_name, (api_name, dll_base + imp_api.hint)) proc_obj.set_api_va_dict(dll_base + imp_api.hint, (dll_name, api_name)) rewrite_iat_table(proc_obj.uc_eng, imp_api.address, dll_base + imp_api.hint) pass
def add_module_to_peb(self, proc_obj: EmuProcess, mod_name: str): new_ldte = ntos.LDR_DATA_TABLE_ENTRY(self.ptr_size) new_ldte.DllBase = pydll.SYSTEM_DLL_BASE[mod_name] new_ldte.Length = ntos.LDR_DATA_TABLE_ENTRY(self.ptr_size).sizeof() self.new_unicode_string(proc_obj, new_ldte.BaseDllName, mod_name) self.new_unicode_string(proc_obj, new_ldte.FullDllName, "C:\\Windows\\System32\\" + mod_name + ".dll") pNew_ldte = self.mem_manager.alloc_heap(proc_obj.peb_heap, new_ldte.sizeof()) list_type = ntos.LIST_ENTRY(self.ptr_size) # Link created list_entry to LDR_MODULE if not proc_obj.ldr_entries: pEntry, prev = proc_obj.peb.Ldr, proc_obj.peb_ldr_data prev.InLoadOrderModuleList.Flink = pNew_ldte prev.InMemoryOrderModuleList.Flink = pNew_ldte + list_type.sizeof() prev.InInitializationOrderModuleList.Flink = 0 else: pEntry, prev = proc_obj.ldr_entries[-1] prev.InLoadOrderLinks.Flink = pNew_ldte prev.InMemoryOrderLinks.Flink = pNew_ldte + list_type.sizeof() prev.InInitializationOrderLinks.Flink = 0 # Not implement Blink new_ldte.InLoadOrderLinks.Flink = proc_obj.peb.Ldr + 0xC new_ldte.InMemoryOrderLinks.Flink = proc_obj.peb.Ldr + 0xC + list_type.sizeof( ) proc_obj.add_ldr_entry((pNew_ldte, new_ldte)) proc_obj.write_mem_self(pNew_ldte, new_ldte.get_bytes()) proc_obj.write_mem_self(pEntry, prev.get_bytes()) proc_obj.write_mem_self(proc_obj.peb_base, proc_obj.peb.get_bytes()) proc_obj.write_mem_self(proc_obj.peb.Ldr, proc_obj.peb_ldr_data.get_bytes()) pass
def switch_thread_context(self, proc_obj: EmuProcess, thread_obj: EmuThread, ret=0): def context_switch_cb(proc_obj: EmuProcess, thread_handle): proc_obj.running_thread.save_context() proc_obj.push_waiting_queue(proc_obj.running_thread.handle) proc_obj.push_waiting_queue(thread_handle) proc_obj.uc_eng.hook_del(proc_obj.ctx_switch_hook) proc_obj.running_thread.suspend_thread() proc_obj.ctx_switch_hook = proc_obj.uc_eng.hook_add( UC_HOOK_CODE, self.api_handler.post_api_call_cb_wrapper, (proc_obj, (proc_obj, thread_obj.handle), 1, context_switch_cb)) pass
def init_vas(self, proc_obj: EmuProcess): # This is actually done by ntoskrnl self.mem_manager.alloc_page( pid=proc_obj.pid, alloc_base=0, size=0x10000, allocation_type=PageAllocationType.MEM_RESERVE) peb_heap = self.mem_manager.create_heap(pid=proc_obj.pid, size=0x2000, max_size=0) peb_base = self.mem_manager.alloc_heap( peb_heap, ntos.PEB(self.ptr_size).sizeof()) proc_default_heap = self.mem_manager.create_heap(pid=proc_obj.pid, size=1024 * 1024, max_size=1024 * 1024) proc_obj.set_peb_heap(peb_heap) proc_obj.set_peb_base(peb_base) proc_obj.set_proc_default_heap(proc_default_heap) pass
def context_switch_cb(proc_obj: EmuProcess, thread_handle): proc_obj.running_thread.save_context() proc_obj.push_waiting_queue(proc_obj.running_thread.handle) proc_obj.push_waiting_queue(thread_handle) proc_obj.uc_eng.hook_del(proc_obj.ctx_switch_hook) proc_obj.running_thread.suspend_thread()
def init_peb(self, proc_obj: EmuProcess): # create new PEB & PEB_LDR & Process Image LDR_ENTRY peb = ntos.PEB(self.ptr_size) new_ldte = ntos.LDR_DATA_TABLE_ENTRY(self.ptr_size) peb_ldr_data = ntos.PEB_LDR_DATA(self.ptr_size) peb.BeingDebugged = 0 peb.ImageBaseAddress = proc_obj.image_base peb.ProcessHeap = proc_obj.proc_default_heap.get_base_addr() # allocate memory space for PEB and PEB_LDR & Process Image LDR_ENTRY peb.Ldr = self.mem_manager.alloc_heap(proc_obj.peb_heap, peb_ldr_data.sizeof()) pNew_ldte = self.mem_manager.alloc_heap(proc_obj.peb_heap, new_ldte.sizeof()) # setup Process Image LDR_ENTRY new_ldte.SizeOfImage = proc_obj.parsed_pe.OPTIONAL_HEADER.SizeOfImage new_ldte.DllBase = proc_obj.parsed_pe.OPTIONAL_HEADER.ImageBase new_ldte.LoadCount = 1 self.new_unicode_string(proc_obj, new_ldte.BaseDllName, proc_obj.name) self.new_unicode_string(proc_obj, new_ldte.FullDllName, proc_obj.path) # link PEB_LDR and Process Image LDR_ENTRY size_of_list_etry = ntos.LIST_ENTRY(self.ptr_size).sizeof() peb_ldr_data.InLoadOrderModuleList.Flink = pNew_ldte peb_ldr_data.InMemoryOrderModuleList.Flink = pNew_ldte + size_of_list_etry new_ldte.InLoadOrderLinks.Flink = peb.Ldr + 0xC new_ldte.InMemoryOrderLinks.Flink = peb.Ldr + 0xC + size_of_list_etry proc_obj.write_mem_self(pNew_ldte, new_ldte.get_bytes()) proc_obj.write_mem_self(peb.Ldr, peb_ldr_data.get_bytes()) proc_obj.write_mem_self(proc_obj.peb_base, peb.get_bytes()) proc_obj.add_ldr_entry((pNew_ldte, new_ldte)) proc_obj.set_peb_ldr(peb_ldr_data) proc_obj.set_peb(peb) pass