MarioVilas / winappdbg

WinAppDbg Debugger
444 stars 111 forks source link

Shared memory writes break debugged process #44

Open hatRiot opened 6 years ago

hatRiot commented 6 years ago

Under certain conditions (active shared memory, for example), modifying a shared memory map with PAGE_WRITECOPY can have adverse effects on the target process.

In the Process class exists the following:

  hProcess = self.get_handle( win32.PROCESS_VM_WRITE |
                                    win32.PROCESS_VM_OPERATION |
                                    win32.PROCESS_QUERY_INFORMATION )
        mbi = self.mquery(lpBaseAddress)
        if not mbi.has_content():
            raise ctypes.WinError(win32.ERROR_INVALID_ADDRESS)
        if mbi.is_image() or mbi.is_mapped():
            prot = win32.PAGE_WRITECOPY
        elif mbi.is_writeable():
            prot = None
        elif mbi.is_executable():
            prot = win32.PAGE_EXECUTE_READWRITE
        else:
            prot = win32.PAGE_READWRITE
        if prot is not None:

In my case, I'm debugging a process that communicates with another via a shared memory section (via CreateFileMappingW with INVALID_HANDLE_VALUE and MapViewOfFile). When I attempt to write to this shared section, poke_dword will first attempt to detect the page protections and, if it's an image or mapped, mprotect it with PAGE_WRITECOPY, even if the section is writable. This causes the parent process to lock up and/or crash.

A couple things are unclear to me:

  1. Why mprotect a shared memory section PAGE_WRITECOPY if it's writable?
  2. Why check a mapped section's protection if it's writable?
  3. Why would this cause other processes sharing/accessing the section to crash/freeze?

I was able to fix this by simply switching the order of the checks:

if mbi.is_writeable():
    prot = None
elif mbi.is_image() or mbi.is_mapped():
    prot = win32.PAGE_WRITECOPY
elif mbi.is_executable():
    prot = win32.PAGE_EXECUTE_READWRITE
else:
    prot = win32.PAGE_READWRITE

I haven't fully debugged the root cause, but I do think the PAGE_WRITECOPY is at fault here. I'm also not sure what implications my fix may have under other scenarios.