# gwatch - Global Variable Watcher A tool to monitor reads and writes to global integer variables in Linux binaries using ptrace and hardware watchpoints. ## Features - Lists all global integer variables in a binary with their addresses - Attempts to set up hardware watchpoints via ptrace to monitor variable access - Supports PIE (Position Independent Executable) binaries - Uses DWARF debug information to locate variables ## Building ```bash cmake -B build cmake --build build ``` ## Usage ### List all global integer variables: ```bash ./build/gwatch --exec ``` ### Watch a specific variable: ```bash ./build/gwatch --exec --var ``` **Note:** The binary must be compiled with debug symbols (`-g` flag). ## Implementation Details ### Variable Detection - Uses libdwarf to parse DWARF debug information - Identifies global integer variables (int, long, short, char, unsigned variants) - Handles const/volatile type qualifiers - Retrieves variable address and size from debug info ### Hardware Watchpoints The tool uses x86-64 hardware debug registers (DR0-DR7) via ptrace to set watchpoints: - DR0: Stores the watched address - DR7: Configures watchpoint type (read/write) and size - DR6: Status register checked on SIGTRAP to detect watchpoint hits ### PIE Binary Support For Position Independent Executables, the tool: 1. Reads `/proc/[pid]/maps` to find the actual load address 2. Adds the load address to the DWARF-provided offset 3. Sets the watchpoint at the runtime address ## Current Limitations **Hardware watchpoints are not currently triggering on the test system.** The implementation follows standard Linux ptrace documentation for setting x86 hardware breakpoints, but watchpoint events are not being generated. This may be due to: 1. Kernel configuration (hardware breakpoints disabled or restricted) 2. Security settings (e.g., `/proc/sys/kernel/yama/ptrace_scope`) 3. System-specific ptrace behavior variations 4. Potential need for additional ptrace options or setup steps The code correctly: - Sets DR0 to the target address - Configures DR7 with proper enable bits, condition codes, and length fields - Monitors for SIGTRAP signals - Checks DR6 for watchpoint hits But SIGTRAP signals are never generated when the watched variable is accessed. ## Testing Test binaries are provided: - `test_binary`: Simple binary with global variables (no accesses) - `test_access`: Program that reads and writes to `global_counter` Compile test programs with: ```bash gcc -g -O0 -o test_access test_access.c ``` ##Future Work - Investigate alternative watchpoint implementations - Add support for watchingnon-integer types - Support multiple simultaneous watchpoints (using DR1-DR3) - Add filtering options (read-only vs write-only vs read/write) - Better error reporting and diagnostics