Skip to content

Using B2R2 APIs

The hands-on problems in this tutorial use F# scripts to automate binary analysis. You write a .fsx file, run it with dotnet fsi <script.fsx>, inspect the result, and then verify the answer against the target binary in your local terminal.

F# scripts are a compact way to try binary analysis ideas without creating a full project. They are well suited for short experiments such as loading a binary, recovering functions, lifting instructions to LowUIR, or preparing concrete and symbolic execution state.

Run a script with:

Terminal window
dotnet fsi script.fsx

A web tutorial script should reference public NuGet packages at the top of the .fsx file:

#r "nuget: B2R2.MiddleEnd.API"

Problem-specific scripts may also use packages for concrete or symbolic execution, for example:

#r "nuget: B2R2.MiddleEnd.ConcEval"
#r "nuget: B2R2.MiddleEnd.SymbEval"

After downloading and extracting tutorial.zip, open the target binary by path. The examples in this site assume commands are run from the matching problem directory.

open System.IO
open B2R2
open B2R2.FrontEnd
let binaryPath =
Path.Combine(__SOURCE_DIRECTORY__, "bin", "findme")
let hdl = BinHandle binaryPath

BinHandle is the starting point for most B2R2 API workflows. From there you can inspect file metadata, access sections, recover functions, or lift instructions.

  1. Load the binary with BinHandle.
  2. Confirm the architecture, file format, and entry point.
  3. Recover the control-flow graph or lift instructions to LowUIR.
  4. Prepare concrete or symbolic evaluation state when the problem requires it.
  5. Print the analysis result and verify it by running the target binary.

Save this as echo-functions.fsx in the extracted cli/ directory:

#r "nuget: B2R2.MiddleEnd.API"
#r "nuget: B2R2.FrontEnd.Intel"
open System.IO
open B2R2
open B2R2.FrontEnd
open B2R2.MiddleEnd
let binaryPath =
Path.Combine(__SOURCE_DIRECTORY__, "echo")
let hdl = BinHandle binaryPath
let brew = BinaryBrew hdl
match hdl.File.EntryPoint with
| Some entry -> printfn "Entry point: 0x%x" entry
| None -> printfn "Entry point: unavailable"
brew.Functions.Sequence
|> Seq.sortBy (fun fn -> fn.EntryPoint)
|> Seq.iter (fun fn ->
printfn "0x%016x blocks=%d" fn.EntryPoint fn.CFG.Size)

Run it from the cli/ directory:

Terminal window
dotnet fsi echo-functions.fsx