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/popto 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 justjmpforward over your string and uselea rdi, [rel msg]for a negativerel32. It's not actually smaller than call/pop, but fewer instructions.