### Dobby Hook Installation Example Source: https://github.com/jmpews/dobby/blob/master/_autodocs/internal-architecture.md Illustrates the core Dobby API for installing hooks, resolving symbols, and monitoring code. Use this as a starting point for custom plugin development. ```c #include "dobby.h" // Install hooks via DobbyHook // Use DobbySymbolResolver to find symbols // Monitor via DobbyInstrument // Create your own routing mechanisms ``` -------------------------------- ### Build Example Programs Source: https://github.com/jmpews/dobby/blob/master/_autodocs/build-configuration.md Enable the building of example programs, such as the basic 'main' example and the 'socket_example'. ```bash cmake -DDOBBY_BUILD_EXAMPLE=ON .. ``` -------------------------------- ### Build Examples Subdirectory Source: https://github.com/jmpews/dobby/blob/master/CMakeLists.txt Includes the 'examples' subdirectory if DOBBY_BUILD_EXAMPLE is enabled and DOBBY_BUILD_KERNEL_MODE is disabled. This allows building example projects conditionally. ```cmake if (DOBBY_BUILD_EXAMPLE AND (NOT DOBBY_BUILD_KERNEL_MODE)) add_subdirectory(examples) endif () ``` -------------------------------- ### Install and Remove Temporary Hook (C) Source: https://github.com/jmpews/dobby/blob/master/_autodocs/usage-patterns.md Demonstrates how to install a hook, use the original function, and then remove the hook. Ensure the target address is valid and the hook is destroyed when no longer needed. ```c #include "dobby.h" typedef void (*target_func_t)(void); target_func_t orig_func = NULL; void fake_func(void) { printf("Hook active\n"); orig_func(); } void temporary_hook_example() { void *target_addr = DobbySymbolResolver(NULL, "some_function"); // Install hook DobbyHook(target_addr, (void *)fake_func, (void **)&orig_func); printf("Hook installed\n"); // Use with hook active // ... call code that uses some_function() ... // Remove hook int ret = DobbyDestroy(target_addr); if (ret == 0) { printf("Hook removed\n"); } } ``` -------------------------------- ### Example Usage of install_hook_name Macro Source: https://github.com/jmpews/dobby/blob/master/_autodocs/api-signatures.md Demonstrates how to use the install_hook_name macro to hook the 'open' function. This example defines a fake 'open' function that prints a message before calling the original 'open' function. ```c install_hook_name(open, int, const char *path, int flags) { printf("open called: %s\n", path); return orig_open(path, flags); } // Creates: // - fake_open() function // - orig_open() pointer to original // - install_hook_open(void *sym_addr) installation function ``` -------------------------------- ### Install and Build Dobby Source: https://github.com/jmpews/dobby/blob/master/_autodocs/README.md Clone the Dobby repository, navigate to the directory, create a build directory, configure the build with CMake, and compile the project using make. Ensure you have the necessary build tools installed. ```bash git clone https://github.com/jmpews/Dobby.git cd Dobby mkdir cmake-build && cd cmake-build cmake -DCMAKE_BUILD_TYPE=Release .. make -j4 ``` -------------------------------- ### Example Custom Plugin Development Source: https://github.com/jmpews/dobby/blob/master/_autodocs/builtin-plugins.md Demonstrates how to create a custom plugin by implementing hooks, using DobbySymbolResolver, and integrating with the build system. This example hooks the 'malloc' function and uses a callback handler. ```c #include "dobby.h" typedef void (*custom_event_handler_t)(const char *event); custom_event_handler_t g_handler = NULL; void my_malloc_hook(void *address, DobbyRegisterContext *ctx) { // Note: On x64, first arg (size) is in rdi on Unix or rcx on Windows if (g_handler) { g_handler("malloc called"); } } void init_custom_plugin(custom_event_handler_t handler) { g_handler = handler; void *malloc_addr = DobbySymbolResolver(NULL, "malloc"); DobbyInstrument(malloc_addr, my_malloc_hook); } ``` -------------------------------- ### Enable/Disable Conditional Hook (C) Source: https://github.com/jmpews/dobby/blob/master/_autodocs/usage-patterns.md Shows how to dynamically enable or disable hooks based on a runtime flag. The `setup` function installs the hook, and `set_hooks_enabled` controls its behavior. ```c #include "dobby.h" #include "stdlib.h" static int hooks_enabled = 1; typedef void* (*malloc_t)(size_t size); malloc_t orig_malloc = NULL; void *fake_malloc(size_t size) { if (hooks_enabled) { printf("malloc(%zu)\n", size); } return orig_malloc(size); } void set_hooks_enabled(int enabled) { hooks_enabled = enabled; } void setup() { void *malloc_addr = DobbySymbolResolver(NULL, "malloc"); DobbyHook(malloc_addr, (void *)fake_malloc, (void **)&orig_malloc); } ``` -------------------------------- ### Example Dobby Debug Log Output Source: https://github.com/jmpews/dobby/blob/master/_autodocs/errors.md This is an example of the detailed log output generated when Dobby is compiled with debug enabled. It shows information about hook installation and instruction relocation. ```text ----- [DobbyHook: 0x7f8b24001234] ----- origin: 0x7f8b24001234, size: 16 relocated: 0x7f8b2410ab00, size: 24 ``` -------------------------------- ### Handle Dobby Hook Installation Errors Source: https://github.com/jmpews/dobby/blob/master/_autodocs/INDEX.md Shows how to check the return value of DobbyHook and handle potential installation errors. It lists common causes for hook failures. ```c int ret = DobbyHook(addr, fake_func, &orig_func); if (ret != 0) { printf("Hook failed\n"); printf("Possible causes:\n"); printf(" - Address already hooked\n"); printf(" - Memory allocation failed\n"); printf(" - Unsupported instruction\n"); } ``` -------------------------------- ### Windows Dobby Setup Source: https://github.com/jmpews/dobby/blob/master/_autodocs/usage-patterns.md Illustrates resolving symbols from specific DLLs, such as kernel32.dll, and hooking functions like CreateFileA on Windows using Dobby. ```c #include "dobby.h" void setup_windows() { // Resolve from specific DLL void *create_file = DobbySymbolResolver("kernel32.dll", "CreateFileA"); if (create_file) { DobbyHook(create_file, fake_CreateFileA, &orig_CreateFileA); } } ``` -------------------------------- ### Safe Hook Installation with Dobby Source: https://github.com/jmpews/dobby/blob/master/_autodocs/usage-patterns.md Demonstrates a safe method for installing a Dobby hook, including symbol resolution and error checking for the hook installation process. Ensure the target symbol is resolved and the hook installation returns success. ```c #include "dobby.h" #include typedef int (*open_t)(const char *path, int flags); open_t orig_open = NULL; int fake_open(const char *path, int flags) { // Implementation return orig_open(path, flags); } int safe_install_hook() { // Step 1: Resolve symbol void *target_addr = DobbySymbolResolver(NULL, "open"); if (!target_addr) { fprintf(stderr, "Error: Failed to resolve 'open'\n"); return -1; } printf("Resolved 'open' to %p\n", target_addr); // Step 2: Install hook int ret = DobbyHook(target_addr, (void *)fake_open, (void **)&orig_open); if (ret != 0) { fprintf(stderr, "Error: Failed to install hook\n"); fprintf(stderr, "Possible causes:\n"); fprintf(stderr, " - Address 0x%p already hooked\n", target_addr); fprintf(stderr, " - Insufficient memory for trampoline\n"); fprintf(stderr, " - Unsupported instruction at target\n"); return -1; } // Verify original function pointer is set if (!orig_open) { fprintf(stderr, "Error: Original function pointer not set\n"); return -1; } printf("Hook installed successfully\n"); return 0; } ``` -------------------------------- ### Install Build Dependencies on Linux Source: https://github.com/jmpews/dobby/blob/master/_autodocs/build-configuration.md Installs essential build tools like GCC and CMake on Ubuntu/Debian, CentOS/RHEL, and Fedora systems. ```bash # Ubuntu/Debian sudo apt-get install build-essential cmake # CentOS/RHEL sudo yum install gcc-c++ cmake # Fedora sudo dnf install gcc-c++ cmake ``` -------------------------------- ### install_hook_name Macro Source: https://github.com/jmpews/dobby/blob/master/_autodocs/api-signatures.md A macro helper to simplify the installation of function hooks. ```APIDOC ## install_hook_name Macro Helper ### Description This macro simplifies the process of installing function hooks by generating the necessary boilerplate code for fake functions, original function pointers, and installation functions. ### Macro Definition ```c #define install_hook_name(name, fn_ret_t, fn_args_t...) \ static fn_ret_t fake_##name(fn_args_t); \ static fn_ret_t (*orig_##name)(fn_args_t); \ static void install_hook_##name(void *sym_addr) { \ DobbyHook(sym_addr, (void *)fake_##name, (void **)&orig_##name); \ } \ fn_ret_t fake_##name(fn_args_t) ``` ### Usage Example ```c install_hook_name(open, int, const char *path, int flags) { printf("open called: %s\n", path); return orig_open(path, flags); } ``` ### Generated Components - `fake_name()`: The function that replaces the original function. - `orig_name`: A pointer to the original function. - `install_hook_name(void *sym_addr)`: The function used to install the hook at a given symbol address. ``` -------------------------------- ### macOS/iOS Symbol and Import Hooking Source: https://github.com/jmpews/dobby/blob/master/_autodocs/architecture-support.md Example of setting up hooks on macOS or iOS by resolving symbols from dyld or using import table replacement. ```c #include "dobby.h" void setup_macos() { // Resolve symbols from dyld void *dlopen_addr = DobbySymbolResolver(NULL, "dlopen"); int ret = DobbyHook(dlopen_addr, fake_dlopen, &orig_dlopen); // Or use import table replacement DobbyImportTableReplace("MyApp", "_dlopen", fake_dlopen, &orig_dlopen); } ``` -------------------------------- ### Build Dobby with CMake Source: https://github.com/jmpews/dobby/blob/master/_autodocs/INDEX.md Build Dobby using CMake. This example shows how to create a build directory, configure the build with Release type, and compile the project. ```bash mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=Release .. make -j4 ``` -------------------------------- ### Linux/Android Dobby Setup Source: https://github.com/jmpews/dobby/blob/master/_autodocs/usage-patterns.md Demonstrates how to resolve symbols from libc or any loaded library and hook functions like malloc on Linux and Android using Dobby. ```c #include "dobby.h" void setup_linux() { // Resolve from libc void *malloc_addr = DobbySymbolResolver("libc.so.6", "malloc"); // Or from any loaded library void *pthread_create = DobbySymbolResolver(NULL, "pthread_create"); if (malloc_addr) { DobbyHook(malloc_addr, fake_malloc, &orig_malloc); } } ``` -------------------------------- ### Set CMAKE_INSTALL_PREFIX Source: https://github.com/jmpews/dobby/blob/master/_autodocs/build-configuration.md Specify the installation directory when using `make install` by setting the CMAKE_INSTALL_PREFIX variable. ```bash cmake -DCMAKE_INSTALL_PREFIX=/usr/local .. make install ``` -------------------------------- ### ARM64e PAC Support Setup Source: https://github.com/jmpews/dobby/blob/master/_autodocs/architecture-support.md Illustrates setting up instrumentation on ARM64e with Pointer Authentication Code (PAC) enabled. Dobby automatically handles PAC stripping during DobbyHook, requiring no explicit user action. ```c #include "dobby.h" void setup_with_pac() { void *target = DobbySymbolResolver(NULL, "function"); // PAC stripping is handled automatically in DobbyHook // No explicit action needed from user DobbyHook(target, fake_func, &orig_func); } ``` -------------------------------- ### macOS/iOS Dobby Setup Source: https://github.com/jmpews/dobby/blob/master/_autodocs/usage-patterns.md Shows how to resolve symbols, potentially with an underscore prefix, and use import table replacement for functions like _open and _pthread_create on macOS and iOS with Dobby. ```c #include "dobby.h" void setup_macos() { // Symbols may have underscore prefix void *open_addr = DobbySymbolResolver(NULL, "_open"); // Use import table replacement DobbyImportTableReplace("MyApp", "_pthread_create", fake_pthread_create, &orig_pthread_create); } ``` -------------------------------- ### Create a Custom Dobby Plugin Source: https://github.com/jmpews/dobby/blob/master/_autodocs/INDEX.md Example of how to create a custom Dobby plugin. This involves defining a handler function and initializing the plugin to instrument a target function. ```c #include "dobby.h" void my_plugin_handler(void *address, DobbyRegisterContext *ctx) { // Custom monitoring logic } void my_plugin_init() { void *target = DobbySymbolResolver(NULL, "function"); DobbyInstrument(target, my_plugin_handler); } ``` -------------------------------- ### Build Dobby with Debug Options Source: https://github.com/jmpews/dobby/blob/master/_autodocs/build-configuration.md Builds Dobby with debug symbols and enables example and test builds. Useful for development and debugging. ```bash mkdir cmake-build-debug cd cmake-build-debug cmake -DCMAKE_BUILD_TYPE=Debug \ -DDOBBY_DEBUG=ON \ -DDOBBY_BUILD_EXAMPLE=ON \ -DDOBBY_BUILD_TEST=ON \ .. make -j4 ``` -------------------------------- ### Android Hooking with Memory Readability Source: https://github.com/jmpews/dobby/blob/master/_autodocs/architecture-support.md Example for Android showing how to make memory readable before hooking and enabling near trampolines for constrained memory environments. ```c #include "dobby.h" void setup_android() { // Memory may need to be made readable first features::android::make_memory_readable(target_addr, 4); DobbyHook(target_addr, fake_func, &orig_func); // Enable near trampolines for constrained memory dobby_set_near_trampoline(true); } ``` -------------------------------- ### Example Usage of DobbyImportTableReplace Source: https://github.com/jmpews/dobby/blob/master/_autodocs/builtin-plugins.md This example demonstrates how to replace the 'malloc' symbol imported by the 'MyApp' module with a custom 'fake_malloc' function. The original 'malloc' function address is stored in 'orig_malloc'. ```c #include "dobby.h" typedef int (*malloc_t)(size_t size); malloc_t orig_malloc = NULL; void *fake_malloc(size_t size) { printf("malloc(%zu) called\n", size); return orig_malloc(size); } void setup() { // Replace malloc imported by "MyApp" module int ret = DobbyImportTableReplace("MyApp", "malloc", (void *)fake_malloc, (void **)&orig_malloc); if (ret == 0) { printf("Import table replacement successful\n"); } } ``` -------------------------------- ### Core Functions Source: https://github.com/jmpews/dobby/blob/master/_autodocs/INDEX.md These are the primary functions for installing, managing, and interacting with hooks and instrumentation provided by Dobby. ```APIDOC ## DobbyHook() ### Description Installs an inline hook at a specified address. ### Return 0 on success, -1 on failure. ``` ```APIDOC ## DobbyInstrument() ### Description Installs instrumentation at a specified address. ### Return 0 on success, -1 on failure. ``` ```APIDOC ## DobbyDestroy() ### Description Removes previously installed hooks or instrumentation. ### Return 0 on success, -1 on failure. ``` ```APIDOC ## DobbyCodePatch() ### Description Patches code directly at a given memory address. ### Return 0 on success, a non-zero value on failure. ``` ```APIDOC ## DobbySymbolResolver() ### Description Resolves a symbol's address by its name. ### Return The symbol's address if found, otherwise NULL. ``` ```APIDOC ## DobbyGetVersion() ### Description Retrieves the current version of the Dobby library. ### Return A string representing the library version. ``` -------------------------------- ### Install Simple Function Hook with Dobby Source: https://github.com/jmpews/dobby/blob/master/_autodocs/usage-patterns.md Intercept function calls by installing a hook. Ensure the original function pointer is resolved and stored for later invocation. This is useful for modifying or logging function behavior. ```c #include "dobby.h" #include // Original function pointer typedef int (*open_t)(const char *path, int flags); open_t orig_open = NULL; // Fake/replacement function int fake_open(const char *path, int flags) { printf("Intercepted: open(\"%s\", 0x%x)\\n", path, flags); return orig_open(path, flags); } int main() { // Resolve the symbol void *open_addr = DobbySymbolResolver(NULL, "open"); if (!open_addr) { printf("Failed to resolve 'open'\\n"); return 1; } // Install the hook int ret = DobbyHook(open_addr, (void *)fake_open, (void **)&orig_open); if (ret != 0) { printf("Failed to install hook\\n"); return 1; } printf("Hook installed\\n"); // Now any call to open() will go through fake_open int fd = open("/tmp/test.txt", 0); return 0; } ``` -------------------------------- ### Define and Install Hook with Name Source: https://github.com/jmpews/dobby/blob/master/_autodocs/api-signatures.md A macro to simplify the process of defining a fake function, a pointer to the original function, and an installation function for Dobby hooks. It automatically generates names based on the provided hook name. ```c #define install_hook_name(name, fn_ret_t, fn_args_t...) \ static fn_ret_t fake_##name(fn_args_t); \ static fn_ret_t (*orig_##name)(fn_args_t); \ static void install_hook_##name(void *sym_addr) { \ DobbyHook(sym_addr, (void *)fake_##name, (void **)&orig_##name); \ } \ fn_ret_t fake_##name(fn_args_t) ``` -------------------------------- ### Clean Up Before Reinstalling Hooks Source: https://github.com/jmpews/dobby/blob/master/_autodocs/errors.md When dynamically installing many hooks, ensure you clean up any existing hooks at the target address before attempting to reinstall them. This prevents 'Address Already Hooked' errors. ```c // Always clean up before reinstalling DobbyDestroy(target_addr); DobbyHook(target_addr, new_fake_func, &orig_func); ``` -------------------------------- ### Hook a Function with Dobby Source: https://github.com/jmpews/dobby/blob/master/_autodocs/INDEX.md Demonstrates the simplest approach to hook a function using Dobby. This involves resolving the target function's address and then installing a hook with a custom fake function. ```c #include "dobby.h" typedef int (*target_t)(const char *arg); target_t orig_func = NULL; int fake_func(const char *arg) { printf("Function called with: %s\n", arg); return orig_func(arg); } void setup() { void *addr = DobbySymbolResolver(NULL, "target_function"); DobbyHook(addr, (void *)fake_func, (void **)&orig_func); } ``` -------------------------------- ### Accessing Registers in ARM64 Context Source: https://github.com/jmpews/dobby/blob/master/_autodocs/types.md Example of how to access general-purpose registers (e.g., x0) and the link register (return address) from a DobbyRegisterContext in ARM64. Demonstrates accessing floating-point registers as well. ```c void my_handler(void *address, DobbyRegisterContext *ctx) { // Access x0 (first argument register) uint64_t arg0 = ctx->general.regs.x0; // Or via array uint64_t arg0_alt = ctx->general.x[0]; // Access link register (return address) uint64_t return_addr = ctx->lr; // Access floating-point register q0 FPReg vec = ctx->floating.regs.q0; } ``` -------------------------------- ### Basic Function Hook with Dobby Source: https://github.com/jmpews/dobby/blob/master/_autodocs/README.md This C code demonstrates how to hook the 'open' function using Dobby. It defines a replacement function 'fake_open' that prints a message and then calls the original 'open' function. Ensure Dobby is correctly installed and linked. ```c #include "dobby.h" #include // Original function pointer typedef int (*open_t)(const char *path, int flags); open_t orig_open = NULL; // Replacement function int fake_open(const char *path, int flags) { printf("Intercepted: open(\"%s\", 0x%x)\\n", path, flags); return orig_open(path, flags); // Call original } int main() { // Find the function void *open_addr = DobbySymbolResolver(NULL, "open"); if (!open_addr) { printf("Symbol not found\\n"); return 1; } // Install the hook int ret = DobbyHook(open_addr, (void *)fake_open, (void **)&orig_open); if (ret != 0) { printf("Hook installation failed\\n"); return 1; } printf("Hook installed successfully\\n"); // Now any call to open() goes through fake_open int fd = open("/tmp/test.txt", 0); return 0; } ``` -------------------------------- ### Handle DobbyHook Failure and Report Causes Source: https://github.com/jmpews/dobby/blob/master/_autodocs/errors.md This example demonstrates how to check the return value of DobbyHook and print potential reasons for failure. It's useful for diagnosing issues like memory allocation problems or unsupported instruction sequences. ```c int ret = DobbyHook(target_addr, fake_func, &orig_func); if (ret != 0) { printf("Failed to create hook routing\n"); printf("Possible causes:\n"); printf(" - Insufficient memory for trampolines\n"); printf(" - Unsupported instruction sequence at target\n"); printf(" - Memory allocation outside valid range\n"); return false; } ``` -------------------------------- ### Install Instrumentation Callback - DobbyInstrument Source: https://github.com/jmpews/dobby/blob/master/_autodocs/README.md Use DobbyInstrument to monitor function calls without altering the function's behavior. A handler callback is invoked before the original function executes. ```c void handler(void *address, DobbyRegisterContext *ctx) { // This callback is invoked when the function is called // ctx contains all CPU register values } DobbyInstrument(target_address, handler); // target_address executes normally, but handler is called first ``` -------------------------------- ### Handle No Hook/Instrumentation Found for Destruction Source: https://github.com/jmpews/dobby/blob/master/_autodocs/errors.md Attempts to find and remove instrumentation at a given address. Returns -1 if no active hook or instrumentation is found. The provided example shows how to handle the return value, noting that a non-zero return may not always indicate an error. ```cpp auto entry = gInterceptor.find((addr_t)address); if (entry) { gInterceptor.remove((addr_t)address); entry->restore_orig_code(); return 0; } return -1; ``` ```c int ret = DobbyDestroy(target_addr); if (ret != 0) { printf("Warning: No hook found at address %p\n", target_addr); // May not be an error - the hook may have already been destroyed } ``` -------------------------------- ### Define Executable Target with Sources Source: https://github.com/jmpews/dobby/blob/master/examples/CMakeLists.txt Configures an executable target named 'socket_example' and specifies its source files. ```cmake add_executable(socket_example main.cc socket_example.cc ) ``` -------------------------------- ### ARM Instrumentation Handler Example Source: https://github.com/jmpews/dobby/blob/master/_autodocs/architecture-support.md An example of an instrumentation handler for ARM architecture that iterates through general-purpose registers r0-r12 and prints their values. This function is called when a hooked function is invoked. ```c void arm_handler(void *address, DobbyRegisterContext *ctx) { // Access r0-r12 for (int i = 0; i < 13; i++) { printf("r%d = 0x%x\n", i, ctx->general.r[i]); } } DobbyInstrument(target_addr, arm_handler); ``` -------------------------------- ### Build for Host with CMake Source: https://github.com/jmpews/dobby/blob/master/docs/compile.md Build the project for the host system using CMake. This involves navigating to the Dobby directory, creating a build directory, configuring with CMake, and then making the build. ```shell cd Dobby && mkdir cmake-build-host && cd cmake-build-host cmake .. make -j4 ``` -------------------------------- ### Build Dobby for Host Platform Source: https://github.com/jmpews/dobby/blob/master/_autodocs/build-configuration.md Standard build process for the host machine. Creates static and shared libraries. ```bash cd Dobby mkdir cmake-build-host cd cmake-build-host cmake .. make -j4 ``` -------------------------------- ### Check PkgConfig and Capstone/Unicorn Libraries Source: https://github.com/jmpews/dobby/blob/master/tests/CMakeLists.txt This snippet checks for the PkgConfig module and the Capstone and Unicorn libraries, printing their include and library directories. This is essential for setting up the build environment. ```cmake find_package(PkgConfig REQUIRED) pkg_check_modules(CAPSTONE REQUIRED capstone) message(STATUS "Capstone libraries: " ${CAPSTONE_LIBRARY_DIRS}) message(STATUS "Capstone includes: " ${CAPSTONE_INCLUDE_DIRS}) pkg_check_modules(UNICORN REQUIRED unicorn) message(STATUS "unicorn libraries: " ${UNICORN_LIBRARY_DIRS}) message(STATUS "unicorn includes: " ${UNICORN_INCLUDE_DIRS}) ``` -------------------------------- ### DobbyHook Source: https://github.com/jmpews/dobby/blob/master/_autodocs/api-signatures.md Installs a hook at a specified address, replacing the original function with a fake function. The original function can be retrieved. ```APIDOC ## DobbyHook ### Description Installs a hook at a specified memory address. Calls to the original address will be redirected to the `fake_func`. The original function's address can be retrieved via `out_origin_func`. ### Function Signature ```c int DobbyHook(void *address, void *fake_func, void **out_origin_func); ``` ### Parameters #### Input Parameters - **address** (`void *`) - The memory address to hook. - **fake_func** (`void *`) - A pointer to the replacement function. #### Output Parameters - **out_origin_func** (`void **`) - A pointer to a void pointer where the address of the original function will be stored. ### Returns - `0` on success. - `-1` on failure. ``` -------------------------------- ### Generate Visual Studio Project for Windows (x64) Source: https://github.com/jmpews/dobby/blob/master/_autodocs/build-configuration.md Configures the Dobby build for Visual Studio 2019 on Windows with a 64-bit architecture. This command should be run from a separate build directory. ```cmd cd Dobby mkdir cmake-build-vs cd cmake-build-vs cmake -G "Visual Studio 16 2019" -A x64 .. cmake --build . --config Release ``` -------------------------------- ### DobbyDestroy Function Signature Source: https://github.com/jmpews/dobby/blob/master/_autodocs/api-signatures.md Removes a previously installed hook or instrumentation from a given address, restoring the original code. ```c int DobbyDestroy( void *address // [in] Address to unhook ); ``` -------------------------------- ### Build for Linux with platform_builder.py Source: https://github.com/jmpews/dobby/blob/master/docs/compile.md Build for Linux using the platform_builder.py script. This requires preparing and downloading CMake and LLVM first. ```shell # prepare and download cmake/llvm sh scripts/setup_linux_cross_compile.sh python3 scripts/platform_builder.py --platform=linux --arch=all --cmake_dir=$HOME/opt/cmake-3.25.2 --llvm_dir=$HOME/opt/llvm-15.0.6 ``` -------------------------------- ### Get Dobby Version Source: https://github.com/jmpews/dobby/blob/master/_autodocs/api-signatures.md Retrieves the current version string of the Dobby library. Use this to check compatibility or log version information. ```c const char *DobbyGetVersion(void); ``` -------------------------------- ### Build Test Suite Source: https://github.com/jmpews/dobby/blob/master/_autodocs/build-configuration.md Enable the building of the Dobby test suite, which includes core hooking, instruction relocation, and platform-specific tests. ```bash cmake -DDOBBY_BUILD_TEST=ON .. ``` -------------------------------- ### DobbyHook Function Signature Source: https://github.com/jmpews/dobby/blob/master/_autodocs/api-signatures.md Installs a hook at a given address, replacing the original function with a fake function and providing a pointer to the original function. ```c int DobbyHook( void *address, // [in] Address to hook void *fake_func, // [in] Replacement function void **out_origin_func // [out] Original function pointer ); ``` -------------------------------- ### Dobby CMake Compile Definitions Source: https://github.com/jmpews/dobby/blob/master/_autodocs/internal-architecture.md Example of setting compile definitions in CMake based on the `DOBBY_DEBUG` variable. This enables debug logging when the variable is set. ```cmake if(DOBBY_DEBUG) set(compile_definitions "-DDOBBY_DEBUG") endif() ``` -------------------------------- ### Build Dobby as a Shared Library Source: https://github.com/jmpews/dobby/blob/master/_autodocs/build-configuration.md Configure Dobby to be built as a shared library (.so, .dylib, .dll). Set to OFF to build a static library. ```bash cmake -DDOBBY_GENERATE_SHARED=ON .. ``` -------------------------------- ### Link Libraries to Executable Source: https://github.com/jmpews/dobby/blob/master/examples/CMakeLists.txt Links the 'dobby' and 'logging' libraries to the 'socket_example' executable target. ```cmake target_link_libraries(socket_example dobby logging ) ``` -------------------------------- ### Enable Obfuscation (Private Option) Source: https://github.com/jmpews/dobby/blob/master/_autodocs/build-configuration.md This CMake option enables private obfuscation features. It requires a specific LLVM setup with obfuscation passes enabled. ```bash cmake -DPrivate.Obfuscation=ON .. ``` -------------------------------- ### Cross-Compile Dobby for Linux Source: https://github.com/jmpews/dobby/blob/master/_autodocs/build-configuration.md Cross-compiles Dobby for Linux using the platform_builder.py script. Requires setup of cross-compilation tools and specifies paths to CMake and LLVM. ```bash sh scripts/setup_linux_cross_compile.sh python3 scripts/platform_builder.py \ --platform=linux \ --arch=all \ --cmake_dir=$HOME/opt/cmake-3.25.2 \ --llvm_dir=$HOME/opt/llvm-15.0.6 ``` -------------------------------- ### Build for macOS with platform_builder.py Source: https://github.com/jmpews/dobby/blob/master/docs/compile.md Use the platform_builder.py script to build for macOS, supporting all architectures. ```shell python3 scripts/platform_builder.py --platform=macos --arch=all ``` -------------------------------- ### Windows Symbol Resolution and Hooking Source: https://github.com/jmpews/dobby/blob/master/_autodocs/architecture-support.md Illustrates how to resolve symbols from specific DLLs like kernel32.dll on Windows and then hook the target function. ```c #include "dobby.h" void setup_windows() { // Resolve from kernel32.dll void *create_file_addr = DobbySymbolResolver("kernel32.dll", "CreateFileA"); DobbyHook(create_file_addr, fake_CreateFileA, &orig_CreateFileA); } ``` -------------------------------- ### x86 Register Context Source: https://github.com/jmpews/dobby/blob/master/_autodocs/architecture-support.md Provides an example of accessing the general-purpose registers (eax) and the EFLAGS register for x86 (32-bit) architecture. Note that the x86 calling convention for arguments can vary. ```c // x86 register context DobbyRegisterContext ctx; uint32_t eax_val = ctx->general.regs.eax; uint32_t arg0 = ctx->general.regs.eax; // x86 calling convention varies uint32_t flags = ctx->flags; // EFLAGS ``` -------------------------------- ### Build for Android with platform_builder.py Source: https://github.com/jmpews/dobby/blob/master/docs/compile.md Build for Android using the platform_builder.py script. This requires preparing and downloading CMake, LLVM, and the Android NDK. ```shell # prepare and download cmake/llvm/ndk sh scripts/setup_linux_cross_compile.sh python3 scripts/platform_builder.py --platform=android --arch=all --cmake_dir=$HOME/opt/cmake-3.25.2 --llvm_dir=$HOME/opt/llvm-15.0.6 --android_ndk_dir=$HOME/opt/ndk-r25b ``` -------------------------------- ### Build Dobby from Xcode Source: https://github.com/jmpews/dobby/blob/master/_autodocs/build-configuration.md Compiles the Dobby project using Xcode's build system. Use the 'Release' configuration for production builds. ```bash xcodebuild -scheme dobby -configuration Release ``` -------------------------------- ### Directly Link Static Library Source: https://github.com/jmpews/dobby/blob/master/_autodocs/build-configuration.md Compile your application by directly linking the static Dobby library. Ensure the library path and include path are correctly specified. ```bash gcc -o myapp myapp.c -L./lib -ldobby -I./include ``` -------------------------------- ### Control Debug Output Verbosity (C) Source: https://github.com/jmpews/dobby/blob/master/_autodocs/usage-patterns.md Manages the verbosity of Dobby's debug logging. `setup_verbose` enables detailed logging, while `setup_quiet` restricts output to errors only. ```c #include "dobby.h" #include "logging/logging.h" void setup_verbose() { // Enable detailed debug logging logger_set_options(0, 0, 0, LOG_LEVEL_DEBUG, false, false); // Now install hooks with full debug output // ... } void setup_quiet() { // Only errors logger_set_options(0, 0, 0, LOG_LEVEL_ERROR, false, false); // Now install hooks with minimal output // ... } ``` -------------------------------- ### Disable Debug Output at Runtime Source: https://github.com/jmpews/dobby/blob/master/_autodocs/errors.md Configure Dobby's logging options at runtime to suppress detailed debug output, even if compiled with debug enabled. This example sets the logging level to ERROR. ```c #include "logging/logging.h" // Set minimal logging logger_set_options(0, 0, 0, LOG_LEVEL_ERROR, false, false); ``` -------------------------------- ### Define Shared Library Target Source: https://github.com/jmpews/dobby/blob/master/examples/CMakeLists.txt Configures a shared library target named 'socket_example_lib' and specifies its source file. ```cmake add_library(socket_example_lib SHARED socket_example.cc ) ``` -------------------------------- ### Install Non-Invasive Instrumentation with Dobby Source: https://github.com/jmpews/dobby/blob/master/_autodocs/usage-patterns.md Monitor function calls without altering their behavior using DobbyInstrument. This is ideal for logging or debugging purposes. The handler function receives the function address and register context. ```c #include "dobby.h" #include void instrument_handler(void *address, DobbyRegisterContext *ctx) { printf("Function at %p was called\\n", address); // On ARM64, first argument is in x0 #ifdef __aarch64__ printf(" First argument: 0x%lx\\n", ctx->general.regs.x0); printf(" Return address: 0x%lx\\n", ctx->lr); #endif } int main() { void *target = DobbySymbolResolver(NULL, "malloc"); int ret = DobbyInstrument(target, instrument_handler); if (ret != 0) { printf("Failed to install instrumentation\\n"); return 1; } printf("Instrumentation installed\\n"); // malloc calls will be logged but behavior unchanged void *mem = malloc(100); return 0; } ``` -------------------------------- ### Install Inline Function Hook - DobbyHook Source: https://github.com/jmpews/dobby/blob/master/_autodocs/README.md Use DobbyHook to replace a function with a custom version while retaining the ability to call the original function. The original function pointer is provided via the third argument. ```c DobbyHook(target_address, fake_function, &original_function_pointer); // Now calls to target_address will execute fake_function // fake_function can call *original_function_pointer to invoke original ``` -------------------------------- ### Enable Near Trampolines for Memory Allocation Failures Source: https://github.com/jmpews/dobby/blob/master/_autodocs/errors.md When encountering memory allocation failures due to installing many hooks, enable near trampolines to reduce memory pressure. This is a configuration option to optimize memory usage. ```c // Enable near trampolines to reduce memory pressure dobby_set_near_trampoline(true); ``` -------------------------------- ### Troubleshoot Compilation Errors on ARM/ARM64 Source: https://github.com/jmpews/dobby/blob/master/_autodocs/build-configuration.md Ensure ARM-specific assembler support is available and that your PATH includes the necessary assembler executables. ```bash # Ensure assembler is available which arm-linux-gnueabihf-as # ARM which aarch64-linux-gnu-as # ARM64 # Update PATH if needed export PATH=/usr/bin:$PATH ``` -------------------------------- ### Build for iPhoneOS with platform_builder.py Source: https://github.com/jmpews/dobby/blob/master/docs/compile.md Use the platform_builder.py script to build for the iPhone operating system, supporting all architectures. ```shell python3 scripts/platform_builder.py --platform=iphoneos --arch=all ``` -------------------------------- ### Hook Bionic Linker Symbols on Android Source: https://github.com/jmpews/dobby/blob/master/_autodocs/builtin-plugins.md Demonstrates how to use DobbySymbolResolver to get addresses of Bionic linker functions like dlopen and dlsym, and then hook them using DobbyHook. This is useful for intercepting dynamic library loading and symbol resolution on Android. ```c #include "dobby.h" void setup_android() { // Use symbol resolver with Bionic void *dlopen_addr = DobbySymbolResolver(NULL, "dlopen"); void *dlsym_addr = DobbySymbolResolver(NULL, "dlsym"); DobbyHook(dlopen_addr, fake_dlopen, &orig_dlopen); DobbyHook(dlsym_addr, fake_dlsym, &orig_dlsym); } ``` -------------------------------- ### Linux Symbol Resolution and Hooking Source: https://github.com/jmpews/dobby/blob/master/_autodocs/architecture-support.md Demonstrates how to resolve symbols from libc or other loaded shared libraries on Linux and then apply a Dobby hook. ```c #include "dobby.h" void setup_linux() { // Resolve from libc void *open_addr = DobbySymbolResolver("libc.so.6", "open"); // Or from any loaded library void *pthread_create_addr = DobbySymbolResolver(NULL, "pthread_create"); DobbyHook(open_addr, fake_open, &orig_open); } ``` -------------------------------- ### Dobby Core Operations Source: https://github.com/jmpews/dobby/blob/master/_autodocs/00-START-HERE.md Demonstrates the three main operations provided by Dobby: hooking, instrumenting, and destroying hooks. Include 'dobby.h' for these functions. ```c #include "dobby.h" // 1. Hook a function (replace it) DobbyHook(address, fake_func, &orig_func); // Calls to address now execute fake_func // fake_func can call orig_func() for the original // 2. Instrument a function (monitor without changing) DobbyInstrument(address, callback); // When address is called, callback is invoked with register state // 3. Remove a hook/instrumentation DobbyDestroy(address); // Restores original behavior ``` -------------------------------- ### Troubleshoot CMake Configuration Source: https://github.com/jmpews/dobby/blob/master/_autodocs/build-configuration.md If CMake configuration fails, check the CMake version (requires 3.5+) and use `--debug-output` for detailed error messages. ```bash cmake --version # Check version (requires 3.5+) cmake --debug-output .. # See detailed output ``` -------------------------------- ### Build Dobby with MinGW on Windows Source: https://github.com/jmpews/dobby/blob/master/_autodocs/build-configuration.md Compiles Dobby on Windows using MinGW Makefiles. This command generates build files and then invokes make with parallel jobs. ```bash cd Dobby mkdir cmake-build-mingw cd cmake-build-mingw cmake -G "MinGW Makefiles" .. make -j4 ``` -------------------------------- ### Include Directories Configuration Source: https://github.com/jmpews/dobby/blob/master/CMakeLists.txt Configures include directories for the Dobby project. Includes conditional directories for Darwin systems when not building kernel mode. ```cmake include_directories( . ./include ./source source/dobby ./external ./external/logging ./builtin-plugin ) if (SYSTEM.Darwin AND (NOT DOBBY_BUILD_KERNEL_MODE)) include_directories( source/Backend/UserMode ) endif () ``` -------------------------------- ### Add External OS Base Library Source: https://github.com/jmpews/dobby/blob/master/CMakeLists.txt Adds the external OS base library as a subdirectory. ```cmake # add osbase library add_subdirectory(external/osbase) ``` -------------------------------- ### Build Dobby for Android Source: https://github.com/jmpews/dobby/blob/master/_autodocs/INDEX.md Command to build Dobby for Android. Specify the platform, architecture, and the path to your Android NDK directory. ```bash python3 scripts/platform_builder.py \ --platform=android \ --arch=all \ --android_ndk_dir=$HOME/opt/ndk-r25b ``` -------------------------------- ### Process Runtime Information Source: https://github.com/jmpews/dobby/blob/master/_autodocs/internal-architecture.md Provides access to runtime process information, including loaded modules and memory layout. Use this to inspect the current process's runtime environment. ```c++ struct RuntimeModule { void *base; char path[1024]; }; class ProcessRuntime { static const stl::vector &getMemoryLayout(); static const stl::vector &getModuleMap(); static RuntimeModule getModule(const char *name); }; ``` -------------------------------- ### Build Dobby on Linux Source: https://github.com/jmpews/dobby/blob/master/_autodocs/build-configuration.md Compiles Dobby on Linux using CMake and Make. It creates a build directory and utilizes all available processor cores for faster compilation. ```bash cd Dobby mkdir cmake-build-linux cd cmake-build-linux cmake -DCMAKE_BUILD_TYPE=Release .. make -j$(nproc) ``` -------------------------------- ### Dobby Platform Detection Macros Source: https://github.com/jmpews/dobby/blob/master/_autodocs/api-signatures.md Preprocessor macros for detecting the target operating system platform (macOS/iOS, Linux, Windows, Android). ```c #if defined(__APPLE__) // macOS/iOS #elif defined(__linux__) // Linux #elif defined(_WIN32) || defined(_WIN64) // Windows #elif defined(__ANDROID__) // Android #endif ``` -------------------------------- ### Add X64 Test Executable Source: https://github.com/jmpews/dobby/blob/master/tests/CMakeLists.txt Configures the 'test_insn_relo_x64' executable, linking it with Capstone and Unicorn libraries and defining architecture-specific compile flags for X64. ```cmake add_executable(test_insn_relo_x64 test_insn_relo_x64.cpp UniconEmulator.cpp ${DOBBY_SOURCES} ) target_compile_definitions(test_insn_relo_x64 PUBLIC LOGGING_DEBUG=1 DISABLE_ARCH_DETECT=1 TARGET_ARCH_X64=1 TEST_WITH_UNICORN=1 # TARGET_ARCH_IA32=1 ) target_include_directories(test_insn_relo_x64 PUBLIC ${CAPSTONE_INCLUDE_DIRS} ${UNICORN_INCLUDE_DIRS} ) target_link_directories(test_insn_relo_x64 PUBLIC ${CAPSTONE_LIBRARY_DIRS} ${UNICORN_LIBRARY_DIRS} ) target_link_libraries(test_insn_relo_x64 PUBLIC ${CAPSTONE_LIBRARIES} ${UNICORN_LIBRARIES} ) ``` -------------------------------- ### Instrument Socket and Connect Functions Source: https://github.com/jmpews/dobby/blob/master/_autodocs/builtin-plugins.md This snippet demonstrates how to instrument the 'socket' and 'connect' functions using Dobby's instrumentation API. It logs network operations when these functions are called. ```c #include "dobby.h" // Instrumentation handler void common_handler(void *address, DobbyRegisterContext *ctx) { // Called when socket function is executed printf("Network operation at %p\n", address); } void setup() { // Instrument socket function void *socket_addr = DobbySymbolResolver(NULL, "socket"); DobbyInstrument(socket_addr, common_handler); // Instrument connect function void *connect_addr = DobbySymbolResolver(NULL, "connect"); DobbyInstrument(connect_addr, common_handler); } ``` -------------------------------- ### General Type Definitions (C) Source: https://github.com/jmpews/dobby/blob/master/_autodocs/types.md Provides basic type definitions for assembly function pointers, bytes, and unsigned integers. ```c typedef void *asm_func_t; // Assembly/function pointer typedef unsigned char byte_t; // Byte type typedef unsigned int uint; // Unsigned integer ``` -------------------------------- ### Add Native Test Executable Source: https://github.com/jmpews/dobby/blob/master/tests/CMakeLists.txt Configures the 'test_native' executable and links it against the 'dobby' library. This is for testing native Dobby functionality. ```cmake add_executable(test_native test_native.cpp) target_link_libraries(test_native dobby) ``` -------------------------------- ### Configure Dobby Logging Library Source: https://github.com/jmpews/dobby/blob/master/external/logging/CMakeLists.txt Defines the source files for the logging library and conditionally includes kernel-specific logging sources if DOBBY_BUILD_KERNEL_MODE is enabled. ```cmake include_directories(.) set(SOURCE_FILE_LIST logging.cc ) if (DOBBY_BUILD_KERNEL_MODE) set(SOURCE_FILE_LIST logging_kern.cc ) endif () get_absolute_path_list(SOURCE_FILE_LIST SOURCE_FILE_LIST_) set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST_}) add_library(logging ${SOURCE_FILE_LIST} ) ``` -------------------------------- ### Define Static Library Source: https://github.com/jmpews/dobby/blob/master/CMakeLists.txt Creates a static library named 'dobby' using the same source files as the shared library and specifies public include directories. The output name is explicitly set to 'dobby'. ```cmake add_library(dobby_static STATIC ${SOURCE_FILE_LIST} ) target_include_directories(dobby_static PUBLIC include ) set_target_properties(dobby_static PROPERTIES OUTPUT_NAME "dobby" ) ``` -------------------------------- ### Enable Android Bionic Linker Utilities Source: https://github.com/jmpews/dobby/blob/master/_autodocs/build-configuration.md Enable utilities for working with the Bionic linker on Android. This option is Android-specific. ```bash cmake -DPlugin.Android.BionicLinkerUtil=ON .. ``` -------------------------------- ### Define Dobby Header File List Source: https://github.com/jmpews/dobby/blob/master/CMakeLists.txt Sets the list of header files for the Dobby project. ```cmake set(dobby.HEADER_FILE_LIST include/dobby.h ) ``` -------------------------------- ### Hook Cleanup on Error with Dobby Source: https://github.com/jmpews/dobby/blob/master/_autodocs/usage-patterns.md Illustrates how to ensure Dobby hooks are properly removed if subsequent initialization steps fail. This pattern is crucial for maintaining system stability by cleaning up resources when an operation does not complete successfully. ```c #include "dobby.h" typedef void (*func_t)(void); func_t orig_func = NULL; void fake_func(void) { orig_func(); } int setup_with_cleanup() { void *target = DobbySymbolResolver(NULL, "target"); if (!target) { printf("Symbol resolution failed\n"); return -1; } int ret = DobbyHook(target, (void *)fake_func, (void **)&orig_func); if (ret != 0) { printf("Hook installation failed\n"); return -1; } // Further initialization... if (further_init_failed) { printf("Further initialization failed, cleaning up\n"); DobbyDestroy(target); // Remove hook return -1; } printf("Setup successful\n"); return 0; } ```