← Back to Writeups
CUSTOMEasyReversing

JCOm

XESXOR9/2/20262 min read
#reversing#custom#easy#brute_force_argument#iterative_recurrence_conversio#modular_arithmetic_32bit#static_analysis

JCOm

Platform: CUSTOM | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: brute_force_argument, iterative_recurrence_conversion, modular_arithmetic_32bit, static_analysis

Summary

Walkthrough of the CUSTOM Reversing JCOm. Task: tiny 32-bit PE console binary that takes a number argument, runs a slow naive Fibonacci-like recursion, and prints 'Success' when the result equals a magic constant. Solution: reverse the recurr

Description

This app takes a number as argument, and calculates something. It can say "Success", but does it too slow. Flag is the number it will show "Success" on.

Given: a tiny 32-bit PE32 console executable JCOm.exe (Intel 80386, stripped to an external PDB, linked against msvcrt). It takes a single integer argument and prints either Success or ERROR. The flag is the argument value N that makes it print Success. The "too slow" wording is a strong hint that a naive exponential recursion is involved and should be replaced by a fast closed/iterative computation. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Analysis

Static analysis with radare2 revealed the structure:

  • The CRT entry resolves argv and then calls the real main at 0x401053.

  • main:

    • requires argc >= 2, otherwise prints argument error.
    • parses N = atoi(argv[1]).
    • runs the recursive function (0x401000) 1024 times in a busy loop — this is the "too slow" part, pure wasted work and a distraction.
    • runs it once more and compares the result to the magic constant 0x33ad3349 (867263817).
    • equal → printf("Success"), else → ERROR.
  • The recursive function f at 0x401000 implements: ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

    f(n) = 1                         if n <= 2
    f(n) = f(n-1) + f(n-2) + 1       otherwise
    

    This is a Fibonacci-like recurrence. The naive doubly-recursive implementation is exactly why running the binary is slow — it grows exponentially. The arithmetic is done in 32-bit registers, so it wraps mod 2^32.

The key realization: we never need to run the slow binary. The recurrence can be computed iteratively in O(n), and we just need the n for which f(n) == 0x33ad3349 under 32-bit wraparound. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Solution

Compute f(n) iteratively with 32-bit modular arithmetic and search for the matching argument:

python
#!/usr/bin/env python3
target = 0x33ad3349
MASK = 0xffffffff

p2 = p1 = 1  # f(1) = f(2) = 1
for n in range(3, 200):
    cur = (p1 + p2 + 1) & MASK
    if cur == target:
        print("n =", n)  # -> REDACTED
        break
    p2, p1 = p1, cur

This yields n = REDACTED, and f(REDACTED) = 0x33ad3349. So the argument that makes the binary print Success is REDACTED.

The flag is simply that number: REDACTED. Submitted via POST flag, the server accepted REDACTED. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering brute_force_argument, iterative_recurrence_conversion, modular_arithmetic_32bit, static_analysis was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-06-15 • CUSTOM • JCOm • Difficulty: Easy