2

I have found topic related to linux x86_64 absolute addressing: Absolute addressing for runtime code replacement in x86_64 . It was told that absolute addressing is not supported for linux.

What about windows x64, are near absolute calls supported?

For windows x86 the address of the function can be grabbed from near absolute calls (0xFF 0x15) in this way:

unsigned char call_nearAbsolute[2] = {0xFF, 0x15};

if(memcmp(bytes, call_nearAbsolute, sizeof(call_nearAbsolute)) == 0) {
{        
    unsigned char offset[] = {
                *(bytes + 0x5),
                *(bytes + 0x4),
                *(bytes + 0x3),
                *(bytes + 0x2)
            };
        PDWORD_PTR absolute_addr = 
        (PDWORD_PTR)(((offset[0] & 0xFF) << 24) | 
        ((offset[1] & 0xFF) << 16) | 
            ((offset[2] & 0xFF) << 8) | 
        offset[3] & 0xFF);
}

If it is supported for x64, how to get procedure address correctly?

Community
  • 1
  • 1
ChatCloud
  • 1,152
  • 2
  • 8
  • 22
  • 2
    Not sure what this is about, ff 15 xx xx xx xx is an indirect call, `call qword ptr [offset]` where *offset* is a 32-bit signed offset from the instruction pointer. The 8 bytes at the addressed location contains the actual address of the function to call. – Hans Passant May 07 '12 at 12:54
  • are 8 bytes used for x64 as well? – ChatCloud May 07 '12 at 13:51
  • Erm, addresses are 8 bytes in 64-bit mode. – Hans Passant May 07 '12 at 13:55
  • So actual address of the function can be be fetched this way: function_addr = *(absolute_addr + ff15_instruction_addr) where absolute_addr is computed from xx xx xx xx as above. Does it look correct? – ChatCloud May 07 '12 at 14:15
  • 1
    The offset is *relative* from the instruction pointer. The address of the *next* instruction. So add 6. – Hans Passant May 07 '12 at 14:20
  • In 32-bit mode, `ff 15 xx xx xx xx` is `call dword ptr [disp32]`, where `xx xx xx xx` is an absolute address. In 64-bit mode, the same encoding means RIP-relative addressing. A 32-bit absolute addressing mode for the 64-bit function pointer would require a SIB, because RIP-relative took over the shorter of the two redundant encodings that 32-bit has for `[disp32]` with no registers. – Peter Cordes Apr 27 '18 at 04:52
  • Near absolute *direct* calls (with address in the instruction) are not supported in 32 or 64 bit mode. But near absolute *indirect* calls work the same in both modes. [Call an absolute pointer in x86 machine code](//stackoverflow.com/q/19552158) – Peter Cordes Apr 27 '18 at 04:53

1 Answers1

0

Use

MOV rax, address(your routine)'
CALL rax

There is no absolute call in that mode (yet) in 1 command (marketing or whatever stupid reason). The mentioned combination (replace it with other temporary register when necessary) allows you to get what you want. The predictors should identify such call at least by its placement in memory without penalty (the call command itself). I didn't test the first call penalty though, but it should be the same or lower (when aligned properly) than the call with indirect address.

Programmer
  • 29
  • 2
  • 32-bit x86 doesn't have absolute direct near `jmp` or `call` either. In fact, most architectures only support relative direct jumps, so you have to use indirect jumps for absolute addresses. [Why do x86 jump/call instructions use relative displacements instead of absolute destinations?](//stackoverflow.com/q/46184755). And see also [Call an absolute pointer in x86 machine code](//stackoverflow.com/q/19552158) (yes, `mov` immediate to register / `call rax` is good.) – Peter Cordes Apr 27 '18 at 04:49