Behind the Scenes
Author: 0xIDA
Platform: HTB · Category: rev · Difficulty: N/A
Solvers
Summary
A "Very Easy" reverse engineering challenge where the binary uses ud2 (undefined opcode) instructions with a SIGILL signal handler as an anti-decompilation trick. The password is stored in plaintext as four 3-character segments in .rodata.
Analysis
The "Behind the Scenes" Trick
The binary installs a SIGILL signal handler (segill_sigaction) that simply advances the instruction pointer by 2 bytes upon receiving SIGILL:
segill_sigaction:
mov -0x28(%rbp),%rax # get the ucontext struct (third arg to sigaction handler)
mov %rax,-0x8(%rbp)
mov -0x8(%rbp),%rax
mov 0xa8(%rax),%rax # get the instruction pointer (uc_mcontext.gregs[REG_RIP])
lea 0x2(%rax),%rdx # add 2 bytes (skip the ud2)
mov -0x8(%rbp),%rax
mov %rdx,0xa8(%rax) # set the instruction pointer back
Every ud2 (0x0f 0x0b) in the code is effectively a NOP at runtime but breaks static disassemblers.
Password Validation
After stripping the ud2 noise, the main logic is:
- Check
argc == 2 - Check
strlen(argv[1]) == 12 - Compare the password in 4 chunks of 3 characters each:
| Chunk | Offset in argv[1] | Compare string | Hex Offset |
|---|---|---|---|
| 1 | 0-2 | Itz | 0x201b |
| 2 | 3-5 | _0n | 0x201f |
| 3 | 6-8 | Ly_ | 0x2023 |
| 4 | 9-11 | UD2 | 0x2027 |
The comparison strings are visible directly via readelf -p .rodata or objdump -s -j .rodata.
Key Findings
- Anti-decompilation via SIGILL handler +
ud2instructions — trivial to bypass manually - Password stored in plaintext in
.rodata - Password:
Itz_0nLy_UD2
Flag
HTB{Itz_0nLy_UD2}
Tools Used
file— identify binary typestrings— initial reconobjdump— disassembly and rodata dumpreadelf— rodata string extraction
Lessons Learned
- Don't be intimidated by
ud2/ SIGILL tricks — they're just noise. Trace the execution flow regardless. - Signal handlers that increment RIP to skip instructions are a classic amateur obfuscation technique (easy to spot, trivial to reverse).
.rodatais always readable — check it even when strings don't show up instringsoutput with proper context.