Once upon a time, WriteProcessMemory and I...

Once upon a time, WriteProcessMemory and I...

Few years back I was working on the module stomping process injection technique there I noticed very unusual behavior ??. That day I noticed “WriteProcessMemory” was able to write shellcode into the “.text” of target process without needing to change the memory protection??. By default characteristics of “.text” section is set to RX (Read and Executable). And we all know if memory protection permission is not set to Writable (W), WriteProcessMemory cannot be able to write buffer in that memory region??. However, here it was able to write payload into the RX memory region ??. I was so confused at that time I had to reverse engineer the whole WriteProcessMemory APi to understand this process.

Instead of reversed code let’s go with something that’s very easy to interpret. Here’s the code implementation of WriteProcessMemory from the react os, we’ll take this as a reference.

https://doxygen.reactos.org/d9/dd7/dll_2win32_2kernel32_2client_2proc_8c_source.html#l02056

If you closely look at the line no 2073 it’s first changing the memory protection to RWX, and saving current memory protection value to OldValue local variable for restoration purpose. Then at line no 2081 the OldValue is getting bitwise AND with couple of other memory protection values. One common attribute for all those memory protection is that they all have the write attribute set. This means if OldValue has the write attribute set the Unprotect variable will set to FALSE. And if we look at line no 2085 !FALSE is TRUE and code inside if block will be executed. There it’ll simply revert back to the old memory protection (Note before reverting memory is set to RWX and it has confirmed the old memory protection has the writable permission set) and write the buffer into the memory.

This is the usual flow what about the RX region??

Above we confirmed that if OldValue (the memory protection value at the time when WriteProcessMemory being called) has writable permission set then it’ll revert back the RWX region to original state and write the buffer into the memory. Alright!! let’s go back to the line no 2081 again. What if the OldValue doesn’t have the writable permission set i.e. R, RX, X. This time the Unprotect value will be set to TRUE. And the memory region is still RWX.

Now let’s focus on the another image, if we look at line no 2118 (because if UnProtect is TRUE then !TRUE is FALSE and we’ll reach here ??) there we can see OldValue is getting checked with memory permission PAGE_NoACCESS or PAGE_READONLY (R). If OldValue is one of these two then memory protection will be reverted back to the original value and raise the STATUS_ACCESS_VIOLATION error.

However, if OldValue is not matching with any of the memory protection values that are being checked from the beginning to this point then the memory region remains RWX. At line no 2133 you can clearly see it’s writing buffer to the memory region with NT version of the API i.e., NtWriteVirtualMemory. After that it’ll revert back to the original memory protection i.e. RX or X.

Despite analyzing the code from the ReactOS, the logic remains similar on the windows as well. However, I can’t deny the fact the reversed code is huge and more stuffs going on??. Now the question is why this unusual behavior?

I can only think of one thing the debuggers. If you know any other usage of this behavior other than the debuggers let me know.

In brief, often software breakpoints in debuggers are done by replacing first byte of the assembly instruction with 0xCC (which is the op code for int3). All this happens in the memory address where we set the breakpoints??. Also, to continue the execution original assembly bytes needs to be restored. This is where the unusual behavior of the WriteProcessMemory comes into play to make such operation very efficient and error free??. Furthermore, we all know that all the executable codes are in the text section of the PE file.

People who work with debuggers, malware, or have an interest in low-level operations are already familiar with this type of information. I get to know when I was working on module stomping before that I was not aware of it.

Some information cannot always be found within the documentation; sometimes, we must explore, and that's where usually tricks and bugs are born.??

Richard R.

Site Reliability Engineer/Cyber Security

1 年

Here is yet another example of systems artifacts in action. These abilities need more attention from the support staff. This isn't something that security by obscurity will work against. Certificates won't protect against them. People who know AND understand will protect them.

Thiago Peixoto

Reverse Engineer | Offensive Security Researcher | Speaker

1 年

I'm gonna leave a comment here to test something crazy and I'll let you know if it works, hahaha.

要查看或添加评论,请登录

John Sherchan的更多文章

社区洞察

其他会员也浏览了