Skip to content
Tom's Software Emporium

Divert X86 Hotpatching

Extend and Secure Legacy Software with Hotpatching via Function Hooking

In today's dynamic software environment, it's not uncommon to find yourself needing to extend, modify, or secure software for which the original source code is unavailable. Whether you need to patch vulnerabilities or enhance the functionality of a third-party application, the ability to inject custom logic into existing binaries becomes indispensable. Enter the Divert X86 Hotpatching Library, a powerful C-based solution that enables you to hook functions in x86 programs and modify their behavior at runtime.

This hotpatching library allows developers to seamlessly insert custom code before or after existing functions, or even entirely replace functions within programs. With this approach, developers gain the power to patch vulnerabilities, sanitize inputs, log additional information, and much more-all without needing source code access.

In fact DivertX86 has been successfully used in modding the game Antinomy of Common Flowers to improve it's multiplayer networking code and synchronization. [Link to Mod]

Why Hotpatching?

Hotpatching is especially useful when dealing with legacy software or closed-source applications where traditional means of modifying or extending the software aren't possible. It offers a way to harden security or extend functionality in situations where recompiling or refactoring the original program isn't an option. For example, you may encounter a scenario where you need to patch a vulnerability in a legacy system by modifying how certain parameters are handled or inserting validation logic, and hotpatching enables that in a minimally-invasive manner.

Key Features

  1. Function Hooking & Extension: The library allows developers to inject custom code before and after an existing function executes, letting you extend the behavior of the function in any way you need.

  2. Complete Function Replacement: When a function needs to be completely replaced, the hotpatching library allows for total control. Replace outdated or faulty functionality with your own logic, while still being able to call back to the original function when needed.

  3. Flexible Hotpatch Awareness: The library works for both binaries that were specifically compiled with hotpatching in mind and those that weren't. Many modern programs have 5-byte padding and a two-byte NOP instruction (e.g., MOV EDI, EDI) emitted before the function prolog to make patching easier, which are utilized if available. However, even if a program wasn't compiled with such accommodations, the library can safely disassemble, adjust, and reassemble the first few instructions of the function to hook it properly.

  4. Safe Disassembly & Reassembly: When hotpatching functions, the library takes care of disassembling the first few bytes of the function and moving them elsewhere. This enables you to insert a jump to your custom code without losing any of the original functionality. It even adjusts for relative jumps and other complex instructions like JCXZ and LOOP, ensuring that all jumps still point to the correct destinations after the patch is applied.

  5. Comprehensive Instruction Support: The library handles a wide range of x86 instructions, even tricky ones that lack wide forms, like JCXZ and LOOP. This careful attention to detail ensures that almost any function can be patched, regardless of its complexity or if it was originally written in assembly.

  6. Trampoline Management: With the provided API, you can store the patched function's trampoline either in its prolog padding or in a separate memory location, depending on the needs of your application.

Patch Vulnerabilities & Improve Security

One of the most important use cases for hotpatching is vulnerability patching. By intercepting a function at the binary level, you can sanitize inputs, modify parameters, or even override return values to prevent known security vulnerabilities from being exploited. This is invaluable in environments where the source code is unavailable or difficult to modify, such as proprietary software, outdated systems, or third-party libraries.

API Overview

The library provides a simple C API that enables function patching in various ways:

  1. HotpatchTT:

    • Hotpatches a function and stores the trampoline (the original bytes of the patched function) in the target's padding.
    • unsigned int HotpatchTT(void* fTarget, void* fNew);
    • This is the most straightforward way to patch functions that were compiled with padding for hotpatching.
  2. HotpatchTTRZ:

    • Hotpatches a function to immediately return zero, with optional callee cleanup by modifying the stack.
    • unsigned int HotpatchTTRZ(void* fTarget, unsigned short addEsp);
    • This function can be particularly useful in bypassing faulty or dangerous code by making the function return a harmless value.
  3. HotpatchXT:

    • Hotpatches a function and stores the trampoline (the original instructions) at a specified location.
    • void* HotpatchXT(void* fTarget, void* fNew, void* fTrampoline, unsigned int trLen);
    • This offers maximum control, as it allows you to specify exactly where the trampoline will be stored, giving you flexibility for more complex patches.

Get Started with Divert X86

Ready to extend the capabilities of your software or patch vulnerabilities at runtime? The following guide will help you get started quickly, walking you through the basic setup and demonstrating how to hook and patch functions in your target application.

Getting Started DivertX86

Ready to extend the capabilities of your software or patch vulnerabilities at runtime? This guide will help you get started quickly with the x86 Hotpatching Library, walking you through the basic setup and demonstrating how to hook and patch functions in your target application.

Step 1: Download and Link the Library

First, obtain the x86 Hotpatching Library in its DLL form. Once you've downloaded it, you need to link it to your C/C++ project. If you're using a build system like Make or an IDE like Visual Studio, follow the steps below to integrate the library.

For Visual Studio:

  1. Go to Project Properties > Linker > Input.
  2. Add the hotpatching library (DLL) to Additional Dependencies.
  3. Include the header file for the library in your project:
    #include "hotpatch.h"

For Makefile-based Projects:

Add the library to your Makefile:

LDFLAGS += -L/path/to/hotpatching/library -lhotpatching

And include the library's header in your source files:

#include "hotpatch.h"

Step 2: Basic Example - Hooking a Function

Let's assume you want to hook a function in a program and execute some custom code before or after it. The function you're targeting could look something like this:

int targetFunction(int param) {
    // Some logic
    return param * 2;
}

To hook this function, you'll write a new function that will be executed in its place. You can choose whether your new function calls the original one or completely replaces it.

Here's how you might define the new function:

int customFunction(int param) {
    printf("Custom code before original function\n");

    // Call the original function (via a trampoline)
    int result = trampoline(param);

    printf("Custom code after original function\n");

    return result;
}

Step 3: Applying the Hook

To apply the hook using the library, follow these steps:

  1. Identify the address of the target function you wish to patch (in this case, targetFunction).
  2. Use the HotpatchTT function to patch the function and insert the trampoline:

    // Declare a pointer for the trampoline (somewhere customFunction can see it)
    int (*trampoline)(int);
    
    // Apply the hotpatch
    trampoline = HotpatchTT((void*)&targetFunction, (void*)&customFunction);

In this example, the HotpatchTT function installs a hook to redirect the execution of targetFunction to customFunction. The original bytes of targetFunction are moved into the function's prolog padding, allowing the original function to still be called as part of your custom logic.

Step 4: Full Function Replacement

In some cases, you may want to completely replace a function without calling the original version. To do this, simply omit the trampoline in your new function. Here's an example:

int newFunction(int param) {
    // Bypass the original function entirely
    printf("This function is fully replaced!\n");
    return 0;  // Return a custom value
}

// Apply the patch to fully replace the target function
HotpatchTT((void*)&targetFunction, (void*)&newFunction);

Step 5: Returning Zero and Cleaning Up

If you want to bypass the function entirely and make it return zero, the HotpatchTTRZ function is perfect for this. It can also manage the cleanup of the stack if necessary:

// Hotpatch the function to always return zero with 4 bytes of stack cleanup
HotpatchTTRZ((void*)&targetFunction, 4);

While HotpatchTT can accomplish this by replacing the target function with an empty function that simply returns zero, you would need to create and manage a custom replacement function for each instance, which can quickly become cumbersome.

Step 6: Advanced - Using Custom Trampolines

For more control over where the trampoline is stored, you can use HotpatchXT. This method allows you to define the location of the trampoline and the maximum length of instructions allowed to be moved.

// Define a buffer to store the trampoline (Must be executable ex. '.text' section)
unsigned char trampolineBuffer[20];

// Apply the patch and store the trampoline in the buffer
HotpatchXT((void*)&targetFunction, (void*)&customFunction, (void*)trampolineBuffer, sizeof(trampolineBuffer));

This approach is especially useful when memory constraints or specific architecture requirements come into play.

Conclusion

By following this guide, you should now have a good understanding of how to get started with hotpatching, apply basic function hooks, and leverage the library's powerful capabilities to meet your needs.

The Divert X86 Hotpatching Library is distributed as a DLL, making it easy to integrate into any project. Contact to inquire about source code access, commercial use, or other licensing options.

Download Library and Sample Project: [DivertX86.zip]