Skip to content

Problem 1: findme

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/
findme

The 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.

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..

  1. Recover internal function entries from the binary.
  2. Inspect candidate function bodies, looking for the one that reaches the target string.
  3. Run strip/findme with the selected entry address.

You can also run the binary without arguments and enter candidate addresses interactively.

Save this as findme.fsx in the extracted findme/ directory:

#r "nuget: B2R2.MiddleEnd.API"
open System.IO
open B2R2
open B2R2.FrontEnd
open 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>

Run the script from the extracted findme/ directory:

Terminal window
dotnet fsi findme.fsx

On Unix-like systems, if the extracted binary is not executable, run:

Terminal window
chmod +x strip/findme

Then test candidates with:

Terminal window
./strip/findme <address-without-0x-prefix>
Show solution
#r "nuget: B2R2.MiddleEnd.API"
open System.IO
open B2R2
open B2R2.FrontEnd
open B2R2.MiddleEnd
let binaryPath =
Path.Combine(__SOURCE_DIRECTORY__, "strip", "findme")
let hdl = BinHandle binaryPath
let brew = BinaryBrew hdl
let 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.Size

Script output:

0x00000000004010b0 23
0x00000000004011a0 3
0x00000000004011d0 1
0x00000000004011e0 4
0x0000000000401250 5
0x0000000000401280 5
0x0000000000401290 4
0x00000000004012b0 8
0x0000000000401300 4
0x0000000000401360 2
0x0000000000401370 2
0x0000000000401380 2
0x00000000004013c0 56
0x0000000000401520 6
0x0000000000401560 1
0x00000000004015b0 5
0x0000000000401630 6

Binary run:

Terminal window
./strip/findme 401370
You find me!