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




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


push   esi          ; ESI =      *b

push   edi          ; ECX =      *c

mov    esi, ecx     ; ESI =      *c

call   Get_A_VTBL   ; c[0]=*A_VTBL

; помещаем в экземпляр объекта C указатель на виртуальную таблицу класса A

lea    edi, [esi+4] ; EDI =      *c[4]

mov    ecx, edi     ; ECX =      **_C_F

call   Get_B_VTBL   ; c[4]=*B_VTBL

; добавляем в экземпляр объекта C

указатель на виртуальную таблицу класса B

; т.е. теперь объект C содержит два указателя на две виртуальные таблицы

; базовых классов. Посмотрим далее, как компилятор справится с конфликтом

; имен…

mov    dword ptr [edi], offset C_VTBL_FORM_B ; c[4]=*_C_VTBL

; Ага! указатель на виртуальную таблицу класса B

замещается указателем

; на виртуальную таблицу класса C

(смотри комментарии в самой таблице)

mov    dword ptr [esi], offset    C_VTBL ; c[0]=C_VTBL

; Ага, еще раз – теперь указатель на виртуальную таблицу класса A замещается

; указателем на виртуальную таблицу класса C. Какой неоптимальный код, ведь это

; было можно сократить еще на стадии компиляции!

mov    eax, esi     ; EAX =      *c

pop    edi

pop    esi

retn  

GET_C_VTBLs  endp

Get_A_VTBL   proc near           ; CODE XREF: main+13p GET_C_VTBLs+4p

mov    eax, ecx

mov    dword ptr [eax], offset    A_VTBL

; помещаем в экземпляр объекта указатель на виртуальную таблицу класса B

retn  

Get_A_VTBL   endp

A_F          proc near           ; DATA XREF: .rdata:004050A8o

; виртуальная функиця f() класса A

push   offset aA_f  ; "A_F\n"

call   printf

pop    ecx

retn  

A_F          endp

Get_B_VTBL   proc near           ; CODE XREF: main+2Ep GET_C_VTBLs+Ep

mov    eax, ecx

mov    dword ptr [eax], offset    B_VTBL

; помещаем в экземпляр объекта указатель на виртуальную таблицу класса B

retn  

Get_B_VTBL   endp

B_F          proc near           ; DATA XREF: .rdata:004050ACo

; виртуальная функция f() класса B

push   offset aB_f  ; "B_F\n"




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