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
|
# 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
|
## Features
|
||||||
|
|
||||||
- Monitors specific global integer variables in a running program
|
- 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
|
- Supports PIE (Position Independent Executable) binaries
|
||||||
- Passes command-line arguments to the target program
|
- Passes command-line arguments to the target program
|
||||||
- Uses DWARF debug information to locate variables
|
- Uses DWARF debug information to locate variables
|
||||||
|
- Tab-delimited output format for easy parsing
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
@ -70,41 +71,34 @@ global_counter write 42->52
|
|||||||
- Handles const/volatile type qualifiers
|
- Handles const/volatile type qualifiers
|
||||||
- Retrieves variable address and size from debug info
|
- Retrieves variable address and size from debug info
|
||||||
|
|
||||||
### Hardware Watchpoints
|
### Single-Stepping Approach
|
||||||
The tool uses x86-64 hardware debug registers (DR0-DR7) via ptrace to set watchpoints:
|
The tool uses `PTRACE_SINGLESTEP` to monitor memory access:
|
||||||
- DR0: Stores the watched address
|
- Executes the target program one instruction at a time
|
||||||
- DR7: Configures watchpoint type (read/write) and size
|
- After each instruction, reads the watched variable's value from memory
|
||||||
- DR6: Status register checked on SIGTRAP to detect watchpoint hits
|
- Detects writes by comparing current value to previous value
|
||||||
|
- Reports changes in the specified tab-delimited format
|
||||||
|
|
||||||
### PIE Binary Support
|
### PIE Binary Support
|
||||||
For Position Independent Executables, the tool:
|
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
|
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
|
### Write Detection
|
||||||
When a watchpoint triggers:
|
When monitoring the variable:
|
||||||
1. The current value is read from the traced process memory using `ptrace(PTRACE_PEEKDATA)`
|
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
|
2. If the value has changed since the last check, it's reported as a write
|
||||||
3. If the value is unchanged, it's reported as a read
|
3. Values are formatted according to the variable size (1, 2, 4, or 8 bytes)
|
||||||
4. 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)
|
For programs with many instructions (100K+ steps), there will be noticeable slowdown.
|
||||||
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
|
## Testing
|
||||||
|
|
||||||
@ -129,8 +123,10 @@ Run tests:
|
|||||||
|
|
||||||
## Future Work
|
## Future Work
|
||||||
|
|
||||||
- Investigate alternative watchpoint implementations
|
- Optimize performance (possibly using hardware watchpoints if system supports it)
|
||||||
- Add support for watching non-integer types
|
- Add support for watching non-integer types (floats, structs, etc.)
|
||||||
- Support multiple simultaneous watchpoints (using DR1-DR3)
|
- Support multiple simultaneous variables
|
||||||
- Add filtering options (read-only vs write-only vs read/write)
|
- Add read detection (currently only writes are reported)
|
||||||
|
- Output instruction pointer (RIP) for each access
|
||||||
- Better error reporting and diagnostics
|
- Better error reporting and diagnostics
|
||||||
|
- Optional: Skip library code and focus on main program only
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user