← Back to Writeups
CUSTOMEasyReversing

C-ASM

XESXOR9/2/20263 min read
#reversing#custom#easy#algorithm_fingerprinting#control_flow_analysis#disassembly_pattern_matching

C-ASM

Platform: CUSTOM | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: algorithm_fingerprinting, control_flow_analysis, disassembly_pattern_matching

Summary

Walkthrough of the CUSTOM Reversing C-ASM. Task: given 5 C sources (c1..c5) and 5 x86-64 disassembly listings (asm1..asm5), pair each C file with the semantically equivalent ASM. Solution: recognize classic algorithm fingerprints in disassembl

Description

c_asm.zip contains 5 C source files (c1.c..c5.c) and 5 x86-64 disassembly listings (asm1.s..asm5.s). Each C file is functionally identical to exactly one of the ASM listings. Match them. Answer format example: 1-1, 2-2, 3-3, 4-4, 5-5 (i.e. Ci-ASMj pairs). Submit via POST flag.

A beginner reverse-engineering / source-matching task. The goal is to read each C source, identify the algorithm it implements, then find the disassembly listing that implements the same algorithm. The "flag" is the pairing string. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Analysis

C sources

FileAlgorithmKey signature
c1.cBubble sort of int a[10]={0..9}nested loops + swap via temp; swaps when a[j] <= a[j+1] (descending)
c2.cminimum(a,b)if (a<b) return a; else return b;
c3.cgcd_iter(u,v)abs both, then while ((u%=v) && (v%=u)); return u+v (Euclid by modulo)
c4.cfind_elem(array,size,elem)linear search, returns index or -1
c5.cis_even(num)num%2 then switch: case 0 → 1, case 1 → 0
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

ASM listings

Each listing was identified purely by its algorithmic fingerprint:

  • asm1.s — initializes VAR[0..9] = 0..9, nested loops over VAR_I/VAR_J, compares adjacent elements and swaps via a temp at [rbp-0x34]. Classic bubble sort → matches c1.
  • asm2.s — function(rdi=ptr, esi=size, edx=elem); loops i=0..size-1, loads array[i], compares to elem, returns i on match else returns 0xffffffff (-1). Linear search → matches c4.
  • asm3.s — function(edi, esi); a single cmp edi,esi; jge ... selects and returns the smaller operand. minimum → matches c2.
  • asm4.s — function(edi=VAR_1, esi=VAR_2); neg on negative inputs (abs), then a loop using idiv to take remainders alternately into VAR_1/VAR_2 until zero, returning VAR_1+VAR_2. Euclid GCD → matches c3.
  • asm5.s — function(edi); computes num%2 via the standard signed-modulo idiom shr edx,0x1f; add; and 0x1; sub edx, then tests: 0 → return 1, 1 → return 0. Parity check → matches c5. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Solution

Match each C algorithm to its ASM fingerprint:

C fileAlgorithmASM listing
c1 (bubble sort)nested-loop swapasm1
c2 (minimum)single branch selecting smallerasm3
c3 (gcd)idiv remainder loop returning sumasm4
c4 (find_elem)linear scan, 0xffffffff sentinelasm2
c5 (is_even)% 2 + switch/branchasm5

Resulting pairing string:

REDACTED

POST this as the flag parameter; the server accepts it. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering algorithm_fingerprinting, control_flow_analysis, disassembly_pattern_matching was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

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