Reputation: 751
I have this code in assembly:
global _start
section .rodata
hello: db "Hello World!", 10
section .text
_start:
mov eax,4
mov ebx,1
mov ecx,hello
mov edx,13
int 80h
; Terminate program
mov eax,1
xor ebx,ebx
int 80h
If I take objdump of the following code, I get:
If I get NUL characters in the objdump I will not be able to achieve the task I'm working on. How can I get objdump without any NUL(0x00) bytes?
Upvotes: 4
Views: 1137
Reputation: 47633
In order to eliminate NUL(0x00) bytes in OBJDUMP you need to write shellcode that assembles into instructions that don't include NUL bytes. The methods you use are also dependent on the target. Are you writing a 32-bit exploit or a 64-bit exploit? Your current question appears to be a 32-bit exploit, so I will make that assumption.
The more complex situation in 32-bit code is getting the address of a string (that will be stack based when run as an exploit without NUL bytes). You can use the JMP/CALL/POP method to achieve that. Alternatively You can also build the Hello World!
string on the stack directly. I will propose a version using JMP/CALL/POP as described in the article:
hello1.asm:
global _start
section .text
_start:
jmp call
pop:
pop ecx ; ECX = address of hello
xor eax, eax ; EAX = 0
mov al, 4 ; EAX = 4 (int 0x80 sys_write)
xor ebx, ebx
inc ebx ; EBX = 1 (1 = Standard output)
xor edx, edx
mov dl, hellolen ; EDX = length of hello string
int 0x80
; Terminate program
xor eax, eax
inc eax ; EAX = 1 (int 0x80 sys_exit)
xor ebx, ebx ; EBX = return value of 0
int 0x80
call:
call pop
hello: db "Hello World!", 10
hellolen equ $-hello
You can assemble and link this code to a 32-bit executable called hello1
using:
nasm -f elf32 hello1.asm -o hello1.o
ld -melf_i386 hello1.o -o hello1
The result of objdump -D hello1
is:
hello1: file format elf32-i386 Disassembly of section .text: 08048060 <_start>: 8048060: eb 15 jmp 8048077 <call> 08048062 <pop>: 8048062: 59 pop %ecx 8048063: 31 c0 xor %eax,%eax 8048065: b0 04 mov $0x4,%al 8048067: 31 db xor %ebx,%ebx 8048069: 43 inc %ebx 804806a: 31 d2 xor %edx,%edx 804806c: b2 0d mov $0xd,%dl 804806e: cd 80 int $0x80 8048070: 31 c0 xor %eax,%eax 8048072: 40 inc %eax 8048073: 31 db xor %ebx,%ebx 8048075: cd 80 int $0x80 08048077 <call>: 8048077: e8 e6 ff ff ff call 8048062 <pop> 0804807c <hello>: 804807c: 48 dec %eax 804807d: 65 6c gs insb (%dx),%es:(%edi) 804807f: 6c insb (%dx),%es:(%edi) 8048080: 6f outsl %ds:(%esi),(%dx) 8048081: 20 57 6f and %dl,0x6f(%edi) 8048084: 72 6c jb 80480f2 <hello+0x76> 8048086: 64 21 0a and %ecx,%fs:(%edx)
You should note that there are no NUL bytes with this code. If you run ./hello1
as a standalone program it should output:
Hello World!
You can now convert this to a shellcode string with:
objcopy -Obinary hello1 shellcode.bin
hexdump -v -e '"\\""x" 1/1 "%02x" ""' shellcode.bin
The OBJCOPY command converts the executable to raw binary and the second outputs a string that can be used for the purposes of an exploit. The output should be:
\xeb\x15\x59\x31\xc0\xb0\x04\x31\xdb\x43\x31\xd2\xb2\x0d\xcd\x80\x31\xc0\x40\x31\xdb\xcd\x80\xe8\xe6\xff\xff\xff\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21\x0a
If you are looking for the equivalent code for 64-bit exploits you can find such an example in this Stackoverflow answer.
Upvotes: 7