Add e9patch binary rewriting for runtime function call tracing#1
Open
overlorde wants to merge 2 commits intosysec-uic:mainfrom
Open
Add e9patch binary rewriting for runtime function call tracing#1overlorde wants to merge 2 commits intosysec-uic:mainfrom
overlorde wants to merge 2 commits intosysec-uic:mainfrom
Conversation
Replaces the broken counter-based path tracing (which always produced call_id=1) with real ordered call sequences via e9patch binary rewriting. The e9patch hook instruments all call instructions at the binary level, recording target addresses into a shared memory buffer. After each fuzzer execution, CollectE9Trace() reads the buffer, resolves addresses to function names via static offsets, and populates CurrentExecutionPath with real ordered data. This makes ComputePathDistance() and DumpCurrentPath() now functional. New files: - FuzzerE9Trace.h/cpp: shared trace buffer between hook and libFuzzer - e9patch_experiments/: hook source, toy target, build scripts, docs - docker-e9/: Dockerfile and scripts for libxml2 end-to-end pipeline Modified: - FuzzerTracePC.cpp: added CollectE9Trace(), InitE9SymbolTable(), GetFunctionName() with dladdr fallback for symbolization without sanitizer runtime - FuzzerTracePC.h: added new method declarations - FuzzerLoop.cpp: added e9_trace_reset() before and CollectE9Trace() after each execution, InitE9SymbolTable() at startup Tested end-to-end on libxml2 with ARVO crash PoC (bug 42470339).
Collaborator
|
Thanks @overlorde, the new PR is received for path-aware fuzz harness re-write, it should be mereged back with the main/master branch soon. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
CurrentExecutionPath,ComputePathDistance(),DumpCurrentPath())Background
The existing counter-based path recorder in
FuzzerTracePC.cpprecords each focus function once per execution withcall_id=1, losing temporal ordering and call counts. This adds an alternative trace source using e9patch binary rewriting that captures the actual ordered call sequence with real per-input call counts.Changes
New files:
FuzzerE9Trace.h/cpp— shared memory buffer between the e9patch hook and libFuzzere9patch_experiments/— e9patch hook source, toy test target, build/run scripts, documentationdocker-e9/— Dockerfile and scripts for building and running the libxml2 pipelineModified files:
FuzzerTracePC.cpp— addedCollectE9Trace(),InitE9SymbolTable(),GetFunctionName()(dladdr fallback for environments without sanitizer symbolization)FuzzerTracePC.h— new method declarationsFuzzerLoop.cpp— callse9_trace_reset()before execution andCollectE9Trace()afterHow to run
What is tested
CollectE9Trace()populatesCurrentExecutionPathwith correct function names and per-input call countsDumpCurrentPath()produces valid traces with input hex, ASCII, and ordered pathWhat is NOT tested
-crash_path_file+-path_distance_threshold) — traces are generated and fed intoComputePathDistance()but the effect on fuzzing decisions has not been validatedcallinstructions not measuredBuild requirements
Target binary must be compiled with:
-fno-inline -fno-optimize-sibling-calls— keeps call instructions for e9patch to hook-rdynamic -ldl— exports symbols for dladdr resolutionKnown limitations
F.namematching does not fire at runtime; workaround isasm=/call.*/which patches all call instructions