Создание VxD на Visual C++ без ассемблерных модулей - Некоторые функции-обертки, определенные в VXDWRAPS
ОГЛАВЛЕНИЕ
Некоторые функции-обертки, определенные в VXDWRAPS
Out_Debug_String - вывод отладочного сообщения void Out_Debug_String (char *String);
- String — указатель строки, выводимой в отладочный поток. Для перехода на новую строку используется символ '\n".
Системный отладочный поток можно просматривать отладчиками WDEB386, SoftICE, а также любым отладочным монитором.
_Sprintf - форматирование строки ULONG _Sprintf (char *Buffer, char *Format, ...);Функция аналогична стандартной функции sprintf языка C.
К сожалению, VMM не предоставляет функции, аналогичной vsprintf, поэтому для реализации функций целевого назначения, в основе которых лежит спецификация формата и список аргументов переменной длины (например, функций отладочного вывода или формирования строк специального вида), приходится использовать _Sprintf, копируя переменную часть списка аргументов (например, 10-20 двойных слов) из стекового кадра целевой функции.
Пример построения функции-обертки
Поскольку сервисная функция 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 — дважды помещать в стек список параметров.