Это академический c вопрос. Я сделал макрос для вызова и получения указателя на виртуальную функцию через виртуальную таблицу. Но изменение адресной переменной vfun c приводит к повреждению памяти. Так получается, что эта область памяти защищена от эксплойтов?
Ее класс c реализация. Я использую G CC (MinGW) для 64-битных программ, компилятор добавляет указатель на vtable (массив) своего класса в первом скрытом поле объекта.
#define VTABLE_CALL(FUNC_TYPE, OBJECT, OFFSET, ...) \
((FUNC_TYPE)(*((size_t**)&(OBJECT))[(OFFSET)]))(__VA_ARGS__)
#define VTABLE_GET(OBJECT, OFFSET) \
((void*)((*(size_t**)&(OBJECT))[(OFFSET)]))
#define VTABLE_SET(OBJECT, OFFSET, NEW_FUNC_P) \
((*((size_t***)&(OBJECT))[(OFFSET)]) = (size_t*)(NEW_FUNC_P))
Итак, этот код дает SegFault
class A {
virtual void foo(void) { printf("Test\n"); }
};
int main()
{
typedef void (*VMethod) (void*); // void* for "this"
A a; // our object with first hidden vTablePtr;
VMethod vm;
VTABLE_CALL(VMethod, a, 0, &a); // call A::foo
vm = (VMethod) VTABLE_GET(a, 0);
vm(&a); // call again A::foo
/* replace the pointer to ourselves */
VTABLE_SET(a, 0, vm); // segmentation fault
/* foot shot completed */
return 0;
}