xorpd assembly riddle 0x04

Syscall59
Syscall59
Dec 8, 2018 · 3 min read

xorpd has some riddle-like pieces of assembly code here. In this post, I’ll analyze this one.

I present to you this marvelous one-line riddle:

xor      al,0x20

What can we infer from this?

  1. It’s using al register: a single byte it’s being used
  2. 0x20 = 32 = 00100000
checking the values equivalences using r2

Now, let’s talk about xor a little. This is its truth table:

input1 | input2 | result
0 | 0 | 0
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0

Analyzing the second column we can see that a 0 placed there will preserve the value of input2 and a 1 will flip its value instead:

input1 | input2 | result
0 | 0 | 0 ==> input2=0, input1=result
0 | 1 | 1 ==> input2=1, input1=!result
1 | 0 | 1 ==> input2=0, input1=result
1 | 1 | 0 ==> input2=1, input1=!result

That’s why xor {regX},{regX} is used a lot by compilers to zero out a register. Observe that any value XORed with itself is equal to 0. i.e: the operation 00110101 xor 00110101 can be expressed like:

input1 | input2 | input1 xor input2
0 | 0 | 0
0 | 0 | 0
1 | 1 | 0
1 | 1 | 0
0 | 0 | 0
1 | 1 | 0
0 | 0 | 0
1 | 1 | 0
Basically every 0 is preserved and every 1 is flipped so we end up with all zeros as results

So, going back to our riddle. We can express what we know so far as:

  al   |   0x20 | xor al, 020
? | 0 | ?
? | 0 | ?
? | 1 | x ==> this bit will be flipped
? | 0 | ?
? | 0 | ?
? | 0 | ?
? | 0 | ?
? | 0 | ?
As the only 1 in 0x20 is at bit n°6 that's the only bit that will flipped on al

How does this bit flip affects al? It will add or subtract 32 (0x20) from al depending on al’s original value:

Case 1: Imagine al to be 0x0 = 0 = 00000000
al | 0x20 | xor al, 020
0 | 0 | 0
0 | 0 | 0
0 | 1 | 1
0 | 0 | 0
0 | 0 | 0
0 | 0 | 0
0 | 0 | 0
0 | 0 | 0
result = 0x20 = 32 = 00100000
Case 2: Imagine al to be 0xff = 255 = 11111111
al | 0x20 | xor al, 020
1 | 0 | 1
1 | 0 | 1
1 | 1 | 0
1 | 0 | 1
1 | 0 | 1
1 | 0 | 1
1 | 0 | 1
1 | 0 | 1
result = 0xdf = 223 = 11000000

Let’s try some more values:

al   | 0x20 | xor al, 020
0x00 | 0x20 | 0x20 = 00100000 = 32 = " "
0xff | 0x20 | 0xdf = 11011111 = 223 = (no ascii value)
0x41 | 0x20 | 0x61 = 01100001 = 97 = "a"
0x50 | 0x20 | 0xdf = 01110000 = 112 = "p"
0x61 | 0x20 | 0x41 = 01000001 = 65 = "A"

From this, it’s clear that values from ASCII letters in uppercase are converted to its lowercase counterpart and vice-versa. We can check this by calculating the distance between the boundary characters:

Upper | lower | distance
A | a | 0x41 - 0x61 = 0x20
Z | z | 0x5a - 0x7a = 0x20

So, long story short this single line of assembly performs a lowercase/uppercase ASCII conversion! isn’t that awesome?


syscall59

Shellcode for the masses

Syscall59

Written by

Syscall59

Twitter: @syscall59 | medium.syscall59.com | syscall59@protonmail.com

syscall59

syscall59

Shellcode for the masses