ReadProcessMemory using priviledged handle from ZwOpenProcess?

So, I was reading up on this thread right here:

https://www.osronline.com/ShowThread.cfm?link=272750

I was able to get everything to work… with a non protected process. I
have the same goal as the OP of the thread, yet when I try to use
ReadProcessMemory using a handle opened by ZwOpenProcess
(PROCESS_ALL_ACCESS), I get error 5 - access denied. Is there a specific
way that I can Read/Write memory using ring 3 functions (ReadProcessMemory,
WriteProcessMemory) using that privileged handle I receive from
ZwOpenProcess rather than having to use Ring 0 memory manipulation
functions? (MmCopyVirtualMemory, RtlCopyMemory, etc)

if you open process with PROCESS_VM_READ - you can read it memory. i sure that error was not in ReadProcessMemory but in ZwOpenProcess - you simply fail open protected process and really have no handle, but forget check NTSTATUS (it was c0000005), error 5 - this is win32 error value in TEB, can be from previous call (from OpenProcess for example :slight_smile: )

ZwOpenProcess does return a handle and the NTSTATUS is 0… The ReadProcessMemory is the one that’s returning (error wise) 5.

On Jun 1, 2016, at 1:41 AM, xxxxx@live.com wrote:

if you open process with PROCESS_VM_READ - you can read it memory. i sure that error was not in ReadProcessMemory but in ZwOpenProcess - you simply fail open protected process and really have no handle, but forget check NTSTATUS (it was c0000005), error 5 - this is win32 error value in TEB, can be from previous call (from OpenProcess for example :slight_smile: )


NTDEV is sponsored by OSR

Visit the list online at: http:
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

if you have handle to process - STATUS_ACCESS_DENIED from ZwReadVirtualMemory you can got only if handle have not PROCESS_VM_READ. even for protected processes. if no mistake - must work. and what you mean under ‘privileged handle’ ?

I opened a privileged handle (PROCESS_ALL_ACCESS using ZwOpenProcess. I send this handle to an application running in user mode, which takes the handle and uses it for ReadProcessMemory. I get access denied from ReadProcessMemory, yet STATUS_SUCCESS from ZwOpenProcess.

On Jun 1, 2016, at 8:33 AM, xxxxx@live.com wrote:

if you have handle to process - STATUS_ACCESS_DENIED from ZwReadVirtualMemory you can got only if handle have not PROCESS_VM_READ. even for protected processes. if no mistake - must work. and what you mean under ‘privileged handle’ ?


NTDEV is sponsored by OSR

Visit the list online at: http:
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

in this case i sure you mistake in some place. ZwReadVirtualMemory return STATUS_ACCESS_DENIED only if handle without PROCESS_VM_READ. even for protected process this true (some api, like NtDebugActiveProcess do extra check on process handle (PspCheckForInvalidAccessByProtection) - but error here another - STATUS_PROCESS_IS_PROTECTED (ERROR_PROCESS_IS_PROTECTED for win32) and ZwReadVirtualMemory not do this extra checks). if by mistake return kernel handle to user space - error will be STATUS_INVALID_HANDLE. so again ZwReadVirtualMemory return (across ObReferenceObjectByHandle) STATUS_ACCESS_DENIED only if handle without PROCESS_VM_READ. try for example before use handle check it access mask

For clarification, I am calling ring 3 functions (ReadProcessMemory) using the handle returned by ZwOpenProcess. I know this works, because I tried reading memory from an unprotected process (minesweeper) via the handle given to me by ZwOpenProcess. What is the protected process doing that is blocking ReadProcessMemory even though I have a handle with PROCESS_ALL_ACCESS?

On Jun 1, 2016, at 9:52 AM, xxxxx@live.com wrote:

in this case i sure you mistake in some place. ZwReadVirtualMemory return STATUS_ACCESS_DENIED only if handle without PROCESS_VM_READ. even for protected process this true (some api, like NtDebugActiveProcess do extra check on process handle (PspCheckForInvalidAccessByProtection) - but error here another - STATUS_PROCESS_IS_PROTECTED (ERROR_PROCESS_IS_PROTECTED for win32) and ZwReadVirtualMemory not do this extra checks). if by mistake return kernel handle to user space - error will be STATUS_INVALID_HANDLE. so again ZwReadVirtualMemory return (across ObReferenceObjectByHandle) STATUS_ACCESS_DENIED only if handle without PROCESS_VM_READ. try for example before use handle check it access mask


NTDEV is sponsored by OSR

Visit the list online at: http:
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

I’ll give screenshots when I get to a computer

On Jun 1, 2016, at 9:52 AM, xxxxx@live.com wrote:

in this case i sure you mistake in some place. ZwReadVirtualMemory return STATUS_ACCESS_DENIED only if handle without PROCESS_VM_READ. even for protected process this true (some api, like NtDebugActiveProcess do extra check on process handle (PspCheckForInvalidAccessByProtection) - but error here another - STATUS_PROCESS_IS_PROTECTED (ERROR_PROCESS_IS_PROTECTED for win32) and ZwReadVirtualMemory not do this extra checks). if by mistake return kernel handle to user space - error will be STATUS_INVALID_HANDLE. so again ZwReadVirtualMemory return (across ObReferenceObjectByHandle) STATUS_ACCESS_DENIED only if handle without PROCESS_VM_READ. try for example before use handle check it access mask


NTDEV is sponsored by OSR

Visit the list online at: http:
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

“I know this works”. i also test this - open several protected processes and read it memory - all ok, no errors.
“What is the protected process doing that is blocking ReadProcessMemory even though I have a handle with PROCESS_ALL_ACCESS?” - i look code of NtReadVirtualMemory and can say - nothing. some api do check for protected process PspCheckForInvalidAccessByProtection. for example NtDebugActiveProcess - even with correct handle to target process with all access - call to NtDebugActiveProcess fail, if you call it not from another protected process (and it protection no less than target process). but NtReadVirtualMemory not do this checks (in latest win 10 too) - so must work with correct handle

Hmm. Well, I’ll post some screenshots when I’m at a computer. The process itself it protected by a kernel driver of its own. I checked in SSDT with PChunter and it does not show that the process is hooking ZwOpenProcess or anything, this is why I’m confused. Maybe screenshots will help.

On Jun 1, 2016, at 12:05 PM, xxxxx@live.com wrote:

“I know this works”. i also test this - open several protected processes and read it memory - all ok, no errors.
“What is the protected process doing that is blocking ReadProcessMemory even though I have a handle with PROCESS_ALL_ACCESS?” - i look code of NtReadVirtualMemory and can say - nothing. some api do check for protected process PspCheckForInvalidAccessByProtection. for example NtDebugActiveProcess - even with correct handle to target process with all access - call to NtDebugActiveProcess fail, if you call it not from another protected process (and it protection no less than target process). but NtReadVirtualMemory not do this checks (in latest win 10 too) - so must work with correct handle


NTDEV is sponsored by OSR

Visit the list online at: http:
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

“The process itself it protected by a kernel driver of its own.” - need be say this at begin. this change situation. but in clean widows - if you got handle of any process (protected too) with PROCESS_VM_READ - ZwReadVirtualMemory must work

Sorry, I forgot to mention that in the beginning. I’ll get the screenshots asap.

On Jun 1, 2016, at 12:18 PM, xxxxx@live.com wrote:

“The process itself it protected by a kernel driver of its own.” - need be say this at begin. this change situation. but in clean widows - if you got handle of any process (protected too) with PROCESS_VM_READ - ZwReadVirtualMemory must work


NTDEV is sponsored by OSR

Visit the list online at: http:
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

Dan,

Something on the system is using ObRegisterCallbacks to filter the ZwOpenProcess. For compatibility, such calls are “filtered”, as in, you get less access rights than you asked for, but still STATUS_SUCCESS. You should use !handle or Process Hacker to actually confirm the access rights. You’ll see that you probably didn’t actually get PROCESS_VM_READ, even if you asked for it and got back success.

You can see registered filters by dumping the CallbackList with !list in the nt!PsProcessType (poi this and cast as nt!_OBJECT_TYPE*).


Best regards,
Alex Ionescu

Why don’t you read the process memory in kernel mode and fill the user buffer with that data ?

If you can pass a handle, you can also pass the memory content of a remote process.

Yeah. I decided to go with that route, and I’m able to read/write memory
now, and I’ve been testing it on the timer in minesweeper. BUT…

For some particularly odd reason, when I READ memory, the value is printed
out in console and Dbgview, but
the timer resets to 1! I’ve tested it with other programs and it seems that
the memory is zeroed out, even though it’s just being read.
Attaching some screenshots… hopefully I didn’t do anything TOO stupid.

http://imgur.com/a/xIAMF

On Wed, Jun 1, 2016 at 5:48 PM, wrote:

> Why don’t you read the process memory in kernel mode and fill the user
> buffer with that data ?
>
> If you can pass a handle, you can also pass the memory content of a remote
> process.
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:>