Создание VxD на Visual C++ без ассемблерных модулей

       

Пример построения функции-обертки


Поскольку сервисная функция VMM _SelectorMapFlat не имеет стандартной обертки, возможная функция-обертка для нее могла бы выглядеть следующим образом:

#pragma warning (disable: 4035) // Блокировка предупреждения о невозврате

_declspec (naked) void *SelectorMapFlat (DWORD VM, DWORD Sel, DWORD Rsv = 0) {

  VMMJmp (_SelectorMapFlat)  // Передача управления VMM

  (void)(VM, Sel, Rsv);                   // Имитация использования параметров

}

#pragma warning (default: 4035)  // Восстановление предупреждений о невозврате

Квалификатор _declspec (naked)

подавляет генерацию пролога/эпилога, так что от функции остается лишь конструкция VMMJmp. При вызове этой функции-обертки параметры VM, Sel

и Rsv

помещаются в стек, затем туда же помещается адрес возврата, управление передается в функцию-обертку, при этом VMMJmp

передает управление сервисной функции VMM _SelectorMapFlat, не запоминая нового адреса возврата в стеке. VMM использует значения параметров из стека, затем выполняет возврат по адресу, находящемуся на верхушке стека, при этом управление сразу возвращается в точку за вызовом функции-обертки, где находится код, удаляющий из стека параметры и использующий значение, возвращенное VMM в EAX.

Такая схема типична для построения функций-оберток, так как в полной мере использует особенности создания стекового кадра в языках C, а также возможности компилятора Visual C++ по оформлению функций. Без использования VMMJmp пришлось бы делать возврат дважды, а без использования квалификатора naked — дважды помещать в стек список параметров.



Содержание раздела