Vladislav
Vladislav

Reputation: 394

How to interpret Jump far FF assembly instruction?

I have 3 classes:

class Base { virtual foo() {...} }
class A : Base { virtual foo() override {...} }
class B : A { virtual bar() {...} /* introduce bar, but no foo override */ }

and I want to understand how this virtual function calls works under the hood.

If I call A a; a.foo() - the compiler generates Call instruction FF 10 which leads to near-jump instruction E9 01 02 03 04. The last 4 bytes - relative offset from vtable-record to real function. It is pretty obvious and clear. But if I call B b; b.foo() - the Call instruction leads to another kind of Jump FF 25. Visual Studio disassemblers displays it like this:

00007FFA2CAB1C85 FF 25 AD 76 21 01    jmp         qword ptr [A::foo (07FFA2DCC9338h)]

I expected to get jump to 07FFA2DCC9338h address, but instead, it jumps to 07FFA4AD05885h(I suppose VS is lying with predicted address):

00007FFA4AD05885 E9 96 5D 01 00       jmp         A::foo (07FFA4AD1B620h)

And this jump instuction (E9) forwards me to the real function.

But I do not understand how FF 25 works. Unfortunately, my assembly knowledge is very poor, I read some documentation, it says about some "gates", and I do not understand it.

Is it possible to predict the jump location for far-jump(FF) by having current instruction address(RIP) and jump-arguments?

Upvotes: 1

Views: 468

Answers (1)

Vladislav
Vladislav

Reputation: 394

Thanks @Jester, seems you are right.

E9 - jumps to specific relative code instruction. FF 25 - calculates some specific relative location, read the memory from there, and use this memory as a pointer to next code instruction.

I just detected that

E9 ...      jmp     A::foo (07FFA4AD1B620h)
FF 25 ...   jmp     qword ptr [A::foo (07FFA2DCC9338h)]

qword ptr[...] says that I should derefer the value!

Upvotes: 2

Related Questions