Therefore, dynamic analysis cannot provide information about an unexecuted path with the same level of certainty as it does for an executed one.
For this reason, these two methods are generally more valuable when used together:
Static Analysis
+
Dynamic Analysis
Static
Helps us understand what paths and dependencies might exist.
Dynamic
Helps us understand what actually happened during a
specific execution.
Tools
There are various tools and frameworks available for Dynamic Binary Analysis and Taint Tracking:
Intel Pin
DynamoRIO
Triton
angr
PANDA
However, we shouldn't assume all these tools do exactly the same thing; their instrumentation models and capabilities differ.
For example:
Triton
Offers features like Taint Analysis and Symbolic Execution for Dynamic Binary Analysis.
Connection to Fuzzing
This is where it gets interesting.
Previously, we had:
Fuzzer
↓
Interesting Input
↓
Crash
Now, we can use Dynamic Taint Analysis to examine the data path.
For example:
Interesting Input
↓
Tainted Data
↓
Parser
↓
Variable
↓
Memory Operation
↓
Crash
So, we don't just say the program crashed;
we can also trace the path the input data took during execution and identify where it contributed to the issue.
Static + Dynamic
A logical analysis workflow might look like this:
Fuzzing
↓
Crash
↓
Crash Triage
↓
Static Analysis
↓
Find Source / Sink
↓
Dynamic Analysis
↓
Trace Data
↓
Root Cause
Here, we gradually move from a simple crash to a better understanding of the path that caused the bug.
Dynamic Taint Analysis
Means tracking specific data or data dependencies during the actual execution of the program.
Key concepts:
Source
↓
Taint
↓
Propagation
↓
Register / Memory ↓
Control Flow
↓
Sink
An important point is that static analysis and dynamic analysis are not rivals.
Static analysis
primarily answers this question:
What possible paths might exist?
Dynamic analysis
primarily answers this question:
What path was actually taken during this specific execution?
When we combine these two with fuzzing and crash analysis,
we can trace a path from
Crash
to
Input
↓
Data Flow
↓
Instruction
↓
Memory Operation
↓
Crash
↓
Root Cause
And this is precisely the point where analyzing a crash shifts from observing a simple event to understanding the bug's root cause.
@reverseengine
Post #1865
52