Assembly Assortment


Computing 101.

You have a working knowledge of assembly from your journey thus far. Let's broaden it!

This module will explore the effects of a number of different assembly instructions, teaching you to recognize them and not panic in their presence. Generally, each challenge will force you to understand its effect on data and generate data that it will accept. If you can do this, you will get flags!


In the previous challenge, you reversed a program by finding password characters directly in the cmp instructions. This time, the program transforms your input before comparing it. You'll need to understand and mentally invert this operation to successfully pass the check!

At /challenge/reverse-me, there's a new SUID binary. It will do some math on the first byte of the first program argument, and compare it against a hardcoded value. If the comparison passes, it reads and prints the flag. Otherwise, it silently exits.

The new instruction here is add, as so:

add rax, 42

This adds 42 to the rax register and updates rax with the result. The following would result in rax having the value 99:

mov rax, 57
add rax, 42

Like many other instructions, add can handle memory, registers, or immediates, when you disassemble this binary with objdump -d -M intel /challenge/reverse-me, you might see something like:

add    BYTE PTR [rax],0x2a
cmp    BYTE PTR [rax],0x96

This adds 0x2a (42) to the first byte of your input (in memory), then checks if the result equals 0x96 (150). To figure out what character you need, just reverse the math: 150 - 42 = 108 (6c). Looking at man ascii, 0x6c is the character 'l'. So the required input character in this case is l (remember, man ascii is your friend for converting between hex values and characters)!

Once you've figured out the character, run the program:

hacker@dojo:~$ /challenge/reverse-me YOUR_CHARACTER_HERE

Now it's your turn! Go and get the flag.


WARNING: /challenge/reverse-me is a SUID binary --- it runs with elevated privileges so it can read /flag. However, debugging a program will drop its SUID privileges, which means the open("/flag") syscall inside will silently fail if you run it under gdb. You can use gdb or objdump to understand the binary, but make sure to run it directly (outside of gdb) to get the flag.

Connect with SSH

Link your SSH key, then connect with: ssh [email protected]

In the previous challenge, the program used add to transform your input before checking it. This time, it uses sub (as in, subtract) instead. Analogous to add, sub rax, 42 will subtract 42 from rax and store the result in rax.

Otherwise, this challenge is the same as the previous one. Go get it!

Connect with SSH

Link your SSH key, then connect with: ssh [email protected]

This challenge introduces a new type of operation: bitwise XOR. Unlike add and sub, which do arithmetic, xor operates on individual bits.

The xor instruction computes the exclusive or of two values: for each bit position, the result is 1 if exactly one of the two input bits is 1, and 0 otherwise. For example:

  01100001  (0x61, 'a')
^ 00101010  (0x2a, 42)
---------
  01001011  (0x4b, 75)

The syntax is the same as add and sub: xor rax, 42.

A key property of XOR is that it's its own inverse: xoring a value with the same value twice gives back the original value. So if you see:

xor    BYTE PTR [rax],0x2a
cmp    BYTE PTR [rax],0x4b

The program XORs your input byte with 0x2a and checks if the result is 0x4b. To reverse this, XOR the target with the key: 0x4b ^ 0x2a = 0x61, which is 'a'.

Now: disassemble the binary, reverse the XOR, and get the flag!

Connect with SSH

Link your SSH key, then connect with: ssh [email protected]

So far, the values you've been reversing have been embedded directly in instructions as immediate operands. However, this challenge compares the first program argument against a hardcoded string inside the challenge. The string lives in a different section of the program file: the binary's .rodata (read-only data) section, rather than in the instructions themselves.

There are several options to find it:

  • The most familiar: stepi to where the comparison is happening and x the registers pointing to the data.
  • Use strings /challenge/reverse-me to list all printable strings in the binary. There are a lot, but one of them will be the password.
  • Use objdump -s -j .rodata /challenge/reverse-me to dump the raw contents of the .rodata section.

Which you use is up to you!

Connect with SSH

Link your SSH key, then connect with: ssh [email protected]

30-Day Scoreboard:

This scoreboard reflects solves for challenges in this module after the module launched in this dojo.

Rank Hacker Badges Score