def hook_WideCharToMultiByte(ql, address, params): ret = 0 cbMultiByte = params["cbMultiByte"] s_lpWideCharStr = params["lpWideCharStr"] lpMultiByteStr = params["lpMultiByteStr"] if cbMultiByte == 0: ret = len(s_lpWideCharStr) + 2 ret = align(ret // 2, 2) else: s = bytes(s_lpWideCharStr, 'ascii').decode('utf-16le') + "\x00" ql.uc.mem_write(lpMultiByteStr, bytes(s, 'ascii')) ret = len(s) return ret
def load_dll(self, dll_name): dll_name = dll_name.lower().decode() if self.ql.arch == QL_X86: self.ql.dlls = os.path.join("Windows", "SysWOW64") elif self.ql.arch == QL_X8664: self.ql.dlls = os.path.join("Windows", "System32") if not is_file_library(dll_name): dll_name = dll_name + ".dll" path = os.path.join(self.ql.rootfs, self.ql.dlls, dll_name) if not os.path.exists(path): raise QlErrorFileNotFound("[!] Cannot find dll in %s" % path) # If the dll is already loaded if dll_name in self.dlls: return self.dlls[dll_name] else: self.dlls[dll_name] = self.ql.DLL_LAST_ADDR self.ql.nprint("[+] Loading %s to 0x%x" % (path, self.ql.DLL_LAST_ADDR)) # cache depends on address base fcache = path + ".%x.cache" % self.ql.DLL_LAST_ADDR # Add dll to IAT try: self.import_address_table[dll_name] = {} except KeyError as ke: pass if self.ql.libcache and os.path.exists(fcache): (data, cmdlines, self.import_symbols, self.import_address_table) = \ pickle.load(open(fcache, "rb")) for entry in cmdlines: self.set_cmdline(entry['name'], entry['address'], data) else: dll = pefile.PE(path, fast_load=True) dll.parse_data_directories() data = bytearray(dll.get_memory_mapped_image()) cmdlines = [] for entry in dll.DIRECTORY_ENTRY_EXPORT.symbols: self.import_symbols[self.ql.DLL_LAST_ADDR + entry.address] = { 'name': entry.name, 'ordinal': entry.ordinal } self.import_address_table[dll_name][ entry.name] = self.ql.DLL_LAST_ADDR + entry.address self.import_address_table[dll_name][ entry.ordinal] = self.ql.DLL_LAST_ADDR + entry.address cmdline_entry = self.set_cmdline(entry.name, entry.address, data) if cmdline_entry: cmdlines.append(cmdline_entry) if self.ql.libcache: # cache this dll file pickle.dump((data, cmdlines, self.import_symbols, self.import_address_table), open(fcache, "wb")) self.ql.nprint("[+] Cached %s" % path) dll_base = self.ql.DLL_LAST_ADDR dll_len = align(len(bytes(data)), 0x1000) self.ql.DLL_SIZE += dll_len self.ql.uc.mem_map(dll_base, dll_len) self.ql.uc.mem_write(dll_base, bytes(data)) self.ql.DLL_LAST_ADDR += dll_len # add dll to ldr data self.add_ldr_data_table_entry(dll_name) self.ql.nprint("[+] Done with loading %s" % path) return dll_base