26.07.2018 Views

hacking-the-art-of-exploitation

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

00000029 6F outsd<br />

0000002A 2C20<br />

sub al,0x20<br />

0000002C 776F<br />

ja 0x9d<br />

0000002E 726C<br />

jc 0x9c<br />

00000030 64210A and [fs:edx],ecx<br />

00000033 0D db 0x0D<br />

reader@<strong>hacking</strong>:~/booksrc $<br />

These remaining null bytes can be eliminated with an understanding <strong>of</strong><br />

register widths and addressing. Notice that <strong>the</strong> first jmp instruction is actually<br />

jmp short. This means execution can only jump a maximum <strong>of</strong> approximately<br />

128 bytes in ei<strong>the</strong>r direction. The normal jmp instruction, as well as <strong>the</strong> call<br />

instruction (which has no short version), allows for much longer jumps. The<br />

difference between assembled machine code for <strong>the</strong> two jump varieties is<br />

shown below:<br />

EB 1E<br />

jmp short 0x20<br />

versus<br />

E9 1E 00 00 00<br />

jmp 0x23<br />

The EAX, EBX, ECX, EDX, ESI, EDI, EBP, and ESP registers are 32 bits<br />

in width. The E stands for extended, because <strong>the</strong>se were originally 16-bit registers<br />

called AX, BX, CX, DX, SI, DI, BP, and SP. These original 16-bit versions<br />

<strong>of</strong> <strong>the</strong> registers can still be used for accessing <strong>the</strong> first 16 bits <strong>of</strong> each corresponding<br />

32-bit register. Fur<strong>the</strong>rmore, <strong>the</strong> individual bytes <strong>of</strong> <strong>the</strong> AX, BX, CX,<br />

and DX registers can be accessed as 8-bit registers called AL, AH, BL, BH, CL,<br />

CH, DL, and DH, where L stands for low byte and H for high byte. Naturally,<br />

assembly instructions using <strong>the</strong> smaller registers only need to specify operands<br />

up to <strong>the</strong> register’s bit width. The three variations <strong>of</strong> a mov instruction are<br />

shown below.<br />

Machine code<br />

Assembly<br />

B8 04 00 00 00 mov eax,0x4<br />

66 B8 04 00 mov ax,0x4<br />

B0 04<br />

mov al,0x4<br />

Using <strong>the</strong> AL, BL, CL, or DL register will put <strong>the</strong> correct least significant<br />

byte into <strong>the</strong> corresponding extended register without creating any null bytes<br />

in <strong>the</strong> machine code. However, <strong>the</strong> top three bytes <strong>of</strong> <strong>the</strong> register could still<br />

contain anything. This is especially true for shellcode, since it will be taking<br />

over ano<strong>the</strong>r process. If we want <strong>the</strong> 32-bit register values to be correct, we<br />

need to zero out <strong>the</strong> entire register before <strong>the</strong> mov instructions—but this, again,<br />

must be done without using null bytes. Here are some more simple assembly<br />

instructions for your arsenal. These first two are small instructions that increment<br />

and decrement <strong>the</strong>ir operand by one.<br />

292 0x500

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!