Reverse Engineering

TryHackMe — Reverse Engineering Introduction

TryHackMe introduction to reverse engineering covering fundamental concepts, tools setup, and basic binary analysis techniques for beginners.

Contents

TryHackMe — Reverse Engineering Introduction

Platform: TryHackMe | Topic: Reverse Engineering Fundamentals | Difficulty: Beginner → Intermediate


1. What is Reverse Engineering?

Reverse engineering (RE) is the process of analyzing a compiled binary to understand what it does without having access to the source code.

Why Learn RE?

Use CaseDescription
Malware AnalysisUnderstand what malicious software does, extract IOCs
Vulnerability ResearchFind bugs in closed-source software
CTF CompetitionsSolve crackmes, keygens, flag extraction challenges
Software SecurityAudit binaries for backdoors, verify patches
Exploit DevelopmentUnderstand program behavior to craft exploits
Game HackingUnderstand game internals (educational)

2. Core Concepts

Compilation Pipeline

Source Code (.c/.cpp)
    |
    v
Preprocessor --> Compiler --> Assembler --> Linker
    |               |            |            |
  .i file       .s (asm)     .o (object)   ELF/PE binary

Key Terms

TermDefinition
DisassemblyConverting machine code → assembly instructions
DecompilationConverting machine code → pseudo-C code (approximate)
Static AnalysisAnalyzing without executing (disassembler)
Dynamic AnalysisAnalyzing while running (debugger)
DebuggingStepping through code, examining memory/registers
PatchingModifying binary instructions to change behavior
ELFExecutable and Linkable Format (Linux binaries)
PEPortable Executable (Windows binaries)

3. Essential RE Tools

Disassemblers / Decompilers

ToolPlatformCostBest For
GhidraAllFreeFull RE with decompiler (NSA)
IDA ProAll$$$$Industry standard
IDA FreeAllFreeDisassembly only (no decompiler)
CutterAllFreeRizin-based, modern UI
Binary NinjaAll$$Clean HLIL decompiler
radare2AllFreeCLI-based, scriptable

Debuggers

ToolPlatformBest For
GDB + PwndbgLinuxBinary exploitation, CTF
GDB + GEFLinuxSimilar to Pwndbg, different UI
x64dbgWindowsWindows RE, malware analysis
WinDbgWindowsKernel debugging, crash analysis
OllyDbgWindowsLegacy 32-bit debugging

Supporting Tools

ToolPurpose
fileIdentify file type (ELF, PE, script, etc.)
strings / FLOSSExtract readable text from binaries
ltraceTrace library function calls
straceTrace system calls
objdumpDisassemble sections, view headers
readelfParse ELF structure
checksecCheck binary protections (NX, ASLR, canary, PIE)
nmList symbols in binary
lddList shared library dependencies

4. x86/x64 Assembly Essentials

Registers (x64)

RegisterPurposeNotes
RAXReturn value, accumulatorFunction return values
RBXBase registerCallee-saved
RCXCounter, 1st arg (Windows) / 4th arg (Linux)Loop counter
RDXData, 2nd arg (Windows) / 3rd arg (Linux)Division
RSISource index, 2nd arg (Linux)String operations
RDIDestination index, 1st arg (Linux)String operations
RSPStack pointerAlways points to top of stack
RBPBase pointerFrame pointer
RIPInstruction pointerNext instruction to execute
R8-R15General purpose (x64 only)R8/R9 = 5th/6th args (Linux)

Calling Conventions

ConventionArgs 1-6ReturnCaller/Callee Saved
Linux x64 (System V)RDI, RSI, RDX, RCX, R8, R9RAXCaller: RAX,RCX,RDX,R8-R11
Windows x64RCX, RDX, R8, R9 (+ shadow space)RAXCaller: RAX,RCX,RDX,R8-R11
Linux x86 (cdecl)Stack (right-to-left push)EAXCaller cleans stack

Essential Instructions

InstructionMeaningExample
mov dst, srcMove/copy valuemov rax, rbx
push valPush to stack (RSP -= 8)push rbp
pop dstPop from stack (RSP += 8)pop rbp
lea dst, [addr]Load effective address (no dereference)lea rax, [rbp-0x10]
call funcPush return addr, jump to functioncall 0x401000
retPop return addr, jump to itReturn from function
cmp a, bCompare (sets flags, no store)cmp eax, 0
test a, bAND (sets flags, no store)test eax, eax (check zero)
je/jzJump if equal/zeroAfter cmp
jne/jnzJump if not equal/not zeroAfter cmp
jmp addrUnconditional jumpjmp 0x401050
xor a, aZero out registerxor eax, eax (eax = 0)
nopNo operationNOP sled, padding
syscallSystem call (x64 Linux)After setting RAX = syscall #
int 0x80System call (x86 Linux)After setting EAX = syscall #

5. Common RE Patterns

Function Prologue & Epilogue

; Prologue - sets up stack frame
push rbp          ; Save old base pointer
mov rbp, rsp      ; Set new base pointer
sub rsp, 0x20     ; Allocate 32 bytes for local variables

; ... function body ...

; Epilogue - tears down stack frame
leave             ; mov rsp, rbp; pop rbp
ret               ; Return to caller

If/Else Pattern

cmp eax, 5        ; if (x == 5)
jne else_branch    ;   if not equal, jump to else
; ... then code ...
jmp end_if
else_branch:
; ... else code ...
end_if:

Loop Pattern

mov ecx, 10       ; counter = 10
loop_start:
; ... loop body ...
dec ecx            ; counter--
jnz loop_start     ; if counter != 0, loop again

String Comparison

lea rdi, [user_input]    ; arg1 = user input
lea rsi, [correct_pass]  ; arg2 = correct password
call strcmp               ; compare strings
test eax, eax            ; check result
je access_granted         ; if equal -> success

6. RE Methodology for CTF

Step 1: Reconnaissance

file challenge           # What type of binary?
checksec challenge       # What protections?
strings challenge        # Any visible strings?
ltrace ./challenge       # What library calls?

Step 2: Static Analysis

# Load into Ghidra or Cutter
# Find main()
# Read decompiled code
# Identify: input, validation logic, success/fail paths

Step 3: Dynamic Analysis

# Load into GDB with Pwndbg
gdb ./challenge
> break main
> run
> step/next through code
> examine registers and memory

Step 4: Common CTF Challenges

Challenge TypeWhat to Do
Password checkFind strcmp/custom compare, extract correct password
XOR encryptionFind XOR loop, extract key and ciphertext
Flag in memoryRun in debugger, break after decode, read memory
Anti-debugPatch out ptrace / IsDebuggerPresent checks
KeygenUnderstand validation algorithm, write keygen
ObfuscatedDe-obfuscate: XOR strings, base64, custom encoding
PackedUnpack first (UPX, custom), then analyze
Multi-stageFollow execution flow through unpacking/decoding stages

7. Linux Syscalls Reference (x86/x64)

Common Syscalls

Syscallx86 (EAX)x64 (RAX)Purpose
read30Read from file descriptor
write41Write to file descriptor
open52Open file
close63Close file descriptor
execve1159Execute program
exit160Exit process
mmap909Map memory
mprotect12510Change memory protections
fork257Create child process
ptrace26101Debug process (anti-debug target)

RoomDifficultyFocus
Intro to x86-64EasyAssembly basics
Reverse EngineeringEasyBasic RE methodology
CrackmeEasy-MediumPassword cracking
GhidraMediumUsing Ghidra for RE
Radare2Mediumradare2 commands
Buffer Overflow PrepMediumStack overflow basics
BinexMediumBinary exploitation
GatekeeperMediumReal-world buffer overflow
BrainstormHardAdvanced buffer overflow
RE (Challenge)HardPut it all together

9. Practice Path

1. Learn x86 assembly basics (registers, instructions, stack)
2. Get comfortable with GDB + Pwndbg
3. Solve easy crackmes (crackmes.one)
4. Learn to use Ghidra/Cutter decompiler
5. Understand common vulnerability classes (BOF, format strings)
6. Progress to binary exploitation (pwntools, ROP)
7. Try malware analysis (combine static + dynamic RE)

Pro Tips

Read the decompiler output, not just assembly — Ghidra’s decompiler turns 50 lines of ASM into 10 lines of C. Start there, then verify with assembly when things look wrong.

Rename functions and variables as you go — In Ghidra/IDA, press L to rename. FUN_004010a0 means nothing. check_password means everything.

Dynamic > Static for beginners — When stuck, run it in GDB. Set breakpoints before and after interesting code. Examine registers. Watch values change in real-time.

Learn to read compiler patterns — Compilers generate predictable code for if/else, for, while, switch. Once you recognize the patterns, RE becomes much faster.