<- Back to README | SSA Guide | SSA Transforms ->
YABR provides thirteen high-level analysis APIs that build on top of the SSA IR system. Each API can be used independently or combined for powerful semantic queries.
| API | Package | Description | Guide |
|---|---|---|---|
| Call Graph | callgraph |
Method caller/callee relationships | Details |
| Dependency Analysis | dependency |
Class-level dependency tracking | Details |
| Type Inference | typeinference |
Nullability and type state analysis | Details |
| Pattern Search | pattern |
Code pattern matching across the codebase | Details |
| Instrumentation | instrumentation |
Bytecode instrumentation with hooks | Details |
| Cross-References | xref |
Track all references to/from classes, methods, fields | Details |
| Data Flow | dataflow |
Build data flow graphs for taint analysis | Details |
| Method Similarity | similarity |
Find duplicate and similar methods | Details |
| Simulation | simulation |
Abstract bytecode/IR simulation with metrics | Details |
| Execution | execution |
Concrete bytecode execution and debugging | Details |
| PDG | pdg |
Program Dependence Graph with slicing | Details |
| SDG | pdg.sdg |
Interprocedural System Dependence Graph | Details |
| CPG | cpg |
Code Property Graph with taint analysis | Details |
Build a graph of method invocations across all classes in a ClassPool.
CallGraph cg = CallGraph.build(pool);
Set<MethodReference> callers = cg.getCallers(target);
Set<MethodReference> reachable = cg.getReachableFrom(entryPoints);Key features: Caller/callee queries, reachability analysis, virtual call resolution, dead code detection.
Track class-level dependencies by scanning constant pools.
DependencyAnalyzer deps = new DependencyAnalyzer(pool);
Set<String> dependencies = deps.getDependencies("java/lang/String");
List<List<String>> cycles = deps.findCircularDependencies();Key features: Dependency queries, transitive closures, circular dependency detection, dependency type filtering.
Perform dataflow analysis to infer types and nullability states for SSA values.
TypeInferenceAnalyzer analyzer = new TypeInferenceAnalyzer(irMethod);
analyzer.analyze();
Nullability nullability = analyzer.getNullability(value);Key features: Nullability analysis, type state tracking, polymorphic type sets.
High-level fluent interface for finding code patterns across the codebase.
PatternSearch search = new PatternSearch(pool);
List<SearchResult> results = search.findMethodCalls("java/io/PrintStream", "println");
List<SearchResult> allocs = search.findAllocations("java/lang/StringBuilder");Key features: Method call search, field access search, type operations, custom patterns, pattern composition.
Fluent interface for adding hooks to bytecode at various instrumentation points.
Instrumenter.forClass(classFile)
.onMethodEntry()
.callStatic("Profiler", "enter", "(Ljava/lang/String;)V")
.withMethodName()
.register()
.apply();Key features: Method entry/exit hooks, field write hooks, method call interception, annotation filtering.
Track all references to and from classes, methods, and fields.
XrefDatabase db = new XrefBuilder(pool).build();
Set<Xref> callers = db.getRefsToMethod(target);
Set<Xref> outgoing = db.getRefsFromMethod(source);Key features: Incoming/outgoing reference queries, reference type filtering, unused code detection.
Build data flow graphs from SSA IR for taint analysis and value tracking.
DataFlowGraph dfg = new DataFlowGraph(irMethod);
dfg.build();
Set<DataFlowNode> reachable = dfg.getReachableNodes(sourceNode);Key features: Taint source/sink identification, flow path queries, taint propagation.
Find duplicate and similar methods for de-obfuscation and pattern detection.
MethodSimilarityAnalyzer analyzer = new MethodSimilarityAnalyzer(pool);
analyzer.buildIndex();
List<SimilarityResult> duplicates = analyzer.findDuplicates();Key features: Multiple similarity metrics, duplicate detection, renamed copy detection, similarity groups.
Abstract bytecode/IR execution simulation with metrics and value tracking.
SimulationEngine engine = new SimulationEngine(ctx)
.addListener(new StackOperationListener())
.addListener(new AllocationListener());
SimulationResult result = engine.simulate(irMethod);Key features: Stack operation tracking, allocation tracking, field access tracking, method call tracking, control flow tracking, value flow queries, inter-procedural simulation.
Concrete bytecode execution with full heap simulation and debugging support.
BytecodeContext ctx = new BytecodeContext.Builder()
.heapManager(new SimpleHeapManager())
.classResolver(new ClassResolver(pool))
.maxInstructions(100000)
.build();
BytecodeEngine engine = new BytecodeEngine(ctx);
BytecodeResult result = engine.execute(method, ConcreteValue.intValue(42));
// Or debug interactively
DebugSession session = new DebugSession(ctx);
session.addBreakpoint(new Breakpoint("MyClass", "method", "()V", 10));
session.start(method);
DebugState state = session.stepOver();Key features: Concrete value execution, mutable heap/stack, object simulation, native method handlers, breakpoints, step debugging, call stack inspection, full Java 11 support (invokedynamic, lambdas, string concatenation, constant dynamic, method handles).
Build intraprocedural program dependence graphs combining control and data dependencies.
PDG pdg = PDGBuilder.build(irMethod);
PDGSlicer slicer = new PDGSlicer(pdg);
SliceResult slice = slicer.backwardSlice(criterion);Key features: Control dependencies via post-dominance, data dependencies via def-use chains, backward/forward slicing, chop computation, DOT export.
Build interprocedural dependence graphs for whole-program analysis.
CallGraph callGraph = CallGraph.build(pool);
SDG sdg = SDGBuilder.build(callGraph, irMethods);
SDGSlicer slicer = new SDGSlicer(sdg);
SliceResult slice = slicer.contextSensitiveSlice(criterion);Key features: Interprocedural slicing, summary edges, parameter passing edges, context-sensitive analysis, call graph integration.
Unified graph combining CFG, PDG, and call graph for comprehensive analysis.
CodePropertyGraph cpg = CPGBuilder.forClassPool(pool)
.withCallGraph()
.withPDG()
.build();
List<TaintPath> vulns = new TaintQuery(cpg)
.withDefaultSources()
.withDefaultSinks()
.analyze()
.getPaths();Key features: Fluent query API, taint analysis, data flow tracking, DOT export, unified traversal across CFG/PDG/call edges.
Runnable demos are in src/main/java/com/tonic/demo/:
| Demo | Description |
|---|---|
CallGraphDemo.java |
Build and query call graph |
DependencyDemo.java |
Analyze class dependencies |
TypeInferenceDemo.java |
Run type inference analysis |
PatternSearchDemo.java |
Search for code patterns |
InstrumentationDemo.java |
Bytecode instrumentation |
SimulationDemo.java |
Bytecode simulation and metrics |
ExecutionDemo.java |
Concrete bytecode execution and debugging |
Run with:
java -cp build/classes/java/main com.tonic.demo.CallGraphDemo
java -cp build/classes/java/main com.tonic.demo.DependencyDemo
java -cp build/classes/java/main com.tonic.demo.TypeInferenceDemo
java -cp build/classes/java/main com.tonic.demo.PatternSearchDemo
java -cp build/classes/java/main com.tonic.demo.InstrumentationDemo
java -cp build/classes/java/main com.tonic.demo.SimulationDemo
java -cp build/classes/java/main com.tonic.demo.ExecutionDemo