## The use of XOR in assembly and shellcode

XOR WITH ONE’S SELF

If we XOR a byte (or bit) with itself, we will get a null byte (or zero bit).

We will explore all cases:

0 XOR 0 = 0
1 XOR 1 = 0

This is a way to create null bytes in shellcode, without actually including the null values.

Example:
XOR EAX, EAX ( which has the code bytes 33 C0)

This command XORs EAX with itself. Whatever the contents of EAX are, in the end EAX will be 0 (all 4 bytes – or 32 bits – will be zero).

The previous command is better than
MOV EAX, 0 (which has the code bytes B8 00 00 00 00)
because the latter command contains a null byte (actually four null bytes, but even one would be disastrous), and we avoid placing null bytes in shellcode, because usually shellcode fills strings. Strings are terminated by null bytes, and we do not want our shellcode to end prematurely.

Also, the former command is smaller by two bytes, resulting in smaller shellcode.

DOUBLE XOR

If we XOR a byte (or bit) with a constant byte (or bit), and we XOR the result with the same constant byte (or bit), we will get back the original byte (or bit).

We will explore all cases:

```Data   Constant   First XOR (Encoding XOR)      Second XOR (Decoding XOR)

Data XOR Constant = Result    Result XOR Constant = Data

0        0            0 XOR 0      =   0            0 XOR 0        =  0
0        1            0 XOR 1      =   1            1 XOR 1        =  0
1        0            1 XOR 0      =   1            1 XOR 0        =  1
1        1            1 XOR 1      =   0            0 XOR 1        =  1```

In shellcode, we choose to XOR-encode bytes with a byte that does not appear in the bytes we will XOR-encode. This is because, although the XOR-decoding will work fine, the XOR-encoding will produce a null byte when XOR-ing with the same byte as the XOR constant. Since we do not want null bytes in shellcode, we avoid using a XOR constant that appears in the bytes we want to XOR-encode.