def install_hook(self, mod_name, new_address, name=None, ordinal=None): if not (bool(name) ^ bool(ordinal)): raise ValueError('must select either name or ordinal, not both') image_import_descriptors = self.get_proc_attribute('image_import_descriptor') image_dos_header_addr = self.get_proc_attribute('image_dos_header_addr') is_ordinal = lambda x: bool(x & 0x80000000) for iid in image_import_descriptors: cur_mod_name = self._get_name_for_image_import_descriptor(iid) if cur_mod_name.lower() != mod_name.lower(): continue ilt = self._get_ilt_for_image_import_descriptor(iid) iat = self._get_iat_for_image_import_descriptor(iid) for idx in range(len(ilt)): if ilt[idx] is None: continue hook_it = False if not is_ordinal(ilt[idx]) and name: cur_func_name = self._get_name_for_ilt_entry(ilt[idx]) if cur_func_name == name: hook_it = True elif is_ordinal(ilt[idx]) and ordinal: cur_func_ordinal = self._get_ordinal_for_ilt_entry(ilt[idx]) if cur_func_ordinal == ordinal: hook_it = True if hook_it: old_address = iat[idx] iat_ent_addr = image_dos_header_addr iat_ent_addr += iid.FirstThunk iat_ent_addr += (ctypes.sizeof(ctypes.c_void_p) * idx) new_addr = ctypes.c_void_p() new_addr.value = new_address written = wintypes.DWORD() if self.k32.WriteProcessMemory(self.handle, iat_ent_addr, ctypes.byref(new_addr), ctypes.sizeof(new_addr), ctypes.byref(written)) == 0: errno = self.k32.GetLastError() if errno == 998: errno = 0 old_permissions = wintypes.DWORD() if (self.k32.VirtualProtectEx(self.handle, iat_ent_addr, 0x400, flags('PAGE_READWRITE'), ctypes.byref(old_permissions)) == 0): raise WindowsProcessError('Error: VirtualProtectEx', get_last_error=self.k32.GetLastError()) if self.k32.WriteProcessMemory(self.handle, iat_ent_addr, ctypes.byref(new_addr), ctypes.sizeof(new_addr), ctypes.byref(written)) == 0: errno = self.k32.GetLastError() self.protect(iat_ent_addr, permissions=old_permissions) if errno: raise WindowsProcessError('Error: WriteProcessMemory', get_last_error=errno) hook = Hook('iat', iat_ent_addr, old_address, new_address) self._installed_hooks.append(hook) return hook raise ProcessError('failed to find location to install hook')
def install_hook(self, mod_name, new_address, name=None, ordinal=None): if architecture_is_32bit(self.__arch__): lm_struct = elf.Elf32_Link_Map dyn_struct = elf.Elf32_Dyn sym_struct = elf.Elf32_Sym elif architecture_is_64bit(self.__arch__): lm_struct = elf.Elf64_Link_Map dyn_struct = elf.Elf64_Dyn sym_struct = elf.Elf64_Sym else: raise LinuxProcessError('unsupported architecture: ' + repr(self.__arch__)) if ordinal: raise NotImplementedError('an ordinal is not supported for this implementation') if not name: raise RuntimeError('a name is required for this implementation') lm = self._read_structure_from_memory(self.get_proc_attribute('link_map_addr'), lm_struct) if os.path.isabs(mod_name): validate_name = lambda lm: bool(self.read_memory_string(lm.l_name) == mod_name) else: validate_name = lambda lm: bool(os.path.split(self.read_memory_string(lm.l_name))[-1].startswith(mod_name)) while not validate_name(lm): if lm.l_next == 0: raise ProcessError('unable to locate shared library') lm = self._read_structure_from_memory(lm.l_next, lm_struct) idx = 0 dyn = self._read_structure_from_memory(lm.l_ld, dyn_struct) nchains = 0 strtab = 0 symtab = 0 while dyn.d_tag: idx += 1 if dyn.d_tag == elf.constants.DT_HASH: #nchains = struct.unpack('I', self.read_memory(dyn.d_un.d_ptr + lm.l_addr + ctypes.sizeof(ctypes.c_int), ctypes.sizeof(ctypes.c_int)))[0] nchains = struct.unpack('I', self.read_memory(dyn.d_un.d_ptr + ctypes.sizeof(ctypes.c_int), ctypes.sizeof(ctypes.c_int)))[0] elif dyn.d_tag == elf.constants.DT_STRTAB: strtab = dyn.d_un.d_ptr elif dyn.d_tag == elf.constants.DT_SYMTAB: symtab = dyn.d_un.d_ptr dyn = self._read_structure_from_memory(lm.l_ld + (ctypes.sizeof(dyn_struct) * idx), dyn_struct) for idx in xrange(0, nchains): sym = self._read_structure_from_memory(symtab + (ctypes.sizeof(sym_struct) * idx), sym_struct) if (sym.st_info & 0xf) != elf.constants.STT_FUNC: continue if self.read_memory_string(strtab + sym.st_name) == name: sym_addr = (symtab + (ctypes.sizeof(sym_struct) * idx)) old_address = lm.l_addr + sym.st_value sym.st_value = (lm.l_addr - new_address) self.write_memory(sym_addr, struct_pack(sym)) hook = Hook('eat', (sym_addr + sym_struct.st_value.offset), old_address, new_address) self._installed_hooks.append(hook) return hook raise ProcessError('unable to locate function')