Date: Fri, 30 May 2025 14:57:07 +0100
On Friday, May 30, 2025, Andre Kostur wrote:
I doubt it. The Standard doesn’t mandate a “vtable pointer” either.
> Neither does it talk about any of the other ABI things (other than linkage,
> and even then doesn’t say much about that either). This would seem to be
> entirely a discussion for the compiler vendors.
>
There wouldn't have to be any mention of vtables -- only a stipulation that
a standard-compliant compiler shall have a feature that it can emit code as
follows:
int IExaminer_Microsoft::GetStatus(void)
{
// Adjust the vtable pointer for Microsoft:
char unsigned const *const pobj = static_cast<char
unsigned*>(static_cast<void*>(p));
typedef int (*FuncPtr)(IExaminer*);
FuncPtr *const vtable = static_cast<FuncPtr*>(
static_cast<void*>( pobj + 4 ) );
return vtable[3]( this->p ); // GetStatus is the 4th
entry in the vtable
}
In fact I bet you within a week or so I could write a program that would do
this purely from reverse-engineering Microsoft machine code. I would write
a function as follows and feed it into the Microsoft compiler:
int Func(IExaminer *const p)
{
return p->GetStatus();
}
then compile it and disassemble it to a handful of instructions something
like:
mov rax, rcx ; Copy object pointer to rax
add rax, 4 ; Move to the vtable pointer (offset 4)
mov rax, [rax] ; Dereference to get vtable pointer
add rax, 24 ; Move to 4th virtual function (3 * 8 bytes)
mov rax, [rax] ; Dereference to get function pointer
jmp rax ; Jump to function
It would be easy to turn the the above 6 instructions into C code, similar
to how I figured out how to devirtualise member function pointers in the
following unfinished unpublished paper, see the section on the
implementation for Microsoft:
http://www.virjacode.com/devirtualize.html
It wouldn't be much work at all to code this -- an AI could figure out most
of it.
I doubt it. The Standard doesn’t mandate a “vtable pointer” either.
> Neither does it talk about any of the other ABI things (other than linkage,
> and even then doesn’t say much about that either). This would seem to be
> entirely a discussion for the compiler vendors.
>
There wouldn't have to be any mention of vtables -- only a stipulation that
a standard-compliant compiler shall have a feature that it can emit code as
follows:
int IExaminer_Microsoft::GetStatus(void)
{
// Adjust the vtable pointer for Microsoft:
char unsigned const *const pobj = static_cast<char
unsigned*>(static_cast<void*>(p));
typedef int (*FuncPtr)(IExaminer*);
FuncPtr *const vtable = static_cast<FuncPtr*>(
static_cast<void*>( pobj + 4 ) );
return vtable[3]( this->p ); // GetStatus is the 4th
entry in the vtable
}
In fact I bet you within a week or so I could write a program that would do
this purely from reverse-engineering Microsoft machine code. I would write
a function as follows and feed it into the Microsoft compiler:
int Func(IExaminer *const p)
{
return p->GetStatus();
}
then compile it and disassemble it to a handful of instructions something
like:
mov rax, rcx ; Copy object pointer to rax
add rax, 4 ; Move to the vtable pointer (offset 4)
mov rax, [rax] ; Dereference to get vtable pointer
add rax, 24 ; Move to 4th virtual function (3 * 8 bytes)
mov rax, [rax] ; Dereference to get function pointer
jmp rax ; Jump to function
It would be easy to turn the the above 6 instructions into C code, similar
to how I figured out how to devirtualise member function pointers in the
following unfinished unpublished paper, see the section on the
implementation for Microsoft:
http://www.virjacode.com/devirtualize.html
It wouldn't be much work at all to code this -- an AI could figure out most
of it.
Received on 2025-05-30 13:57:13