Search code examples
assemblyx86x86-64reverse-engineeringvirtual-functions

what does this x86_64 asm code do?


This is from 64-bit Linux shared object:

mov     rax, [rbp+var_1C+4]
mov     rax, [rax]
add     rax, 8
mov     rax, [rax]
mov     rdx, [rbp+var_1C+4]
mov     rdi, rdx
call    rax

Solution

  • Looks like a virtual function call.

    Looks like un-optimized compiler output, given the usage of rbp as a frame pointer, and using add rax,8 instead of an addressing mode like mov rax, [rax+8]. And the reload of the local for no reason when it could have kept the pointer live in a register after loading it earlier.

    It looks like it's preparing a this pointer as an arg for the virtual function, as well as calling a virtual function through the vtable. How do objects work in x86 at the assembly level?

    Anyway this code is just an inefficient way of writing

    mov    rdi, [rbp+var_1C+4]    # load a pointer to a local from the stack
    mov    rax, [rdi]             # load the vtable pointer from the start of the object
    call   [rax+8]                # index into the vtable
    

    Or maybe setting rdx was intended, rather than just inefficient un-optimized code. In the x86-64 System V ABI, rdx holds the 3rd integer / pointer arg to function calls. rdi holds the first (including this as a hidden first arg). If rsi was set earlier, then perhaps rdx is being passed intentionally, so it's a call like foo->virtual_function(something, foo), where class something *foo is a local variable or function arg.

    Otherwise it's just foo->virtual_function().


    Or it's something completely different that just happens to look like what a compiler would emit for a virtual function call. You can't know without more context.