Techniques-> (64-bit only) RIP Relative Addressing
Note: This technique is only for 64-bit variant
So, so far we know that a string can not be directly hardcooded in the assembly (eg: using mov rsi, hello_world)
This would hardcode the memory address of the string in shellcode and when we paste that in C, since addresses change, string won't be at the same location and we'd get a segmentation fault.
So far we have learnt 2 techniques to counter this. Here is a 64-bit variant for the same.
We want to include the string onto a register using RIP + offset. For example, If I know my string is 13 instructions down below, I can simply so "lea rsi,[rip+0x13]"
let's take that one step further. In assembly an instruction called "rel" exists which does relative RIP addresing. Here is an example:
global _start
section .text
_start:
mov rax,1
mov rdi,1
lea rsi, [rel message]
mov rdx,13
syscall
;exiting
mov rax,60
mov rdi,0
syscall
message: db 'Hello World!',0xa
In objdump this looks something like this:

Wonderful. But in shellcode we can't have 0s. Let's remove that.

Well, we can see in objdump that majorly all 0s are now removed. But what to do with our hero line? The relative addressing. We can see that rip + 0x15 is nothing but rip+0x00000015
Trick: Since there are 0s within the relative addressing, we can move our message line above the lea line and change that from 0s to "f"s!!

Voila! Since the negative offset is converted to F in hex, we removed the 0s.
global _start
section .text
message: db 'Hello World!',0xa
_start:
xor rax,rax
add rax,1
mov rdi,rax
lea rsi, [rel message]
mov rdx,rdi
add rdx,12
syscall
;exiting
xor rax,rax
add rax,60
xor rdi,rdi
syscall
Here is the extracted shellcode:
objdump -d ./hello.o |grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
"\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21\x0a\x48\x31\xc0\x48\x83\xc0\x01\x48\x89\xc7\x48\x8d\x35\xe2\xff\xff\x48\x89\xfa\x48\x83\xc2\x0c\x0f\x05\x48\x31\xc0\x48\x83\xc0\x3c\x48\x31\xff\x0f\x05"
Last updated
Was this helpful?