Esempio n. 1
0
	def __init__(self, *args, **kwargs):
		self.errno = None
		"""The libc error number at the time the exception was raised."""
		if 'errno' in kwargs:
			self.errno = kwargs['errno']
			del kwargs['errno']
		ProcessError.__init__(self, *args, **kwargs)
Esempio n. 2
0
 def __init__(self, *args, **kwargs):
     self.errno = None
     """The libc error number at the time the exception was raised."""
     if 'errno' in kwargs:
         self.errno = kwargs['errno']
         del kwargs['errno']
     ProcessError.__init__(self, *args, **kwargs)
Esempio n. 3
0
    def __init__(self,
                 pid=None,
                 exe=None,
                 handle=None,
                 arch='x86',
                 access=None):
        if platform.system() != 'Windows':
            raise RuntimeError('incompatible platform')
        self.__arch__ = arch
        self.k32 = ctypes.windll.kernel32
        self.ntdll = ctypes.windll.ntdll
        self.psapi = ctypes.windll.psapi
        self._setup_winapi()

        self.handle = None
        if pid == -1:
            handle = -1
            pid = None
        if access is None:
            access = "(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ | PROCESS_TERMINATE)"
        if pid:
            self.handle = self.k32.OpenProcess(flags(access), False, pid)
            if not self.handle:
                raise ProcessError('could not open PID')
        elif exe:
            startupinfo = wintypes.STARTUPINFO()
            process_info = wintypes.PROCESS_INFORMATION()
            startupinfo.dwFlags = 0x01
            startupinfo.wShowWindow = 0x00
            startupinfo.cb = ctypes.sizeof(startupinfo)
            self.k32.CreateProcessA(exe, None, None, None, True, 0, None, None,
                                    ctypes.byref(startupinfo),
                                    ctypes.byref(process_info))
            self.handle = process_info.hProcess
            if not self.handle:
                raise ProcessError('could not the create process')
        elif handle:
            self.handle = handle
        else:
            raise ProcessError(
                'either a pid, exe or a handle must be specified')
        if process_is_wow64() != process_is_wow64(self.handle):
            raise ProcessError(
                'the python process must be the same architecture as the target process'
            )
        self.pid = self.k32.GetProcessId(self.handle)
        _name = (ctypes.c_char * 0x400)
        name = _name()
        if hasattr(self.psapi, 'GetModuleFileNameExA'):
            self.psapi.GetModuleFileNameExA(self.handle, 0, name,
                                            ctypes.sizeof(name))
        else:
            self.k32.GetModuleFileNameExA(self.handle, 0, name,
                                          ctypes.sizeof(name))
        self.exe_file = ''.join(name).rstrip('\x00')
        self._installed_hooks = []
        self._update_maps()
Esempio n. 4
0
	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')
Esempio n. 5
0
 def get_proc_attribute(self, attribute):
     requested_attribute = attribute
     if attribute.startswith('&'):
         attribute = attribute[1:] + '_addr'
     if hasattr(self, '_get_attr_' + attribute):
         return getattr(self, '_get_attr_' + attribute)()
     raise ProcessError('Unknown Attribute: ' + requested_attribute)
Esempio n. 6
0
 def get_proc_attribute(self, attribute):
     requested_attribute = attribute
     if attribute.startswith('&'):
         attribute = attribute[1:] + '_addr'
     if attribute.startswith('elf_'):
         if architecture_is_32bit(self.__arch__):
             attribute = 'elf32_' + attribute[4:]
         elif architecture_is_64bit(self.__arch__):
             attribute = 'elf64_' + attribute[4:]
     if hasattr(self, '_get_attr_' + attribute):
         return getattr(self, '_get_attr_' + attribute)()
     elif not attribute.endswith('_addr') and attribute.startswith(
             'elf32_'):
         if hasattr(self, '_get_attr_' + attribute + '_addr'):
             address = getattr(self, '_get_attr_' + attribute + '_addr')()
             attribute = 'Elf32_' + attribute[6:].title()
             if hasattr(elf, attribute):
                 return self._read_structure_from_memory(
                     address, getattr(elf, attribute))
     elif not attribute.endswith('_addr') and attribute.startswith(
             'elf64_'):
         if hasattr(self, '_get_attr_' + attribute + '_addr'):
             address = getattr(self, '_get_attr_' + attribute + '_addr')()
             attribute = 'Elf64_' + attribute[6:].title()
             if hasattr(elf, attribute):
                 return self._read_structure_from_memory(
                     address, getattr(elf, attribute))
     raise ProcessError('Unknown Attribute: ' + requested_attribute)
Esempio n. 7
0
    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')
Esempio n. 8
0
	def _allocate_malloc(self, size):
		malloc_addr = None
		malloc_locations = ['libc-', 'ld-linux.so']
		for lib in malloc_locations:
			try:
				malloc_addr = self._get_function_address(lib, 'malloc')
				break
			except ProcessError:
				pass
		if malloc_addr is None:
			raise ProcessError('unable to locate function')
		return self._call_function(malloc_addr, size)
Esempio n. 9
0
	def _free_free(self, address):
		free_addr = None
		free_locations = ['libc-', 'ld-linux.so']
		for lib in free_locations:
			try:
				free_addr = self._get_function_address(lib, 'free')
				break
			except ProcessError:
				pass
		if free_addr is None:
			raise ProcessError('unable to locate function')
		self._call_function(free_addr, address)
		return
Esempio n. 10
0
 def __init__(self, *args, **kwargs):
     self.get_last_error = None
     if 'get_last_error' in kwargs:
         self.get_last_error = kwargs['get_last_error']
         del kwargs['get_last_error']
     ProcessError.__init__(self, *args, **kwargs)
Esempio n. 11
0
    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')
Esempio n. 12
0
	def __init__(self, *args, **kwargs):
		self.get_last_error = None
		if 'get_last_error' in kwargs:
			self.get_last_error = kwargs['get_last_error']
			del kwargs['get_last_error']
		ProcessError.__init__(self, *args, **kwargs)
Esempio n. 13
0
 def __init__(self, *args, **kwargs):
     self.get_last_error = None
     if "get_last_error" in kwargs:
         self.get_last_error = kwargs["get_last_error"]
         del kwargs["get_last_error"]
     ProcessError.__init__(self, *args, **kwargs)