Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results
The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.
Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/
Hello folks,
I am trying to call MmCopyVirtualMemory but it keeps returning 0x8000000d. just to give some context: The code is running in the right process context and the virtual address is valid. The virtual address in this case basically an address where my DLL is mapped. I am trying to write something to the in memory image using MmCopyVirtualMemory. !vad on the address indicates that it is EXECUTE_WRITECOPY. I was under the impression that if anything is written to a page with EXECUTE_WRITECOPY protection, a private copy of the page will be created for that process. However, I am seeing MmCopyVirtualMemory consistently failing with error 0x8000000d.
And idea what could be going on? Thanks!
Upcoming OSR Seminars | ||
---|---|---|
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead! | ||
Writing WDF Drivers | 7 Dec 2020 | LIVE ONLINE |
Internals & Software Drivers | 25 Jan 2021 | LIVE ONLINE |
Developing Minifilters | 8 March 2021 | LIVE ONLINE |
Comments
MmCopyVirtualMemory (which is undocumented) is designed for copying from user process to user process. Are you copying from kernel to user? If so, then why not just ProbeForWrite and use RtlCopyMemory?
Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.
Thanks Tim. I am able to copy from user space address to kernel buffer but not copy it back. I am using the PreviousMode as KernelMode.
I did try that before trying the MmCopyVirtualMemory function. ProbeForWrite raises an exception even though the protection flags are EXECUTE_WRITECOPY.
.....which means the target virtual address is simply invalid. The most likely scenario here is that you are in the wrong process context.
BTW, have you ever heard of IoAllocateMdl(), MmProbeAndLockPages() and MmMapLockedPagesSpecifyCache() functions? This is how one is supposed to access the userland from the KM driver. You would not have to post your question here if you took this option....
Anton Bassov
Couple of things.
- I have already tried the RtlCopyMemory route, probing and Locking the pages and creating an MDL. All result in an exception.
- Although I am doing this from load image notification routine where the process context is correct, I have tried the KeStackAttachProcess too; that didn’t help either.
- Now coming to whether memory is valid. I am pretty sure the memory is valid because I am first reading from the exact same location and copying it in a kernel buffer and then modifying the kernel buffer and copying it back. And I can see in the debugger that buffer has the right expected contents after reading. So I am pretty sure the address is valid; it’s the copy operation from kernel to user buffer that fails. Other way round it works.
- !vad also works correctly on the user address and shows the protection type as EXECUTE_WRITECOPY
The key issue that I am trying to figure out is why I am unable to write to an address which has EXECUTE_WRITECOPY protection.
OMG - I completely overlooked this part.
If a page is mapped as a copy-on-write one, what else should one expect if they try to write to it???? Of course you are getting an exception - after all, this is how copy-on-write is meant to work. When you try to modify a copy-on-write page, the CPU raises page fault exception, because the target page is, in actuality, mapped as a RO one in its PTE. The page fault handler allocates a new page, copies the contents of the old one to it , and modifies the target PTE, so that the target address gets backed up by the newly-allocated physical page. This page gets mapped as a writable one, so that you can modify it without any problem.
... simply because the target page is mapped as a RO one at the moment. Otherwise, the very concept of COW simply would not work...
The above mentioned sequence would happen transparently to your code if you did it from the userland, but you are trying to do it from a driver. Apparently, page fault handler does not even check this part if you do it from the KM, and dispatches the exception to the "culprit" straight away.
BTW, what are you trying to do? Are you trying to modify some DLL's executable code or what?
Anton Bassov