Rusty ARM
Rusty ARM
Platform: CUSTOM | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: checker_reconstruction, static_reverse_engineering, transform_inversion
Summary
Walkthrough of the CUSTOM Reversing Rusty ARM. Task: a Rust ARM64 checker reads a line, trims it, transforms each byte through a small closure, and compares the result with a fixed reference_password vector. Solution: reconstruct the exact per-byt
Description
Ржавый ARM
English summary: we are given a Rust ARM64 binary that asks for a password and accepts only the input whose transformed bytes match a hardcoded reference vector.
Analysis
This corrected writeup supersedes the earlier incorrect local/API entry 20260406_hackerlab_rusty_arm, which used the wrong reconstructed bytes and therefore produced the wrong flag.
The main checker flow is straightforward once the Rust standard-library calls are identified:
- print a prompt,
- call
read_line, - call
trim, - iterate over
password.bytes(), - apply a closure to each byte,
- collect the result into
Vec<u8>, - compare that vector with
reference_password.
The valid reconstructed logic is:
rust read-only • copy allowedlet encrypted_password: Vec<u8> = password.bytes().map(|b| { let add_result = b.wrapping_add(0x30); let xor_result = add_result ^ 0x45; let sub_result = xor_result.wrapping_sub(0x99); let qwe = sub_result.wrapping_add(0x35); let xor_result2 = qwe ^ 0x45; xor_result2 }).collect();
The correct reference_password bytes are:
python read-only • copy allowedreference_password = [ 0x97, 0x93, 0x88, 0x89, 0x96, 0x2d, 0xcf, 0x26, 0x86, 0xc7, 0x18, 0x23, 0x2a, 0x84, 0x26, 0x23, 0x95, 0x26, 0x91, 0x23, 0x3b, 0x3c, 0x94, 0x38, 0x83, 0xc1, ]
Because the transformation is applied independently to each byte, we can reverse it byte by byte without emulating the whole program.
Solution
To invert one output byte, reverse the operations in the opposite order:
- XOR
0x45 - subtract
0x35 - add
0x99 - XOR
0x45 - subtract
0x30
In code:
python read-only • copy allowed#!/usr/bin/env python3 reference_password = [ 0x97, 0x93, 0x88, 0x89, 0x96, 0x2d, 0xcf, 0x26, 0x86, 0xc7, 0x18, 0x23, 0x2a, 0x84, 0x26, 0x23, 0x95, 0x26, 0x91, 0x23, 0x3b, 0x3c, 0x94, 0x38, 0x83, 0xc1, ] def invert_byte(x: int) -> int: x ^= 0x45 x = (x - 0x35) & 0xff x = (x + 0x99) & 0xff x ^= 0x45 x = (x - 0x30) & 0xff return x flag = bytes(invert_byte(x) for x in reference_password).decode() print(flag)
Running the script yields:
text read-only • copy allowedCODEBY{REDACTED}
That matches the expected format and is the correct password accepted by the checker.
Key Takeaways / Lessons
- Mastering checker_reconstruction, static_reverse_engineering, transform_inversion was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-04-06 • CUSTOM • Rusty ARM • Difficulty: Easy