Пример #1
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')
Пример #2
0
    def load_library(self, libpath):
        libpath = os.path.abspath(libpath)
        libpath_len = align_up(len(libpath) + 1, 0x200)
        LoadLibraryA = self.k32.GetProcAddress(
            self.k32.GetModuleHandleA("kernel32.dll"), "LoadLibraryA")
        RemotePage = self.k32.VirtualAllocEx(self.handle, None,
                                             len(libpath) + 1,
                                             flags("MEM_COMMIT"),
                                             flags("PAGE_EXECUTE_READWRITE"))
        if not RemotePage:
            raise WindowsProcessError(
                'Error: failed to allocate space for library name in the target process'
            )
        self.k32.WriteProcessMemory(self.handle, RemotePage, libpath,
                                    len(libpath), None)
        RemoteThread = self.k32.CreateRemoteThread(self.handle, None, 0,
                                                   LoadLibraryA, RemotePage, 0,
                                                   None)
        self.k32.WaitForSingleObject(RemoteThread, -1)

        exitcode = wintypes.DWORD(0)
        self.k32.GetExitCodeThread(RemoteThread, ctypes.byref(exitcode))
        self.k32.VirtualFreeEx(self.handle, RemotePage, len(libpath),
                               flags("MEM_RELEASE"))
        if exitcode.value == 0:
            raise WindowsProcessError('Error: failed to load: ' +
                                      repr(libpath))
        self._update_maps()
        return exitcode.value
Пример #3
0
 def read(self):
     ctarray = (ctypes.c_byte * self.buffer_size)()
     bytes_read = wintypes.DWORD(0)
     if not kernel32.ReadFile(self.handle, ctarray, self.buffer_size,
                              ctypes.byref(bytes_read), 0):
         return None
     return utilities.ctarray_to_bytes(ctarray)[:bytes_read.value]
Пример #4
0
    def load_library(self, libpath):
        libpath = os.path.abspath(libpath)
        libpath = libpath.encode('utf-8') + b'\x00'
        LoadLibraryA = self.k32.GetProcAddress(
            self.k32.GetModuleHandleA(b'kernel32.dll'), b'LoadLibraryA')
        remote_page = self.k32.VirtualAllocEx(self.handle, None, len(libpath),
                                              flags("MEM_COMMIT"),
                                              flags("PAGE_EXECUTE_READWRITE"))
        if not remote_page:
            raise WindowsProcessError(
                'Error: failed to allocate space for library name in the target process'
            )
        if not self.k32.WriteProcessMemory(self.handle, remote_page, libpath,
                                           len(libpath), None):
            raise WindowsProcessError(
                'Error: failed to copy the library name to the target process')
        remote_thread = self.k32.CreateRemoteThread(self.handle, None, 0,
                                                    LoadLibraryA, remote_page,
                                                    0, None)
        self.k32.WaitForSingleObject(remote_thread, -1)

        exitcode = wintypes.DWORD(0)
        self.k32.GetExitCodeThread(remote_thread, ctypes.byref(exitcode))
        self.k32.VirtualFreeEx(self.handle, remote_page, len(libpath),
                               flags("MEM_RELEASE"))
        if exitcode.value == 0:
            raise WindowsProcessError(
                "Error: failed to load: {0}, thread exited with status: 0x{1:x}"
                .format(libpath, exitcode.value))
        self._update_maps()
        return exitcode.value
Пример #5
0
    def load_library(self, path):
        path = os.path.abspath(path)
        libpath = path.encode('mbcs') + b'\x00'
        remote_page = m_k32.VirtualAllocEx(self.handle, None, len(libpath),
                                           flags("MEM_COMMIT"),
                                           flags("PAGE_EXECUTE_READWRITE"))
        if not remote_page:
            raise WindowsProcessError(
                'Error: failed to allocate space for library name in the target process'
            )
        if not m_k32.WriteProcessMemory(self.handle, remote_page, libpath,
                                        len(libpath), None):
            raise WindowsProcessError(
                'Error: failed to copy the library name to the target process')
        remote_thread = m_k32.CreateRemoteThread(self.handle, None, 0,
                                                 m_k32.LoadLibraryA.address,
                                                 remote_page, 0, None)
        m_k32.WaitForSingleObject(remote_thread, -1)

        exitcode = wintypes.DWORD(0)
        m_k32.GetExitCodeThread(remote_thread, ctypes.byref(exitcode))
        m_k32.VirtualFreeEx(self.handle, remote_page, len(libpath),
                            flags("MEM_RELEASE"))
        if exitcode.value == 0:
            raise WindowsProcessError(
                "Error: failed to load \"{0}\", thread exited with status: 0x{1:x}"
                .format(path, exitcode.value))
        return exitcode.value
Пример #6
0
 def protect(self, address, permissions=None, size=0x400):
     permissions = flags(permissions or 'PAGE_EXECUTE_READWRITE')
     old_permissions = wintypes.DWORD()
     if (self.k32.VirtualProtectEx(self.handle, address, size, permissions,
                                   ctypes.byref(old_permissions)) == 0):
         raise WindowsProcessError('Error: VirtualProtectEx',
                                   get_last_error=self.k32.GetLastError())
     return
Пример #7
0
 def _get_attr_peb_addr(self):
     process_basic_information = wintypes.PROCESS_BASIC_INFORMATION()
     return_length = wintypes.DWORD()
     self.ntdll.NtQueryInformationProcess(
         self.handle, 0, ctypes.byref(process_basic_information),
         ctypes.sizeof(process_basic_information),
         ctypes.byref(return_length))
     return process_basic_information.PebBaseAddress
Пример #8
0
        def read(self):
                ctarray = (ctypes.c_byte * self.buffer_size)()
                bytes_read = wintypes.DWORD(0)

                overlapped = wintypes.OVERLAPPED()
                overlapped.hEvent = m_k32.CreateEventW(None, True, False, None)
                if m_k32.ReadFile(self.handle, ctypes.byref(ctarray), self.buffer_size, ctypes.byref(bytes_read), ctypes.byref(overlapped)):
                        return utilities.ctarray_to_bytes(ctarray)[:bytes_read.value]
                error = m_k32.GetLastError()
                if error == ERROR_IO_PENDING and _wait_overlapped_io(overlapped):
                        return utilities.ctarray_to_bytes(ctarray)[:overlapped.InternalHigh]
                if error == ERROR_BROKEN_PIPE:
                        return None
                raise ctypes.WinError()