Description
Debugger0_d jumps into func1 where EAX is multiplied by a constant. Convert that constant to decimal for the final flag.
Setup
Launch the binary under gdb and examine main until it calls func1.
Inside func1, watch for the IMUL instruction that scales EAX; its immediate operand is the flag.
wget https://artifacts.picoctf.net/c/532/debugger0_dchmod +x debugger0_dgdb --args ./debugger0_dSolution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1
Step into func1ObservationI noticed the disassembly of main ends with a CALL to func1 before any meaningful arithmetic appears, which suggested the actual constant we need is inside that called function and we must follow execution into it rather than stepping over the call.From main, step or break inside func1 (main+38). Within func1 the IMUL at offset +14 multiplies EAX by 0x3269.Learn more
This challenge introduces control flow tracing across function boundaries. Main calls
func1using aCALLinstruction, which pushes the return address onto the stack and transfers control to the called function. In GDB,stepi(step one instruction, entering calls) follows execution intofunc1, whilenexti(step over) would execute the entire call and return as a single step.In real reverse engineering, following call graphs is essential. Complex software can have hundreds of nested function calls, and understanding the data flow requires knowing which functions are called in what order and what they do to the arguments. GDB's
backtracecommand (aliasbt) shows the current call stack, which helps you understand where you are in the call hierarchy at any breakpoint.The IMUL instruction at
func1+14is the key. Setting a breakpoint at that exact offset (b *(func1+14)) would land execution right before the multiply, letting you inspect EAX before and after to observe the transformation. Alternatively, breaking after the IMUL and reading the assembly listing statically reveals the multiplier without needing to run anything.Step 2
Convert the constantObservationI noticed the IMUL instruction at func1+14 uses the immediate operand 0x3269 as its multiplier, which suggested the challenge wanted that constant converted from hex to decimal rather than any runtime register value.Translate 0x3269 into decimal and wrap it with picoCTF{...}. Any method works-printf, python, or bc all give 12905.pythonpython3 - <<'PY' print(0x3269) PYbashprintf "picoCTF{%d}\n" 0x3269Expected output
picoCTF{...}What didn't work first
Tried: Run the binary, let func1 execute, then read EAX after the IMUL to get the flag value.
EAX before the IMUL holds whatever main passed in as an argument, so the product depends on runtime input and is not a constant. The challenge asks for the multiplier - the immediate operand 0x3269 - not the result of the multiplication. Reading the IMUL operand from the disassembly, not the register after execution, gives the reliable constant.
Tried: Interpret 0x3269 as ASCII by treating the two bytes 0x32 and 0x69 as characters.
0x32 is the ASCII character '2' and 0x69 is 'i', so the bytes spell '2i' - which is not a meaningful flag value. The challenge instruction says to convert the hex constant to its decimal integer value (12905), then wrap it with picoCTF{}. Decimal conversion is the required step, not ASCII decoding.
Learn more
0x3269converts to decimal 12905. The challenge specifically asks for the multiplier - the immediate operand of the IMUL instruction - rather than the result of the multiplication. This distinction matters: the multiplier is a constant visible in the disassembly, while the result depends on whatever value EAX held before the IMUL, which could vary across runs.This challenge wraps up the GDB Baby Step series by combining all the skills introduced in the previous three: disassembling a binary, tracing data flow across instructions, following a function call, and converting a constant from hex to decimal. Each step was simple in isolation, but combining them is the actual skill being assessed.
The real-world application is binary auditing for hardcoded constants. License keys, encryption round counts, magic numbers for validation, and protocol version numbers all appear as constants in binaries. Being able to locate and extract them using GDB or static disassembly tools is a core reverse engineering skill used in vulnerability research, malware analysis, and software interoperability work.
Flag
Reveal flag
picoCTF{...}
Only the multiplier matters; the rest of the function simply returns EAX after scaling.