Skip to main content

Bit-O-Asm-3 picoGym Exclusive Solution

Work through a small assembly routine step by step and compute the result to find the flag.

Published: March 5, 2024Updated: August 25, 2026

Description

Trace the arithmetic in the third disassembly file: move 0x9fe1a into EAX, multiply by 4, and add 0x1f5. Convert the final value into decimal.

Open the dump and focus on the MOV/IMUL/ADD sequence in main.

bash
wget https://artifacts.picoctf.net/c/530/disassembler-dump0_c.txt
bash
cat disassembler-dump0_c.txt

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1Translate each constant
    Observation
    A MOV loads a constant into EAX and an IMUL and an ADD follow. Walk the instructions in order and treat EAX as an accumulator that changes at every step.
    EAX first becomes 0x9fe1a, then is multiplied by 0x4, and finally 0x1f5 is added. Perform the arithmetic exactly as shown.
    Learn more

    This step introduces multi-instruction arithmetic tracing. Compilers routinely decompose high-level expressions like result = x * 4 + 501 into a sequence of assembly instructions, each modifying the same register. Reading the dump requires treating the register as an accumulator that changes with every instruction and tracking its value through the entire sequence.

    IMUL (Integer Multiply) multiplies the register by an immediate value and stores the product back in the same register. ADD adds an immediate value to the register. Both instructions modify EAX in place, so the order matters: multiply first, then add - not the other way around.

    This pattern mirrors the way compilers implement array indexing and struct field access. For instance, accessing array[i] where each element is 4 bytes compiles to something like mov eax, i; imul eax, 4; add eax, base_address. Recognizing these idioms lets you reconstruct the original high-level logic from the raw assembly, which is the core skill of reverse engineering.

  2. Step 2Output the decimal flag
    Observation
    The answer wants decimal and every constant in the dump is hex. Let Python evaluate the literals and print the result.
    Compute (0x9fe1a * 4) + 0x1f5 = 2,619,997. Wrap picoCTF{...}.
    python
    python3 - <<'PY'
    print((0x9fe1a * 4) + 0x1f5)
    PY

    Expected output

    2619997
    What didn't work first

    Tried: Manually converting 0x9fe1a to decimal first, then doing all arithmetic in base 10

    Intermediate rounding or transcription errors accumulate when you convert each hex constant separately before multiplying. Python accepts hex literals directly, so writing 0x9fe1a * 4 + 0x1f5 avoids any conversion step and removes the opportunity for off-by-one mistakes from manual hex-to-decimal lookups.

    Tried: Adding 0x1f5 before multiplying by 4, reversing the instruction order

    Assembly runs line by line: the multiply happens first, then the add. Swap them and you get a different number entirely. The order in the dump is the order that ran.

    Learn more

    Python is an excellent calculator for this kind of arithmetic because it understands hex literals natively. Writing 0x9fe1a * 4 + 0x1f5 directly in Python gives the correct result without any manual conversion - you work in the same notation as the assembly listing.

    The here-document syntax (<<'PY' ... PY) passes a multi-line script to Python from the command line without needing a temporary file. This is a useful shell technique for quick computations in CTF work and scripting generally. Alternatively, python3 -c "print((0x9fe1a * 4) + 0x1f5)" achieves the same result on one line.

    Choosing the right tool for arithmetic conversions matters when time is limited in a CTF. Python handles arbitrarily large integers, understands hex and binary literals, and is available on virtually every Linux system - making it the default choice for quick calculations in competitive security contexts.

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{...}

The dump intentionally includes unused instructions; only the highlighted arithmetic matters for the flag.

Key takeaway

Compilers turn arithmetic expressions into runs of multiply and add instructions that each modify a register in place, and the order decides the answer. The same multiply-then-add shape shows up in array index math, struct field offsets, and hash functions, so recognizing it lets you rebuild the source from the assembly. The habit that matters is treating a register as a running accumulator: write down its value after every instruction rather than assuming you know it.

Related reading

Useful tools for Reverse Engineering

Where to go next