Фундаментальные основы хакерства




Идентификация виртуальных функций - часть 16


Другое различие: статические объекты размешаются в стеке (сегменте данных), а динамические – в куче. Таблица виртуальных функций упорно создается компиляторами в обоих случаях, а при вызове каждый функции (включая не виртуальные) подготавливается указатель this (как правило, помещаемый в один из регистров общего назначения – подробнее см. "Идентификация аргументов функций"), содержащий адрес экземпляра объекта.

Таким образом, если мы встречаем функцию, вызываемую непосредственно по ее смещению, но в то же время присутствующую в виртуальной таблице класса – можно с уверенностью утверждать, что это – виртуальная функция статичного экземпляра объекта.

Рассмотрим следующий пример:

#include <stdio.h>

class Base{

 public:

virtual void demo(void)

{

printf("BASE DEMO\n");

};

virtual void demo_2(void)

{

printf("BASE DEMO 2\n");

};

void demo_3(void)

{

printf("Non virtual BASE DEMO 3\n");

};

};

class Derived: public Base{

 public:

virtual void demo(void)

{

printf("DERIVED DEMO\n");

};

virtual void demo_2(void)

{

printf("DERIVED DEMO 2\n");

};

void demo_3(void)

{

printf("Non virtual DERIVED DEMO 3\n");

};

};

main()

{

Base p;

p.demo();

p.demo_2();

p.demo_3();

Derived d;

d.demo();

d.demo_2();

d.demo_3();

}

Листинг 32 Демонстрация вызова статической виртуальной функции

Результат ее компиляции в общем случае должен выглядеть так:

main         proc near           ; CODE XREF: start+AFp

var_8        = byte ptr -8       ; derived

var_4        = byte ptr -4       ; base

; часто, (но не всегда!) экземпляры объектов в стеке расположены снизу вверх,

; т.е. в обратном порядке их объявления в программе

push   ebp

mov    ebp, esp

sub    esp, 8

lea    ecx, [ebp+var_4] ; base

call   GetBASE_VTBL               ; p[0]=*BASE_VTBL

; обратите внимание – экземпляр объекта размещается в стеке,




Содержание  Назад  Вперед