Even though both the programs abide by relative addressing instructions required for shellcode execution, and both print the desired message on execution, the 2nd Sample fails when used as a shellcode. Can anyone explain the behavior? Strangely a 3rd sample identical to the 1st one fails as well.
Output: Sample 1 Hello World
Other Samples(2&3) print garbage values
Sample 1
global _start section .text _start: jmp widen pHworld: pop rsi xor rax,rax mov al,1 mov rdi,rax mov rdx,rdi add rdx,11 syscall ;Exit xor rax,rax mov rax,60 xor rdi,rdi syscall widen: call pHworld Hworld db "Hello World",0xa
Sample 2
global _start section .text _start: call pHworld Hworld db "Hello World",0xa pHworld: pop rsi xor rax,rax mov al,1 mov rdi,rax mov rdx,rdi add rdx,11 syscall ;Exit xor rax,rax mov rax,60 xor rdi,rdi syscall
Sample 3
global _start section .text _start: jmp label1 label1: call pHworld Hworld db "Hello World",0xa pHworld: pop rsi xor rax,rax mov al,1 mov rdi,rax mov rdx,rdi add rdx,11 syscall ;Exit xor rax,rax mov rax,60 xor rdi,rdi syscall
Unable to rest my curiosity , I tried yet another variation , and this fails (prints garbage values) even though I the objdump does not have any 0x00. Sample 4
global _start section .text pHworld: pop rsi xor rax,rax mov al,1 mov rdi,rax mov rdx,rdi add rdx,11 syscall xor rax,rax xor rdi,rdi mov al,60 syscall l1: call pHworld Hworld db "Hello World", 0xa _start: jmp l1 enter code here
Objdump of sample4
./hworld2.s: file format elf64-x86-64 Disassembly of section .text: 0000000000400080 : 400080: 5e pop rsi 400081: 48 31 c0 xor rax,rax 400084: b0 01 mov al,0x1 400086: 48 89 c7 mov rdi,rax 400089: 48 89 fa mov rdx,rdi 40008c: 48 83 c2 0b add rdx,0xb 400090: 0f 05 syscall 400092: 48 31 c0 xor rax,rax 400095: 48 31 ff xor rdi,rdi 400098: b0 3c mov al,0x3c 40009a: 0f 05 syscall 000000000040009c : 40009c: e8 df ff ff ff call 400080 00000000004000a1 : 4000a1: 48 rex.W 4000a2: 65 gs 4000a3: 6c ins BYTE PTR es:[rdi],dx 4000a4: 6c ins BYTE PTR es:[rdi],dx 4000a5: 6f outs dx,DWORD PTR ds:[rsi] 4000a6: 20 57 6f and BYTE PTR [rdi+0x6f],dl 4000a9: 72 6c jb 400117 4000ab: 64 fs 4000ac: 0a eb or ch,bl 00000000004000ad : 4000ad: eb ed jmp 40009c
call
/pop
to get a PC-relative address into a register. You can use RIP-relative LEA. e.g. Avoiding 0xFF bytes in shellcode using CALL to read RIP?, or justjmp
forward over your string and uselea rdi, [rel msg]
for a negativerel32
. It's not actually smaller than call/pop, but fewer instructions. – Lotuseater