2

Someone said to do something like this to avoid scans for WPM calls:

__declspec(naked) BOOL WINAPI SafeWriteProcessMemory(HANDLE hProcess,
    LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize,
    SIZE_T *lpNumberOfBytesRead)
{
    __asm
    {
            mov edi, edi
            push ebp
            mov ebp, esp
            pop ebp
            mov eax, WriteProcessMemory
            add eax, 6
            jmp eax
    }
}

I put it in a program and debugged it in olly. I looked at kernel32.WriteProcessMemory. We're using the add eax, 6 to jump from here:

MOV EDI,EDI                              ; BOOL kernel32.WriteProcessMemory(hProcess, ...)
PUSH EBP
MOV EBP,ESP
POP EBP
JMP <JMP.&API-MS-Win-Core-Memory-L1-1-0. ; Jump to KERNELBASE.WriteProcessMemory

To there. Effectively skipping over the instructions between the two. We're executing those instructions in our own call. But I don't understand why those instructions are being executed. We're pushing EBP onto the stack, moving ESP into EBP, then restoring EBP from the stack. That shouldn't actually be doing anything.

I debugged it instruction-by-instruction, and still can't figure out why it's being done.

Does it have something to do with Windows' useless mov edi,edis at the beginning of functions to allow jump patching?

2 Answers 2

2

This is the "stolen bytes" technique, where the first few bytes of the function are copied to a remote location and executed from there, then the original function is called from the location after the bytes that were copied.

The purpose of skipping the first few bytes of the function allows you to call the function body without being "detected". That is, any code which detoured the function at exactly the start would be bypassed.

In your example, the EBP manipulation is meaningless. Those instructions exist in the original function in order to provide a familiar signature for routines that, for example, detour the code (but which is presumably broken by also including the hot-patching support). Note that the POP instruction did not exist in that location before Windows 7, with the introduction of the kernelbase.dll. Previously, the real function body would have followed the MOV instruction.

3

The intention was likely to cause breakpoints set on the first instruction of WriteProcessMemory() to not fire.

However, this is a very unsafe approach and is prone to breaking should the prologue of the API function change.

4
  • Excuse my ignorance, but how would that prevent a breakpoint from firing? I set a breakpoint on the first instruction, and it fired correctly.
    – Pulpo
    Mar 4, 2015 at 22:09
  • If you set a breakpoint on WriteProcessMemory() and call SafeWriteProcessMemory(), the breakpoint won't fire. Mar 4, 2015 at 22:38
  • But doesn't Microsoft basically guaranteed that the prologue won't change (in the forseeable future) with their introduction of Hotpatching?
    – user45891
    Mar 5, 2015 at 21:24
  • No.​​​​​​​​​​​​ Mar 5, 2015 at 23:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.