update README to reflect working single-stepping implementation
This commit is contained in:
parent
26478a3c2f
commit
61639c1555
60
README.md
60
README.md
@ -1,14 +1,15 @@
|
||||
# gwatch - Global Variable Watcher
|
||||
|
||||
A tool to monitor reads and writes to global integer variables in Linux binaries using ptrace and hardware watchpoints.
|
||||
A tool to monitor writes to global integer variables in Linux binaries using ptrace single-stepping.
|
||||
|
||||
## Features
|
||||
|
||||
- Monitors specific global integer variables in a running program
|
||||
- Attempts to set up hardware watchpoints via ptrace to detect variable access
|
||||
- Detects and reports all writes to the watched variable
|
||||
- Supports PIE (Position Independent Executable) binaries
|
||||
- Passes command-line arguments to the target program
|
||||
- Uses DWARF debug information to locate variables
|
||||
- Tab-delimited output format for easy parsing
|
||||
|
||||
## Building
|
||||
|
||||
@ -70,41 +71,34 @@ global_counter write 42->52
|
||||
- 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
|
||||
### Single-Stepping Approach
|
||||
The tool uses `PTRACE_SINGLESTEP` to monitor memory access:
|
||||
- Executes the target program one instruction at a time
|
||||
- After each instruction, reads the watched variable's value from memory
|
||||
- Detects writes by comparing current value to previous value
|
||||
- Reports changes in the specified tab-delimited format
|
||||
|
||||
### PIE Binary Support
|
||||
For Position Independent Executables, the tool:
|
||||
1. Reads `/proc/[pid]/maps` to find the actual load address
|
||||
1. Reads `/proc/[pid]/maps` to find the base load address (lowest mapping)
|
||||
2. Adds the load address to the DWARF-provided offset
|
||||
3. Sets the watchpoint at the runtime address
|
||||
3. Monitors the calculated runtime address
|
||||
|
||||
### Read vs Write Detection
|
||||
When a watchpoint triggers:
|
||||
### Write Detection
|
||||
When monitoring the variable:
|
||||
1. The current value is read from the traced process memory using `ptrace(PTRACE_PEEKDATA)`
|
||||
2. If the value has changed since the last access, it's reported as a write
|
||||
3. If the value is unchanged, it's reported as a read
|
||||
4. Values are formatted according to the variable size (1, 2, 4, or 8 bytes)
|
||||
2. If the value has changed since the last check, it's reported as a write
|
||||
3. Values are formatted according to the variable size (1, 2, 4, or 8 bytes)
|
||||
4. Sign extension is applied for smaller integer types
|
||||
|
||||
## Current Limitations
|
||||
## Performance Considerations
|
||||
|
||||
**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:
|
||||
The tool uses single-stepping which executes one CPU instruction at a time. This is:
|
||||
- **Very thorough**: Catches every write to the watched variable
|
||||
- **Slow**: Adds significant overhead compared to native execution
|
||||
- **Reliable**: Works consistently across different systems and configurations
|
||||
|
||||
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.
|
||||
For programs with many instructions (100K+ steps), there will be noticeable slowdown.
|
||||
|
||||
## Testing
|
||||
|
||||
@ -129,8 +123,10 @@ Run tests:
|
||||
|
||||
## Future Work
|
||||
|
||||
- Investigate alternative watchpoint implementations
|
||||
- Add support for watching non-integer types
|
||||
- Support multiple simultaneous watchpoints (using DR1-DR3)
|
||||
- Add filtering options (read-only vs write-only vs read/write)
|
||||
- Optimize performance (possibly using hardware watchpoints if system supports it)
|
||||
- Add support for watching non-integer types (floats, structs, etc.)
|
||||
- Support multiple simultaneous variables
|
||||
- Add read detection (currently only writes are reported)
|
||||
- Output instruction pointer (RIP) for each access
|
||||
- Better error reporting and diagnostics
|
||||
- Optional: Skip library code and focus on main program only
|
||||
|
||||
Loading…
Reference in New Issue
Block a user