def _read_structure_from_memory(self, address, structure): structure_data = self.read_memory(address, ctypes.sizeof(structure)) return struct_unpack(structure, structure_data)
def _get_function_address(self, mod_name, func_name): if architecture_is_32bit(self.__arch__): ehdr_struct = elf.Elf32_Ehdr shdr_struct = elf.Elf32_Shdr sym_struct = elf.Elf32_Sym elif architecture_is_64bit(self.__arch__): ehdr_struct = elf.Elf64_Ehdr shdr_struct = elf.Elf64_Shdr sym_struct = elf.Elf64_Sym else: raise LinuxProcessError('unsupported architecture: ' + repr(self.__arch__)) ehdr_addr = None if os.path.isabs(mod_name): exe_maps = filter(lambda x: x.pathname == mod_name, self.maps.values()) filename = mod_name else: exe_maps = filter(lambda x: x.pathname != None and os.path.basename(x.pathname).startswith(mod_name), self.maps.values()) filename = exe_maps[0].pathname handle = open(filename, 'rb') ehdr = struct_unpack(ehdr_struct, handle.read(ctypes.sizeof(ehdr_struct))) # get the shdrs handle.seek(ehdr.e_shoff, os.SEEK_SET) data = handle.read(ehdr.e_shnum * ehdr.e_shentsize) _shdrs = (shdr_struct * ehdr.e_shnum) shdrs = _shdrs() ctypes.memmove(ctypes.byref(shdrs), data, len(data)) strtab = 0 symtab = 0 for idx in range(len(shdrs)): shdr = shdrs[idx] if shdr.sh_type == elf.constants.SHT_SYMTAB or shdr.sh_type == elf.constants.SHT_DYNSYM: if not (shdr.sh_entsize and shdr.sh_size): continue symtab = idx elif shdr.sh_type == elf.constants.SHT_STRTAB: if idx != ehdr.e_shstrndx: strtab = idx if symtab == 0 or strtab == 0: continue symh = shdrs[symtab] strh = shdrs[strtab] handle.seek(strh.sh_offset, os.SEEK_SET) strsymtbl = handle.read(strh.sh_size) sym_num = symh.sh_size / symh.sh_entsize _syms = (sym_struct * sym_num) syms = _syms() handle.seek(symh.sh_offset, os.SEEK_SET) ctypes.memmove(ctypes.byref(syms), handle.read(ctypes.sizeof(syms)), ctypes.sizeof(syms)) for idx in range(1, len(syms)): sym = syms[idx] name = "" if sym.st_name == 0: continue name_end = strsymtbl.find('\x00', sym.st_name) if strsymtbl[sym.st_name:name_end] != func_name: continue address = sym.st_value if filter(lambda mr: (address > mr.addr_low and address < mr.addr_high), exe_maps): return address else: return address + sorted(exe_maps, key=lambda mr: mr.addr_low)[0].addr_low strtab = 0 symtab = 0 raise ProcessError('unable to locate function')
def _get_function_address(self, mod_name, func_name): if architecture_is_32bit(self.__arch__): ehdr_struct = elf.Elf32_Ehdr shdr_struct = elf.Elf32_Shdr sym_struct = elf.Elf32_Sym elif architecture_is_64bit(self.__arch__): ehdr_struct = elf.Elf64_Ehdr shdr_struct = elf.Elf64_Shdr sym_struct = elf.Elf64_Sym else: raise LinuxProcessError('unsupported architecture: ' + repr(self.__arch__)) ehdr_addr = None if os.path.isabs(mod_name): exe_maps = filter(lambda x: x.pathname == mod_name, self.maps.values()) filename = mod_name else: exe_maps = filter( lambda x: x.pathname != None and os.path.basename(x.pathname). startswith(mod_name), self.maps.values()) filename = exe_maps[0].pathname handle = open(filename, 'rb') ehdr = struct_unpack(ehdr_struct, handle.read(ctypes.sizeof(ehdr_struct))) # get the shdrs handle.seek(ehdr.e_shoff, os.SEEK_SET) data = handle.read(ehdr.e_shnum * ehdr.e_shentsize) _shdrs = (shdr_struct * ehdr.e_shnum) shdrs = _shdrs() ctypes.memmove(ctypes.byref(shdrs), data, len(data)) strtab = 0 symtab = 0 for idx in range(len(shdrs)): shdr = shdrs[idx] if shdr.sh_type == elf.constants.SHT_SYMTAB or shdr.sh_type == elf.constants.SHT_DYNSYM: if not (shdr.sh_entsize and shdr.sh_size): continue symtab = idx elif shdr.sh_type == elf.constants.SHT_STRTAB: if idx != ehdr.e_shstrndx: strtab = idx if symtab == 0 or strtab == 0: continue symh = shdrs[symtab] strh = shdrs[strtab] handle.seek(strh.sh_offset, os.SEEK_SET) strsymtbl = handle.read(strh.sh_size) sym_num = symh.sh_size / symh.sh_entsize _syms = (sym_struct * sym_num) syms = _syms() handle.seek(symh.sh_offset, os.SEEK_SET) ctypes.memmove(ctypes.byref(syms), handle.read(ctypes.sizeof(syms)), ctypes.sizeof(syms)) for idx in range(1, len(syms)): sym = syms[idx] name = "" if sym.st_name == 0: continue name_end = strsymtbl.find('\x00', sym.st_name) if strsymtbl[sym.st_name:name_end] != func_name: continue address = sym.st_value if filter( lambda mr: (address > mr.addr_low and address < mr.addr_high), exe_maps): return address else: return address + sorted( exe_maps, key=lambda mr: mr.addr_low)[0].addr_low strtab = 0 symtab = 0 raise ProcessError('unable to locate function')