← Back to Writeups
CUSTOMEasyReversing

ASM0

XESXOR9/2/20263 min read
#reversing#custom#easy#conditional_jump_analysis#manual_control_flow_tracing

ASM0

Platform: CUSTOM | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: conditional_jump_analysis, manual_control_flow_tracing

Summary

Walkthrough of the CUSTOM Reversing ASM0. Task: given an x86 NASM assembly source (asm_0.s), statically trace the control flow and report the final value of edx at the finish label. Solution: hand-trace the jump graph, noting that a cmp of

Description

Дан исходный файл на ассемблере (NASM, x86) asm_0.s. Определите значение регистра edx в точке метки finish. edx = ?

English summary: a NASM x86 source file is provided. The goal is to statically trace the control flow and report the value of register edx when execution reaches the finish label. The answer (REDACTED) is submitted via a POST flag form.

Analysis

There is no binary to run — only the assembly source. The challenge is a pure control-flow-tracing exercise over a graph of labels (Metka0..Metka5, finish) connected by conditional and unconditional jumps. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

nasm
_start:
    xor eax, eax        ; eax=ebx=ecx=edx=0
    xor ebx, ebx
    xor ecx, ecx
    xor edx, edx
Metka0:
    add eax, 0x0A
    add ebx, 20
    sub ebx, eax
    cmp eax, ebx
    jl Metka5           ; taken only if eax <  ebx (signed)
    jge Metka4          ; taken if  eax >= ebx
Metka1:
    add ecx, ecx
    add ecx, ecx        ; ecx *= 4
    sub edx, ecx
    cmp edx, eax
    jz finish
    jmp Metka2
...

Two pitfalls make this trickier than it looks:

  1. Equal operands. After cmp eax, ebx with eax == ebx, the Zero Flag is set and the Sign/Overflow flags agree, so jl is not taken but jge is.
  2. Only the first satisfied jump fires. When two conditional jumps sit back to back (e.g. jl Metka5 / jge Metka4), exactly one of them is taken. The second becomes unreachable for that pass — it is not a fall-through. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Solution

Hand-trace from _start:

StepLabelOperationseaxebxecxedxBranch decision
0startall xor0000fall to Metka0
1Metka0eax+=0x0A; ebx+=20; ebx-=eax; cmp eax,ebx0x0A0x0A00eax==ebx → jge Metka4
2Metka4edx=50; ecx=0x0A; cmp eax,edx0x0A0x0A0x0A500x0A>50 false → jmp Metka3
3Metka3edx^=ecx (0x32^0x0A=0x38); edx^=eax (0x38^0x0A=0x32); cmp edx,eax0x0A0x0A0x0A5050!=0x0A → jne Metka1
4Metka1ecx*=4 (0x0A→40); edx-=ecx (50-40=0x0A); cmp edx,eax0x0A0x0A400x0Aequal → jz finish
5finish—0x0A0x0A40REDACTEDdone
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Step 3 detail (XOR arithmetic):

  • edx = 50 = 0x32, ecx = 0x0A
  • edx ^= ecx → 0x32 ^ 0x0A = 0x38 = 56
  • edx ^= eax → 0x38 ^ 0x0A = 0x32 = 50

At finish, edx = REDACTED. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering conditional_jump_analysis, manual_control_flow_tracing was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-06-13 • CUSTOM • ASM0 • Difficulty: Easy