diff --git a/README.md b/README.md index 1322ba6..4e8c6bb 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,10 @@ A tool to monitor writes to global integer variables in Linux binaries using ptr ## Building ```bash -cmake -B build -cmake --build build +mkdir build +cd build +cmake --preset debug .. +make ``` ## Usage @@ -31,66 +33,6 @@ gwatch --var --exec [-- arg1 arg2 ... argN] **Note:** The target binary must be compiled with debug symbols (`-g` flag). -**Examples:** - -```bash -# Watch global_counter in test_access -./build/gwatch --var global_counter --exec ./test_access - -# Watch with program arguments -./build/gwatch --var global_counter --exec ./test_with_args -- hello world 123 -``` - -## Output Format - -When watchpoints trigger, gwatch outputs access events in the following format: - -**For writes:** -``` -\twrite\t-> -``` - -**For reads:** -``` -\tread\t -``` - -Example output: -``` -global_counter read 0 -global_counter write 0->42 -global_counter read 42 -global_counter write 42->52 -``` - -## 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 - -### 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 base load address (lowest mapping) -2. Adds the load address to the DWARF-provided offset -3. Monitors the calculated runtime address - -### 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 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 - ## Performance Considerations The tool uses single-stepping which executes one CPU instruction at a time. This is: @@ -119,14 +61,8 @@ Run tests: # Test with arguments ./build/gwatch --var global_counter --exec ./test_with_args -- hello world 123 + +# Run test suite +./build/gwatch_tests ``` -## Future Work - -- 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