Graphics Programs Reference
In-Depth Information
which means that a small value like 19 will have to be padded with leading
zeros resulting in null bytes.
One way around this problem takes advantage of two's complement. A
small negative number will have its leading bits turned on, resulting in 0xff
bytes. This means that, if we call using a negative value to move backward in
execution, the machine code for that instruction won't have any null bytes.
The following revision of the helloworld shellcode uses a standard implemen-
tation of this trick: Jump to the end of the shellcode to a call instruction which,
in turn, will jump back to a pop instruction at the beginning of the shellcode.
helloworld2.s
BITS 32 ; Tell nasm this is 32-bit code.
jmp short one ; Jump down to a call at the end.
two:
; ssize_t write(int fd, const void *buf, size_t count);
pop ecx ; Pop the return address (string ptr) into ecx.
mov eax, 4 ; Write syscall #.
mov ebx, 1 ; STDOUT file descriptor
mov edx, 15 ; Length of the string
int 0x80 ; Do syscall: write(1, string, 14)
; void _exit(int status);
mov eax, 1 ; Exit syscall #
mov ebx, 0 ; Status = 0
int 0x80 ; Do syscall: exit(0)
one:
call two ; Call back upwards to avoid null bytes
db "Hello, world!", 0x0a, 0x0d ; with newline and carriage return bytes.
After assembling this new shellcode, disassembly shows that the call
instruction (shown in italics below) is now free of null bytes. This solves the
first and most difficult null-byte problem for this shellcode, but there are still
many other null bytes (shown in bold).
reader@hacking:~/booksrc $ nasm helloworld2.s
reader@hacking:~/booksrc $ ndisasm -b32 helloworld2
00000000 EB1E jmp short 0x20
00000002 59 pop ecx
00000003 B804 000000 mov eax,0x4
00000008 BB01 000000 mov ebx,0x1
0000000D BA0F 000000 mov edx,0xf
00000012 CD80 int 0x80
00000014 B801 000000 mov eax,0x1
00000019 BB 00000000 mov ebx,0x0
0000001E CD80 int 0x80
00000020 E8DDFFFFFF call 0x2
00000025 48 dec eax
00000026 656C gs insb
00000028 6C insb
Search WWH ::




Custom Search