Problem 1: findme
Overview
Section titled “Overview”Field: Function identification
findme is a stripped binary with several internal functions. One of them
prints You find me!; the exercise is to recover that function’s entry address
and pass it to the binary.
Use the findme/ directory from
tutorial.zip.
It has this layout:
findme/ Makefile src/ findme.c bin/ findme strip/ findmeThe stripped challenge binary is at strip/findme. The unstripped rebuild is
at bin/findme. The source file and unstripped binary are provided for
verification; use the stripped binary for the exercise.
Find the address of the function that prints:
You find me!Then run the binary with that address, written as a hexadecimal value without
the 0x prefix.
Problem Description
Section titled “Problem Description”findme accepts one command-line argument. It parses the argument as a
hexadecimal address, casts that address to a function pointer, and calls it.
The dispatcher does not call arbitrary addresses. It accepts only a small set of
allowed function entries and rejects all other inputs with You are not allowed..
Suggested Workflow
Section titled “Suggested Workflow”- Recover internal function entries from the binary.
- Inspect candidate function bodies, looking for the one that reaches the target string.
- Run
strip/findmewith the selected entry address.
You can also run the binary without arguments and enter candidate addresses interactively.
Starter Code
Section titled “Starter Code”Save this as findme.fsx in the extracted findme/ directory:
#r "nuget: B2R2.MiddleEnd.API"
open System.IOopen B2R2open B2R2.FrontEndopen B2R2.MiddleEnd
let binaryPath = Path.Combine(__SOURCE_DIRECTORY__, "strip", "findme")
let hdl =let brew =let text = hdl.File.GetTextSectionPointer()
let isInText (addr: Addr) = text.IsValid && text.Addr <= addr && addr <= text.MaxAddr
let funcs =
printfn "Entry address # basic blocks"for fn in funcs do printfn "0x%016x %d" fn.EntryPoint fn.CFG.Size
// Pick the function that reaches the target string, then run:// ./strip/findme <entry-address-without-0x-prefix>Recommended References
Section titled “Recommended References”BinHandlefor loading the target binary.hdl.File.GetTextSectionPointer()andBinFilePointerfor checking whether a recovered function entry belongs to.text.BinaryBrewfor recovering functions and CFGs.FunctionCollection,Function, and CFG members forbrew.Functions.Sequence,fn.EntryPoint, andfn.CFG.Size.
Run the script from the extracted findme/ directory:
dotnet fsi findme.fsxOn Unix-like systems, if the extracted binary is not executable, run:
chmod +x strip/findmeThen test candidates with:
./strip/findme <address-without-0x-prefix>Solution
Section titled “Solution”Show solution
#r "nuget: B2R2.MiddleEnd.API"
open System.IOopen B2R2open B2R2.FrontEndopen B2R2.MiddleEnd
let binaryPath = Path.Combine(__SOURCE_DIRECTORY__, "strip", "findme")
let hdl = BinHandle binaryPathlet brew = BinaryBrew hdllet text = hdl.File.GetTextSectionPointer()
let isInText (addr: Addr) = text.IsValid && text.Addr <= addr && addr <= text.MaxAddr
let funcs = brew.Functions.Sequence |> Seq.filter (fun fn -> isInText fn.EntryPoint) |> Seq.sortBy (fun fn -> fn.EntryPoint)
for fn in funcs do printfn "0x%016x %d" fn.EntryPoint fn.CFG.SizeScript output:
0x00000000004010b0 230x00000000004011a0 30x00000000004011d0 10x00000000004011e0 40x0000000000401250 50x0000000000401280 50x0000000000401290 40x00000000004012b0 80x0000000000401300 40x0000000000401360 20x0000000000401370 20x0000000000401380 20x00000000004013c0 560x0000000000401520 60x0000000000401560 10x00000000004015b0 50x0000000000401630 6Binary run:
./strip/findme 401370You find me!