← Back to Writeups
CUSTOMEasyReversing

My First Kernel

XESXOR9/2/20263 min read
#reversing#custom#easy#static_reverse_engineering#loop_inversion#state_recovery

My First Kernel

Platform: CUSTOM | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: static_reverse_engineering, loop_inversion, state_recovery

Summary

Walkthrough of the CUSTOM Reversing My First Kernel. Task: a small 32-bit kernel binary prints a hint and runs a long arithmetic/XOR state update before checking three 32-bit words against constants. Solution: reverse one loop iteration, apply the inver

Description

Попробуй запустить моё первое ядро. Там есть вывод текста :)

English summary: we are given a 32-bit kernel-style ELF that prints text directly to the screen. The binary hints that the flag can be recovered by understanding and patching the right memory values.

Analysis

The first quick win is running strings on the binary. That reveals both the theme of the task and the exact direction for analysis:

  • Hi! This is my first core. If you want to get a flag, then you need to manually patch the values in memory. Hehe :)
  • Great! Look in memory before the loop how they will look as a string, and then add them between curly brackets in CODEBY{}. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Disassembly of kmain shows a simple flow:

  1. write the intro string to VGA memory at 0xb8000,
  2. initialize four local variables,
  3. run a loop while the counter is less than 0x1337,
  4. compare the final state with three hardcoded constants,
  5. print the success message if all checks pass.

The relevant initial values are:

text
[ebp-0x8]  = 0x1337   # loop count
[ebp-0x20] = 1        # X
[ebp-0x1c] = 1        # Y
[ebp-0x18] = 1        # Z

After the loop, the program requires:

text
[ebp-0x8]  == 0x1337
[ebp-0x20] == 0x82b9f885
[ebp-0x1c] == 0x05afcb5c
[ebp-0x18] == 0x77e64835

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

The loop body performs this forward transform on three 32-bit words modulo 2^32:

text
B ^= A
B += (C ^ 0x539)
C -= (B ^ A)
A ^= (B + C)
B ^= (A - C)
C ^= (B + A)

So the task is not to brute-force the state but to invert one iteration and walk backward from the checked constants.

Solution

Let the state after one forward round be (X, Y, Z). Reversing the operations in the opposite order gives:

text
z1 = Z ^ (Y + X)
y1 = Y ^ (X - z1)
x1 = X ^ (y1 + z1)
z  = z1 + (y1 ^ x1)
y  = y1 - (z ^ 0x539)
x  = x1 ^ y

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

All arithmetic is done modulo 2^32. Applying this inverse function 0x1337 times to the target state

text
X = 0x82b9f885
Y = 0x05afcb5c
Z = 0x77e64835

yields the pre-loop values:

text
x = 0x53723166
y = 0x326b5f74
z = 0x6c654e72

These are not random numbers. Interpreting each dword as little-endian bytes gives:

text
0x53723166 -> f1rS
0x326b5f74 -> t_k2
0x6c654e72 -> rNel

Concatenating them produces the flag body REDACTED, so the final flag is CODEBY{REDACTED}.

Minimal solver: ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

python
#!/usr/bin/env python3

MASK = 0xffffffff

def inv_round(x, y, z):
    z1 = (z ^ ((y + x) & MASK)) & MASK
    y1 = (y ^ ((x - z1) & MASK)) & MASK
    x1 = (x ^ ((y1 + z1) & MASK)) & MASK
    z0 = (z1 + (y1 ^ x1)) & MASK
    y0 = (y1 - (z0 ^ 0x539)) & MASK
    x0 = (x1 ^ y0) & MASK
    return x0, y0, z0

x, y, z = 0x82b9f885, 0x05afcb5c, 0x77e64835
for _ in range(0x1337):
    x, y, z = inv_round(x, y, z)

flag_body = (
    x.to_bytes(4, "little") +
    y.to_bytes(4, "little") +
    z.to_bytes(4, "little")
).decode()
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

print(f"CODEBY{{{flag_body}}}")

Running it prints:

text
CODEBY{REDACTED}

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Key Takeaways / Lessons

  • Mastering static_reverse_engineering, loop_inversion, state_recovery was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-04-06 • CUSTOM • My First Kernel • Difficulty: Easy