Reputation: 41
Is there a way to access the value in the instruction pointer (RIP) without using a call
followed by a pop
in assembly language? Or is there a machine code opcode that can do it?
I have been googling with no clear results.
My problem is that I can't have any zeroes in the machine code, or else I get a SIGSEGV error. It's due to the way the server loads the code and executes it from a string of bytes. A near call has zeroes in the distance to the subroutine, so using call is not an option.
I'm on linux, 64-bit, and have nasm and yasm.
Upvotes: 3
Views: 6434
Reputation: 41805
In x86_64 the standard way is to use RIP-relative addressing instead of CALL
like in x86. Even then, call/pop is not a recommended way1
Normally you'll use lea rax, [rip]
to get RIP into RAX (which is actually encoded as lea rax, [rip + 0]
with four bytes for the immediate at the end). However since LEA
doesn't dereference the memory address, you can just add any constant displacements to the RIP and subtract it later
0: 48 8d 05 04 03 02 01 lea rax,[rip+0x1020304]
7: 48 2d 04 03 02 01 sub rax,0x1020304
You can choose any immediate values that don't have a zero or 0xFF byte. If you want the address of the instruction after lea
(which is 7 bytes long) you can fix up accordingly with sub rax, 0x01020304 - 7
GetCurrentAddress:
mov eax, [esp]
ret
...
call GetCurrentAddress
mov [currentInstruction], eax
in order to avoid mismatching between the call stack and the return stack buffer (RSB). But probably it isn't important in shellcode
Upvotes: 6