Ejemplo n.º 1
0
 def read_memory(self, address, length):
     data = bytes()
     read_buf = create_string_buffer(length)
     if self.bitness == BinaryType.SCS_32BIT_BINARY.value:
         count = c_ulong(0)
     elif self.bitness == BinaryType.SCS_64BIT_BINARY.value:
         count = c_int64(0)
     while length:
         r = 0
         if self.bitness == BinaryType.SCS_32BIT_BINARY.value:
             r = windll.kernel32.ReadProcessMemory(self._process_handle,
                                                   address, read_buf,
                                                   length, byref(count))
         elif self.bitness == BinaryType.SCS_64BIT_BINARY.value:
             windll.kernel32.ReadProcessMemory.argtypes = [
                 c_int, c_uint64, c_char_p, c_long,
                 POINTER(c_int64)
             ]
             r = windll.kernel32.ReadProcessMemory(self._process_handle,
                                                   c_uint64(address),
                                                   read_buf, length,
                                                   byref(count))
         if r == 0:
             if len(data) == 0:
                 raise_windows_error(
                     "Unable to read %d bytes from address %08x" %
                     (length, address))
             else:
                 return data
         data += read_buf.raw
         length -= count.value
         address += count.value
     return data
Ejemplo n.º 2
0
    def protect_memory(self, address, length, protection):
        old_protection = c_ulong(0)
        p = None
        if self.bitness == BinaryType.SCS_32BIT_BINARY.value:
            windll.kernel32.VirtualProtectEx.argtypes = [
                c_int, c_ulong, c_int, c_long,
                POINTER(c_ulong)
            ]
            p = windll.kernel32.VirtualProtectEx(self._process_handle, address,
                                                 length, protection,
                                                 byref(old_protection))
        elif self.bitness == BinaryType.SCS_64BIT_BINARY.value:
            windll.kernel32.VirtualProtectEx.argtypes = [
                c_int, c_uint64, c_int, c_long,
                POINTER(c_ulong)
            ]
            p = windll.kernel32.VirtualProtectEx(self._process_handle,
                                                 c_uint64(address), length,
                                                 protection,
                                                 byref(old_protection))
        else:
            raise Exception("Unsupported processus bitness")

        if p == 0:
            raise_windows_error(
                "Unable to VirtualProtectEx [%08x-%08x] with protection 0x%08x"
                % (address, address + length, protection))
        return old_protection.value
Ejemplo n.º 3
0
 def allocate(self, size, aligned=0):
     if aligned != 0:
         size = align(size, aligned)
     address = windll.kernel32.VirtualAllocEx(
         self._process_handle, 0, size, AllocationType.VIRTUAL_MEM.value,
         MemoryPermission.PAGE_READWRITE.value)
     if address == 0:
         raise_windows_error("Unable allocate memory in remote process")
     return address
Ejemplo n.º 4
0
 def create_thread(self, address, arguments_address):
     thread_id = c_ulong(0)
     h_thread = windll.kernel32.CreateRemoteThread(self._process_handle,
                                                   None, 0, address,
                                                   arguments_address, 0,
                                                   byref(thread_id))
     if h_thread == 0:
         raise_windows_error("Failed to create thread in remote process")
     return Thread(thread_id.value, h_thread)
Ejemplo n.º 5
0
    def load_library(self, dll_path):
        dll_len = len(dll_path)
        arg_address = self.allocate(dll_len + 1)
        self.write_memory(arg_address, dll_path)

        h_loadlib = get_proc_address("kernel32.dll", "LoadLibraryA")
        th = self.create_thread(h_loadlib, arg_address)
        exit_code = th.wait()

        self.free(arg_address)
        if exit_code != 0:
            raise_windows_error("Error during remote thread execution",
                                exit_code)
Ejemplo n.º 6
0
    def run(self, arguments=None, flags=0):
        if not is_executable(self._filename):
            raise Exception("File does not seem to be executable")
        bintype = get_binary_type(self._filename.encode())
        if not python64() and bintype == BinaryType.SCS_64BIT_BINARY.value:
            raise_windows_error(
                "Unable create 64bit process using Python 32bit")

        pi = ProcessInfo()
        si = StartupInfo()
        if not windll.kernel32.CreateProcessA(
                c_char_p(0),
                c_char_p(
                    (self._filename + ("" if arguments is None else
                                       (" " + arguments))).encode('utf-8')), 0,
                0, False, flags, 0, 0, byref(si), byref(pi)):
            raise_windows_error("Unable create process")
        self._process_id = pi.dwProcessId
        self._process_handle = pi.hProcess
        self._threads.add(Thread(pi.dwThreadId, pi.hThread))
Ejemplo n.º 7
0
    def peb(self):
        process_basic_information = PROCESS_BASIC_INFORMATION()
        returned_length = DWORD()
        ret = windll.ntdll.NtQueryInformationProcess(
            self._process_handle,
            ProcessInformationQuery.PROCESS_BASIC_INFORMATION.value,
            byref(process_basic_information),
            sizeof(process_basic_information), byref(returned_length))
        if ret != NTStatus.STATUS_SUCCESS.value:
            raise_windows_error(
                "Unable to query information for remote process")

        peb_addr = process_basic_information.PebBaseAddress
        peb = PEB()
        read = DWORD()
        ret = windll.kernel32.ReadProcessMemory(self._process_handle, peb_addr,
                                                byref(peb), sizeof(peb),
                                                byref(read))
        if ret == 0:
            raise_windows_error("Unable to read data in remote process")

        return peb
Ejemplo n.º 8
0
 def write_memory(self, address, value, force=False):
     if self.bitness == BinaryType.SCS_32BIT_BINARY.value:
         count = c_ulong(0)
     elif self.bitness == BinaryType.SCS_64BIT_BINARY.value:
         count = c_int64(0)
     old_protect = 0
     if force:
         old_protect = self.protect_memory(
             address, len(value),
             MemoryPermission.PAGE_EXECUTE_READWRITE.value)
     tmp_length = len(value)
     while len(value) > 0:
         r = 0
         if self.bitness == BinaryType.SCS_32BIT_BINARY.value:
             r = windll.kernel32.WriteProcessMemory(self._process_handle,
                                                    address, value,
                                                    len(value),
                                                    byref(count))
         elif self.bitness == BinaryType.SCS_64BIT_BINARY.value:
             windll.kernel32.WriteProcessMemory.argtypes = [
                 c_int, c_uint64, c_char_p, c_long,
                 POINTER(c_int64)
             ]
             r = windll.kernel32.WriteProcessMemory(self._process_handle,
                                                    c_uint64(address),
                                                    value, len(value),
                                                    byref(count))
         if r == 0:
             raise_windows_error(
                 "Unable to write %d bytes to address %08x" %
                 (len(value), address))
         value = value[count.value:]
     if force:
         self.protect_memory(address, tmp_length, old_protect)
     self._modified_memory = True
     return True
Ejemplo n.º 9
0
 def free(self, address):
     ret = windll.kernel32.VirtualFreeEx(self._process_handle, address, 0,
                                         FreeType.MEM_RELEASE.value)
     if ret == 0:
         raise_windows_error("Unable freed memory in remote process")