Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Windows Hot Patching Mechanism Explained
Bartosz Wójcik
Bartosz Wójcik

Posted on • Edited on

     

Windows Hot Patching Mechanism Explained

Hot Patching is a mechanism introduced in Windows XP if I remember correctly. It was created to solve the problems with hooking system library functions. For example to bugfix compatibility issues with older software running on a newer Windows version or applying security patches on the running machines.

How function hooking works at a low-level?

Normally hooking a function in DLL libraries or EXE files is about getting the memory address of the function and putting a so-calledtrampoline (a jump) to the hook handling routine in place of its first instructions. Sounds simple, right?

Let's take a look.

Sample function prologue (beginning) before setting the hook:

_function_x:pushebpmovebp,espmoveax,ecxmovedx,0400h...
Enter fullscreen modeExit fullscreen mode

Function after the hook is set:

_function_x:; transfer execution to the hooking handler; the original instructions were removed from; the function prolog to put the JMP instruction; that needs 5 bytes for encoding E9 xx xx xx xxjmp_hook_handler_after_the_trampoline:movedx,0400h..._hook_handler:; save original registers & CPU flags statespushadpushfd...; execute hooking code, manipulate original parameters etc....popfdpopad; execute the code that's been cut off; from the original function prologue...pushebpmovebp,espmoveax,ecx; return to the code after the trampoline jumpjmp_after_the_trampoline
Enter fullscreen modeExit fullscreen mode

This involves using adisassembler to get the correct size of the first instructions (different x86/x64 instructions have different sizes) and make sure to replace enough bytes (five to be exact) to fit the assemblyjmp rel32 instruction (encoded asE9 xx xx xx xx bytes).

Problems with hooking prologue code with random instructions

But what if the first instructions are something else, like acall instruction? That would require rewriting the originalcall instruction or emulating it in the hooking handler code (we need to execute it after all!). But it's just troublesome to rewrite or emulate all the possible x86 instructions.

Microsoft has met such a demand for hooking and created a hot patching mechanism. The system library functions have aspecial prologue that makes it easy to quickly set up and remove hooks without having to bother to rewrite random instructions.

Function prologue with hot patching design

System library USER32.dll in HIEW hex editor and a sample function with hot patching code structure:

Hot patching bytes

Notice the difference. It looks like this:

; 5 nop instructionsdb90h,90h,90h,90h,90h_function_x:; mov edi,edi takes 2 bytesmovedi,edipushebpmovebp,espmoveax,ecxmovedx,0400h...
Enter fullscreen modeExit fullscreen mode

In hot patching enabled binaries (you need to build it with appropriate compiler flags!) the first bytes of the functions are always themov edi,edi instruction (which does nothing by itself, it's like C++ version of0=0; statement).

Before it, there is also a window (byte array) with fivenop instructions encoded as0x90, 0x90, 0x90, 0x90 bytes.

What's the deal here, huh?

First step. Putting a hook trampoline into such a constructed function consists of inserting thejmp short (encoded as two bytesEB xx opcode) instruction into thismov edi,edi instruction place.

Second step. It jumps to the above 5xnop window, where thecall rel32 orjmp rel32 instructions are placed that jumps or calls the hook handler code.

So this time you don't have to worry about overwriting random function prologue instructions, because there is a standard construct that can be easily restored to the default value (unhooked).

The whole thing is trivially simple and allows you to quickly insert hooks without the need to use a library likeMicrosoft Detours.

Patching libraries using hot patching features

Below I present the code forMASM compiler, showing an example of setting a hook onSetWindowTextA function within our own process using hot patching code characteristics.

.data; library to set a hookszLibUserdb'USER32.dll',0; hooked function nameszSetWindowTextAdb'SetWindowTextA',0; original function address (after mov edi,edi prologue)lpOrgSetWindowTextAdd0; default short jump instruction into 5 bytes NOP window; it's encoded as a relative short jump instructioncHotPatchJmpsdb0EBh,0F9h; call _hook (E9 xx xx xx xx) instruction encodingcHotPatchCalldb0E9hdwHotPatchReldd0szHookTestdb'https://www.pelock.com',0.code; sample hook handler code; it replaced every call to:;  SetWindowTextA(hWindow, lpString);; with;  SetWindowsTextA(hWindow, "https://www.pelock.com");align4_hook_SetWindowTextAprocusesesiediebx,hWnd:dword,lpString:dword; ignore the original lpString parameter; and call the function with our bogus parameter;       push    lpString <-- original parameterpushoffsetszHookTestpushhWndcalllpOrgSetWindowTextAret_hook_SetWindowTextAendpalign4_make_hookprocusesesiediebx,hProcess:dword,lpszLib:dword,lpszProc:dword,lpOrgPtr:dword,lpHookHandlerProc:dword; check if the DLL is already loadedpushlpszLibcallGetModuleHandleAtesteax,eaxje_make_hook_exit; get the function pointerpushlpszProcpusheaxcallGetProcAddresstesteax,eaxje_make_hook_exit; save the function pointer to the EDI registermovedi,eax; check if the first bytes of the function; matches the bytes of the mov edi,edi instructioncmpwordptr[eax],0FF8Bhjne_make_hook_exit; store the pointer to the code after the mov edi,edi; instruction (where the real function starts)addeax,2movedx,lpOrgPtrmovdwordptr[edx],eax; overwrite mov edi,edi instruction; with a jump to the 5x NOP windowpushoffsetdwWrittenpush2pushoffsetcHotPatchJmpspushedipushhProcesscallWriteProcessMemory; hook handler routine addressmovedx,lpHookHandlerProc; let's build a call _hook_handler_proc instruction; 5x NOP window memory addressleaeax,[edi-5]; call instruction is built like this:;; E9 xx xx xx xx;; where xx xx xx xx is 4 bytes of the relative; address of the destination call address, relative; to the position of the call instruction itself;; if we were to call the instruction right after; any call instruction, for example like this:;; call _next_instruction_label; _next_instruction_label:; nop;; it would have been encoded as:;; E9 00 00 00 00; 90;; to calculate the relative destination address; take the destination pointer, subtract the call; instruction pointer and its size (5 bytes);; rel32 = dst - src - 5;subedx,eaxsubedx,5movdwHotPatchRel,edx; patch library function memory, by overwriting; the 5x NOP window with a call to the hooking; handler routinepushoffsetdwWrittenpush5pushoffsetcHotPatchCallpusheaxpushhProcesscallWriteProcessMemory_make_hook_exit:ret_make_hookendpalign4_test_hooksprocusesesiediebx; our process IDcallGetCurrentProcessId; open our own processpusheaxpush1pushPROCESS_ALL_ACCESScallOpenProcesstesteax,eaxje_exitmovebx,eax; setup a hookmovedi,offset_make_hookpushoffset_hook_SetWindowTextA; hook procpushoffsetlpOrgSetWindowTextA; &lpOrgProcpushoffsetszSetWindowTextA; szApiNamepushoffsetszLibUser; szLibNamepushebx; hProcesscalledi;_make_hook_exit:ret_test_hooksendp
Enter fullscreen modeExit fullscreen mode

As you can see, hot patching can be used not only by Windows, but we can use it too to our advantage.

More low-level and reverse engineering resources

If you are interested in similar security and low-level topics, I invite you to read my articles aboutreverse engineering, malware analysis & assembler.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Reverse engineering services (source code recovery, legacy software modification, recovering software algorithms). Software protection, monetization & licensing solutions for developers.
  • Joined

More fromBartosz Wójcik

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp