Nov 19, 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 the riddle number 0x02:

`neg      raxsbb      rax,raxneg      rax`

In order to understand this one we first need to understand neg and sbb instructions. Let’s check Intel’s manuals:

Integer Subtraction with Borrow (aka sbb) definition from Intel’s manual:

Adds the source operand (second operand) and the carry (CF) flag, and subtracts the result from the destination operand (first operand). The result of the subtraction is stored in the destination operand

`DEST ← (DEST — (SRC + CF));`

Two’s Complement Negation (aka neg) definition from Intel’s manual:

Replaces the value of operand (the destination operand) with its two’s complement. (This operation is equivalent to subtracting the operand from 0.)

`IF DEST = 0   THEN CF ← 0;   ELSE CF ← 1;FI;DEST ← [– (DEST)]`

Now you may ask, how’s the two’s complement obtained? It’s obtained just by flipping every bit and then adding 1 to the result. Here are some examples:

`00110101 ==(flip)==> 11001010 ==(+1)==> 11001011 11001011 is the 2’s complement of 0011010111110000 ==(flip)==> 00001111 ==(+1)==> 0001000000010000 is the 2’s complement of 11110000`

Now that we grasp what each instruction does let’s analyze the code line by line

## Line 1: neg rax

This computes the two’s complement, places the result into rax and updates the Carry Flag (CF) accordingly.

`Example 1: Suppose the original value from rax on line 1 was 101neg rax ; rax is now = !rax+1 = (!101)+1 = 010+1 = 011        ; CF=1Example 2: Suppose the original value from rax on line 1 was 000neg rax ; rax is now = !rax+1 = (!000)+1 = 111+1 = 000        ; CF=0`

## Line 2: sbb rax, rax

This op performs subtraction between rax and itself + the CF (which is 0 if the original value from rax was 0, or 1 otherwise).

`Following Example 1 (original rax value was 101):sbb rax, rax ; This can be expressed as:             ;   1. 011 - (011+CF) CF=1 in this case, from prev op             ;   2. 011 - (011+1)  <--|             ;   3. 011 - 100             ;   4. 111   A borrow occurred hereFollowing Example 2 (original rax value was 000):sbb rax, rax ; This can be expressed as:             ;   1. 000 - (000+CF) CF=0 in this case, from prev op             ;   2. 000 - (000+0)  <--|             ;   3. 000 - 000             ;   4. 000`

## Line 3: neg rax

Same as in line 1, of course, but just with updated values from previous ops:

`Following Example 1 (original rax value was 101):neg rax ; rax is now = !rax+1 = (!111)+1 = 000+1 = 001Following Example 2 (original rax value was 000):neg rax ; rax is now = !rax+1 = (!000)+1 = 111+1 = 000`

## Conclusion

As a final conclusion, we can say that this piece of code sets rax to 0 if its original value was 0 or to 1 if it was otherwise. I can imagine this to be a sort of integer to boolean conversion. In a high-level programming language this could be expressed as:

`func foo(n *int) bool {  return *n != 0}`

Written by

## syscall59

#### Shellcode for the masses

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just \$5/month. Upgrade