Description
What does asm2(0x6, 0x24) return? Trace through the x86 assembly with loop logic. Submit the flag as a hexadecimal value.
Setup
Download the assembly file.
wget <url>/test.SSolution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1Read the assembly
ObservationThe challenge gives a .S source file and calls asm2(0x6, 0x24). Read the raw assembly first to find the function's structure, where its arguments sit, and where the loop begins and ends.Open test.S. The function asm2 is called as asm2(0x6, 0x24): the first argument 0x6 is at [ebp+8] and the second 0x24 is at [ebp+12]. It contains a loop. Identify the loop variable, the loop condition, the loop body operations, and the exit value. Note that the step constant and loop bound are instance-specific, so verify them in your own test.S.bashcat test.SWhat didn't work first
Tried: Assume [ebp+8] is the second argument and [ebp+12] is the first argument, reversing the parameter order.
x86 cdecl pushes arguments right to left, so the first sits at [ebp+8] and the second at [ebp+12]. Swap them and the accumulator and counter start wrong, the loop runs a different number of times, and the return value is wrong.
Tried: Use objdump or ndisasm to disassemble test.S directly instead of reading it as source.
test.S is assembly source text, not an object file or a binary. Run objdump -d or ndisasm on it and the tool reads the ASCII characters as machine code and prints nonsense. Just open it with cat or an editor: it is already readable.
Learn more
Assembly loops use conditional jumps to backward labels. A typical loop structure: initialize a counter, compare it to a limit, do the body, increment the counter, and jump back if the condition still holds.
The two arguments are stored at fixed offsets from ebp: first argument at [ebp+8], second at [ebp+12]. Local variables are at negative offsets: [ebp-4], [ebp-8], etc.
Step 2Simulate the loop on paper
ObservationThe assembly contains a loop with a counter and an exit condition. Step through it with the given inputs 0x6 and 0x24, tracking eax each iteration until the condition is met.Initialize the local variables with the given arguments. Step through each iteration of the loop, tracking register and memory values, until the exit condition is met. Note the value in eax at the ret instruction.Learn more
Alternatively, translate the assembly to Python for rapid simulation: replace each assembly instruction with equivalent Python operations and print intermediate values to verify.
Step 3Submit the return value
ObservationThe question asks what asm2(0x6, 0x24) returns, and the function leaves its result in eax at ret. So the final eax value from the simulation is the answer, submitted in hex.The return value in hex (preceded by 0x) is the answer. Check if it should be wrapped in picoCTF{...}.Learn more
Understanding loop patterns in assembly is essential for reversing cryptographic algorithms, where loops process data byte-by-byte or block-by-block. Recognizing the loop structure quickly is more valuable than tracing every iteration manually.
Interactive tools
- Hex ViewerView text or raw hex bytes as a xxd-style hex dump with byte offset, hex columns, and ASCII sidebar. Highlights printable characters and null bytes.
- Number Base ConverterConvert numbers between binary, octal, decimal, and hexadecimal instantly. Enter any value and see all four bases update in real time.
Flag
Reveal flag
picoCTF{0x63}
asm2(0x6, 0x24): the loop adds 0xf each iteration until the counter exceeds arg2 (0x24), and the function returns 0x63.