MODULE // 02

Your first legal target

10 mindifficulty: beginner

TARGET / AUTHORIZATION分析对象:本课自行编写、本机 gcc 编译的 hello ELF(白名单第 3 类:自行编译产物)。授权链:作者=分析者本人。lab 记录:doc/labs/2026-10-12-lab01。

The number-one beginner mistake is not technical — it is pointing tools at the wrong binary. Choose the target first, deliberately. Here is the whitelist we use on this site, in order of preference:

target classexampleauthorization basis
Self-compiled binarieshello.c you built todayYou made it — total rights
Open-source releasesOpenSSL libcrypto (lesson 1)License grants inspection
Official demos/samplesvendor-provided sample filesProvided for study
Classic DRM-free gamesold shareware-era titlesNo protection circumvented
HARD RULENever target commercial software with the intent to bypass licensing or DRM, and never analyze employer/client software without written permission. The tools do not know the difference — you must.

build the target, record the truth (30 seconds)

The cleanest first target is one you compile yourself — and it comes with a superpower: you know the answer, so you can check your reverse-engineering against it. Source used in our lab:

hello.c + build verified: ran 2026-10-12
#include <stdio.h>
int secret(int x){return x*1337+7;}
int main(){printf("hello realearn %d\n", secret(42));return 0;}
$ gcc -O0 -o hello hello.c
$ ./hello
hello realearn 56161
(预期 42*1337+7 = 56161 ✓ —— 运行时基准,供逆向结果对账)

Note the two compile choices, because they matter: -O0 (no optimization — the machine code mirrors the source) and default not-stripped (symbol names survive). Both are beginner training wheels; lesson 3 takes them off.

identify the artifact

bash — lab@realearn verified: ran 2026-10-12
$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked,
interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=8a984d6d..., not stripped

find the function by name

Because the binary is not stripped, the symbol table still lists every function with its address:

bash — lab@realearn verified: ran 2026-10-12
$ readelf -h hello
  Class: ELF64 / Data: 2's complement little endian / Type: EXEC
  Machine: Advanced Micro Devices X86-64 / Entry point: 0x400320
$ readelf -s hello | grep -E 'secret|main'
  27: 0000000000400406   21 FUNC GLOBAL DEFAULT 3 secret
  32: 000000000040041b   38 FUNC GLOBAL DEFAULT 3 main

read the disassembly — and recover the secret

objdump — secret() verified: ran 2026-10-12
$ objdump -d -M intel hello | grep -A8 '<secret>:'
0000000000400406 <secret>:
  400406: 55                push rbp
  400407: 48 89 e5          mov rbp,rsp
  40040a: 89 7d fc          mov DWORD PTR [rbp-0x4],edi      ; 参数 x 入栈
  40040d: 8b 45 fc          mov eax,DWORD PTR [rbp-0x4]
  400410: 69 c0 39 05 00 00 imul eax,eax,0x539              ; ×1337(0x539)
  400416: 83 c0 07          add eax,0x7                     ; +7
  400419: 5d                pop rbp
  40041a: c3                ret

Read it slowly — this is your first real disassembly. The constants give the whole secret away: imul eax,eax,0x539 is ×1337 (0x539 in hex), add eax,0x7 is +7. So the binary says secret(x) = x*1337 + 7 — which matches the source, and matches the runtime output (42 → 56161). Three independent sources agree: source, disassembly, execution. That is the core habit this lesson teaches: reverse engineering is proposing a verifiable hypothesis, then verifying it.

Two extra observations worth pocketing: the first integer argument arrives in edi (System V ABI — your first calling-convention lesson), and when an AI agent later claims "this function computes x*1337+7", you now know exactly how to audit that claim by hand.

One more thing, honestly stated: with no analysis engine installed, REA's deep analysis on this very binary fails closed with provider_unavailable — while the binutils path you just followed works everywhere, always. The setup guide shows both tiers.

next: Reading a disassembly →