I'm trying to create a dispatch table which changes the location of some instruction in another address which is allocated by
One of the problems that I encountered was almost all of
Calls and all kind of
relative and as long as I load the assemblies in new location, then these instructions won't work.
As I know I should convert these instructions to
far jump or
far call one of the solutions that I saw during my googling was using
ret like :
push 0xdeadbeef ret
or someone suggests using registers for absolute addressing like :
mov %eax,0xdeadbeef jmp %eax
These solutions won't work in my case because as long as I'm in a function routine, changing the stack state or in the second case changing a register like
%eax causes failure.
Someone in this question wrote :
- call far (with opcode 9A) jumps to an absolute segment and offset. ie, it's like setting CS and ?IP at once.
So it seems I should use opcode with
far calls, but this just works for the calls and I have no idea about converting all kinds of Jumps with this method!
I regularly use
objdump to disassemble a binary, then use
clang as the assembler by using the following command :
clang -c MyAsm.asm -m32
But when I assemble with the above command then the result is relative.
For example when
MyAsm.asm is :
The result of
objdump is :
MyAsm.o: file format Mach-O 32-bit i386 Disassembly of section __TEXT,__text: __text: 0: e8 ed 2a 40 00 calll 4205293 <__text+0x402AF2>
These results are relative.
So my questions are :
clangor any other tools (which of course, work for both 80x86 and Amd64 structures)?
If you can spare a register, I advise you to use
movabs $addr,%rax jmp *%rax
or, if you can ensure that the address is within the first 2 GB of address space,
mov $addr,%eax jmp *%eax
I strongly advise you against using
push $addr ret
as this trashes the return prediction, making the next few function returns slower than necessary. Far jumps and calls (
lcall) are a red herring. While they could technically be used, they won't help you achieve your goal and are actually meant for a different purpose (changing
cs) and are implemented as slow, micro-coded instructions on modern processors.
If you cannot spare a register, you can use this sort of trick instead:
jmp *0f(%rip) 0: .quad addr
This should just work and in addition doesn't require you to use an extra register. It is slower than using a register though.
Note that conditional jumps strictly require the jump target to be immediate. If you want to do a conditional jump to an absolute address, use an idiom like this:
# for jz addr jnz 1f jmp *0f(%rip) 0: .quad addr 1:
User contributions licensed under CC BY-SA 3.0