gwatch/README.md

88 lines
2.8 KiB
Markdown

# 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 <binary>
```
### Watch a specific variable:
```bash
./build/gwatch --exec <binary> --var <variable_name>
```
**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