Смотрел, смотрел и решил поделиться ...
Пользуйтесь
#ifndef _SSS_TYPES
#define _SSS_TYPES
#define INVALID_ADDRESS ((PVOID) -1)
// =================================================================
// (1) INTEL X86 Регистры, селекторы
// =================================================================
// РОНЫ
typedef DWORD X86_REGISTER, *PX86_REGISTER, **PPX86_REGISTER;
// Селекторы
typedef struct _X86_SELECTOR
{union
{struct
{
WORD wValue; // Упакованный вид
WORD wReserved; // Резерв
};
struct
{
unsigned RPL : 2; // запрашиваемый уровень привелегий RPL
unsigned TI : 1; // Индикатор таблицы 0=GDT, 1=LDT
unsigned Index : 13; // индекс в таблице дескрипторов xDT
unsigned Reserved : 16; //Резерв для WIN64
};
};
} X86_SELECTOR, *PX86_SELECTOR, **PPX86_SELECTOR;
#define X86_SELECTOR_ sizeof (X86_SELECTOR)
// Элемент таблицы дескрипторов
typedef struct _X86_DESCRIPTOR
{union
{struct
{
DWORD dValueLow; // Упакованный вид
DWORD dValueHigh;
};
struct
{
unsigned Limit1 : 16; // предел сегмента bits 15..00
unsigned Base1 : 16; // база сегмента bits 15..00
unsigned Base2 : 8; // база сегмента bits 23..16
unsigned Type : 4; // тип сегмента (очень обширно тип, подчиняемость, расширяемость, разрешения чтения/записи)
unsigned S : 1; // ещё тип (0=system, 1=code/data)
unsigned DPL : 2; // уровень привилегий дескриптора DPL
unsigned P : 1; // флаг присутствия в памяти
unsigned Limit2 : 4; // предел сегмента bits 19..16
unsigned AVL : 1; // флаг - в распоряжении програмиста (available to programmer)
unsigned Reserved : 1;
unsigned DB : 1; // B: если сегмент данных определяет макс. размер 0= 64 кБ 1= 4ГБ
// B: если сегмент стека определяет разрядность ESP и разрядность данных в операциях POP и PUSH 0= 16 bit 1= 32 bit
// D: если кодовый сегмент определяет разрядность адресов и операндов 0= 16 bit 1= 32 bit
unsigned G : 1; // гранулярность (1=4KB)
unsigned Base3 : 8; // база сегмента bits 31..24
};
};
} X86_DESCRIPTOR, *PX86_DESCRIPTOR, **PPX86_DESCRIPTOR;
#define X86_DESCRIPTOR_ sizeof (X86_DESCRIPTOR)
// Дескриптор шлюза (вентиль)
typedef struct _X86_GATE
{union
{struct
{
DWORD dValueLow; // Упакованный вид
DWORD dValueHigh;
};
struct
{
unsigned Offset1 : 16; // смещение точки входа в целевом сегменте bits 15..00
unsigned Selector : 16; // селектор целевого сегмента
unsigned Parameters : 5; // только в шлюзах вызовов
// для 286 количество слов из старого стека
// для 386 количество двойных слов из старого стека
unsigned Reserved : 3;
unsigned Type : 4; // тип шлюза (gate type and size)
unsigned S : 1; // всегда 0
unsigned DPL : 2; // уровень привелегий дескриптора
unsigned P : 1; // действительность сегмента
unsigned Offset2 : 16; // смещение точки входа в целевом сегменте bits 31..16
};
};
} X86_GATE, *PX86_GATE, **PPX86_GATE;
#define X86_GATE_ sizeof (X86_GATE)
// Структура для чтений SGDT, SIDT (48 bit)
typedef struct _X86_TABLE
{
WORD wReserved; // для выравнивания на 32-bit
WORD wLimit; // размер таблицы
union{
PX86_DESCRIPTOR pDescriptors; // используется для SGDT инструкции
PX86_GATE pGates; // используется для SIDT инструкции
};
} X86_TABLE, *PX86_TABLE, **PPX86_TABLE;
#define X86_TABLE_ sizeof (X86_TABLE)
// Индексы сегментов (для внутреннего использования)
#define X86_SEGMENT_OTHER 0
#define X86_SEGMENT_CS 1
#define X86_SEGMENT_DS 2
#define X86_SEGMENT_ES 3
#define X86_SEGMENT_FS 4
#define X86_SEGMENT_GS 5
#define X86_SEGMENT_SS 6
#define X86_SEGMENT_TSS 7
// Маски доступа (для внутреннего использования)
#define X86_SELECTOR_RPL 0x0003
#define X86_SELECTOR_TI 0x0004
#define X86_SELECTOR_INDEX 0xFFF8
#define X86_SELECTOR_SHIFT 3
#define X86_SELECTOR_LIMIT (X86_SELECTOR_INDEX >> \
X86_SELECTOR_SHIFT)
// Типы сегментов (поле Type в дескрипторах)
#define X86_DESCRIPTOR_NO_SYSTEM 0x0100000000000 // Системный сегмент
// Если X86_DESCRIPTOR_NO_SYSTEM = 0 то тип сегмента
#define X86_DESCRIPTOR_SYS_TSS16A 0x1 // Доступный сегмент задачи TSS286
#define X86_DESCRIPTOR_SYS_LDT 0x2 // Таблица локальных дескрипторов
#define X86_DESCRIPTOR_SYS_TSS16B 0x3 // Недоступный сегмент задачи TSS286 (Busy)
#define X86_DESCRIPTOR_SYS_CALL16 0x4 // шлюз вызова (Call gate) 286
#define X86_DESCRIPTOR_SYS_TASK 0x5 // шлюз задачи (Task gate)286
#define X86_DESCRIPTOR_SYS_INT16 0x6 // шлюз прерывания (Interrupt gate) 286
#define X86_DESCRIPTOR_SYS_TRAP16 0x7 // шлюз ловушки (Trap gate) 286
#define X86_DESCRIPTOR_SYS_TSS32A 0x9 // Доступный сегмент задачи TSS386+
#define X86_DESCRIPTOR_SYS_TSS32B 0xB // Недоступный сегмент задачи TSS286 (Busy)
#define X86_DESCRIPTOR_SYS_CALL32 0xC // шлюз вызова (Call gate)386+
#define X86_DESCRIPTOR_SYS_INT32 0xE // шлюз прерывания (Interrupt gate)386+
#define X86_DESCRIPTOR_SYS_TRAP32 0xF // шлюз ловушки (Trap gate) 386+
// Если X86_DESCRIPTOR_NO_SYSTEM = 1 то тип сегмента
#define X86_DESCRIPTOR_APP_CODE 0x8 // 1 - кодовый 0 - данных
#define X86_DESCRIPTOR_APP_ACCESSED 0x1 // Было обращение
#define X86_DESCRIPTOR_APP_READ_WRITE 0x2 // для данных - запись разрешена
#define X86_DESCRIPTOR_APP_EXECUTE_READ 0x2 // для кода - разрешено чтение
#define X86_DESCRIPTOR_APP_EXPAND_DOWN 0x4 // для данных: 0 - расширение вверх 1 - расширение вниз (стек)
#define X86_DESCRIPTOR_APP_CONFORMING 0x4 // для кода подчиненность разрешения выполнения: 1 {CPL <= DPL}; 0 {CPL = DPL}
// -----------------------------------------------------------------
// =================================================================
// (2) INTEL X86 Страницы
// =================================================================
//
// Структурное представление регистра CR3
//(базовый регистр каталога страниц) PDBR (page-directory base register)
typedef struct _X86_PDBR
{union
{struct
{
DWORD dValue; // Упакованный вид
};
struct
{
unsigned Reserved1 : 3;
unsigned PWT : 1; // политика кэширования (1 - write-through)
unsigned PCD : 1; // установка запрещает кэш страницы (таблицы)
unsigned Reserved2 : 7;
unsigned PFN : 20; // Базовый адрес таблицы страниц (PhysAddr = PFN x PAGESIZE)
// пример: PFN = 2, PS = 0, PhysAddr = 2 * 0x1000 = 0x2000
// (номер страничного блока)
};
};
} X86_PDBR, *PX86_PDBR, **PPX86_PDBR;
#define X86_PDBR_ sizeof (X86_PDBR)
// строка каталога страниц 4 МБ
typedef struct _X86_PDE_4M
{union
{struct
{
DWORD dValue; // Упакованный вид
};
struct
{
unsigned P : 1; // Бит присутствия Гук стр 151
unsigned RW : 1; // Read/Write Гук стр 152
unsigned US : 1; // User/Supervisor Гук стр 152
unsigned PWT : 1; // политика кэширования (1 - write-through)
unsigned PCD : 1; // установка запрещает кэш страницы (таблицы)
unsigned A : 1; // (Accessed) к адресу, в трансляции которого учавствовала страница было обращение (r/w)
unsigned D : 1; // (Dirty) по адресу, в трансляции которого учавствовала страница была запись (write)
// (грязная), т.е. в случае замещения необходима выгрузка
// для каталога всегда D = 0
unsigned PS : 1; // размер страниц 1 - 4 MB
unsigned G : 1; // Глобальность (только P6)
unsigned Available : 3; // Доступны программисту
unsigned Reserved : 10;
unsigned PFN : 10; // Базовый адрес таблицы страниц (PhysAddr = PFN x PAGESIZE)
// (номер страничного блока)
};
};
} X86_PDE_4M, *PX86_PDE_4M, **PPX86_PDE_4M;
#define X86_PDE_4M_ sizeof (X86_PDE_4M)
// строка каталога страниц 4 кБ
typedef struct _X86_PDE_4K
{union
{struct
{
DWORD dValue; // Упакованный вид
};
struct
{
unsigned P : 1; // Бит присутствия Гук стр 151
unsigned RW : 1; // Read/Write Гук стр 152
unsigned US : 1; // User/Supervisor Гук стр 152
unsigned PWT : 1; // политика кэширования (1 - write-through)
unsigned PCD : 1; // установка запрещает кэш страницы (таблицы)
unsigned A : 1; // (Accessed) к адресу, в трансляции которого учавствовала страница было обращение (r/w)
unsigned Reserved : 1; // (Dirty) по адресу, в трансляции которого учавствовала страница была запись (write)
// (грязная), т.е. в случае замещения необходима выгрузка
// для каталога всегда D = 0
unsigned PS : 1; // размер страниц 0 - 4 кБ
unsigned G : 1; // Глобальность (только P6)
unsigned Available : 3; // Доступны программисту
unsigned PFN : 20; // Базовый адрес таблицы страниц (PhysAddr = PFN x PAGESIZE)
// (номер страничного блока)
};
};
} X86_PDE_4K, *PX86_PDE_4K, **PPX86_PDE_4K;
#define X86_PDE_4K_ sizeof (X86_PDE_4K)
// строка таблицы страниц 4 кБ
typedef struct _X86_PTE_4K
{union
{struct
{
DWORD dValue; // Упакованный вид
};
struct
{
unsigned P : 1; // Бит присутствия Гук стр 151
unsigned RW : 1; // Read/Write Гук стр 152
unsigned US : 1; // User/Supervisor Гук стр 152
unsigned PWT : 1; // политика кэширования (1 - write-through)
unsigned PCD : 1; // установка запрещает кэш страницы (таблицы)
unsigned A : 1; // (Accessed) к адресу, в трансляции которого учавствовала страница было обращение (r/w)
unsigned D : 1; // (Dirty) по адресу, в трансляции которого учавствовала страница была запись (write)
// (грязная), т.е. в случае замещения необходима выгрузка
// для каталога всегда D = 0
unsigned Reserved : 1;
unsigned G : 1; // Глобальность (только P6)
unsigned Available : 3; // Доступны программисту
unsigned PFN : 20; // Базовый адрес таблицы страниц (PhysAddr = PFN x PAGESIZE)
// (номер страничного блока)
};
};
} X86_PTE_4K, *PX86_PTE_4K, **PPX86_PTE_4K;
#define X86_PTE_4K_ sizeof (X86_PTE_4K)
// Запись страницы отсутствующей в памяти
typedef struct _X86_PNPE
{union
{struct
{
DWORD dValue; // Упакованный вид
};
struct
{
unsigned P : 1; // (0 = not present) Бит присутствия Гук стр 151
unsigned Reserved1 : 9;
unsigned PageFile : 1; // Страница выгружена в pagefile (undoc)
unsigned Reserved2 : 21;
};
};
} X86_PNPE, *PX86_PNPE, **PPX86_PNPE;
#define X86_PNPE_ sizeof (X86_PNPE)
// Общая структура-объединение строки страницы
typedef struct _X86_PE
{union
{
DWORD dValue; // Упакованный вид
X86_PDBR pdbr; // базовый регистр каталога страниц
X86_PDE_4M pde4M; // строка каталога страниц 4 МБ
X86_PDE_4K pde4K; // строка каталога страниц 4 кБ
X86_PTE_4K pte4K; // строка таблицы страниц 4 кБ
X86_PNPE pnpe; // строка страницы отсутствующей в памяти
};
} X86_PE, *PX86_PE, **PPX86_PE;
#define X86_PE_ sizeof (X86_PE)
// =================================================================
// (3) INTEL X86 Представление линейных адресов
// =================================================================
// Линейный адрес (страница 4 МБ)
typedef struct _X86_LINEAR_4M
{union
{struct
{
PVOID pAddress; // Упакованный адрес
};
struct
{
unsigned Offset : 22; // смещение в странице
unsigned PDI : 10; // индекс в каталоге страниц
};
};
} X86_LINEAR_4M, *PX86_LINEAR_4M, **PPX86_LINEAR_4M;
#define X86_LINEAR_4M_ sizeof (X86_LINEAR_4M)
// Линейный адрес (страница 4 кБ)
typedef struct _X86_LINEAR_4K
{union
{struct
{
PVOID pAddress; // Упакованный адрес
};
struct
{
unsigned Offset : 12; // смещение в странице
unsigned PTI : 10; // индекс в таблице страниц
unsigned PDI : 10; // индекс в каталоге страниц
};
};
} X86_LINEAR_4K, *PX86_LINEAR_4K, **PPX86_LINEAR_4K;
#define X86_LINEAR_4K_ sizeof (X86_LINEAR_4K)
// Общая структура линейного адреса
typedef struct _X86_LINEAR
{union
{
PVOID pAddress; // Упакованный адрес
X86_LINEAR_4M linear4M; // Линейный адрес (страница 4 МБ)
X86_LINEAR_4K linear4K; // Линейный адрес (страница 4 кБ)
};
} X86_LINEAR, *PX86_LINEAR, **PPX86_LINEAR;
#define X86_LINEAR_ sizeof (X86_LINEAR)
// =================================================================
// (4) INTEL X86 Макросы и константы
// =================================================================
#ifndef SKMD_DIRECTIVE // определены в ntddk.h
// Макросы получения битовых полей из линейного адреса
#define PAGE_SHIFT 12
#define PTI_SHIFT 12
#define PDI_SHIFT 22
#endif
#define X86_PAGE_MASK (0 - (1 << PAGE_SHIFT)) // 0xFFFFF000
#define X86_PAGE(_p) (((DWORD) (_p) & X86_PAGE_MASK) >> PAGE_SHIFT)
// Page directory index из линейного (виртуального) адреса
#define X86_PDI_MASK (0 - (1 << PDI_SHIFT)) //0xFFC00000
#define X86_PDI(_p) (((DWORD) (_p) & X86_PDI_MASK) >> PDI_SHIFT)
// Page table index из линейного (виртуального) адреса
#define X86_PTI_MASK ((0 - (1 << PTI_SHIFT)) & ~X86_PDI_MASK) //0x003FF0000
#define X86_PTI(_p) (((DWORD) (_p) & X86_PTI_MASK) >> PTI_SHIFT)
// Смещения из линейного адреса
#define X86_OFFSET(_p,_m) ((DWORD_PTR) (_p) & ~(_m))
#define X86_OFFSET_4M(_p) X86_OFFSET (_p, X86_PDI_MASK)
#define X86_OFFSET_4K(_p) X86_OFFSET (_p, X86_PDI_MASK|X86_PTI_MASK)
//Размеры страниц
#define X86_PAGE_4M (1 << PDI_SHIFT)
#define X86_PAGE_4K (1 << PTI_SHIFT)
// Число страниц необходимых для описания пространства в 4 ГБ
#define X86_PAGES_4M (1 << (32 - PDI_SHIFT))
#define X86_PAGES_4K (1 << (32 - PTI_SHIFT))
// Начало масива PTE для Win (NT4) 2000
#define X86_PAGES 0xC0000000
// Приведение начала масива PTE для Win (NT4) 2000
// к указателю (массиву !) на общую структуру
// строки страницы X86_PE
#define X86_PTE_ARRAY ((PX86_PE) X86_PAGES)
#define X86_PDE_ARRAY (X86_PTE_ARRAY + (X86_PAGES >> PTI_SHIFT))
// =================================================================
// (5) Kernel Mode Driver. Мютексы
// =================================================================
#define MUTEX_INITIALIZE(_mutex) \
KeInitializeMutex \
(&(_mutex), 0)
#define MUTEX_WAIT(_mutex) \
KeWaitForMutexObject \
(&(_mutex), Executive, KernelMode, FALSE, NULL)
#define MUTEX_RELEASE(_mutex) \
KeReleaseMutex \
(&(_mutex), FALSE)
// =================================================================
// (6) Kernel Mode Driver. Константы для генерирования
// кодов IOCTL (распознавание номеров функций)
// =================================================================
// Формат бит управляющего кода (32 bit)
// 00 - 01 Метод
// 02 - 13 Функция
// 14 - 15 Права доступа для работы IOCTL
// 0 - ANY 1 - R 2 - W 3 - R/W
// 16 - 31 Тип устройства
// идентификатор типа устройства (16 bit).
// 0x0000 - 0x7FFF - зарезервировано Microsoft
#define FILE_DEVICE_SKMD 0x8000
// идентификатор функции устройства (12 bit).
// 0x0000 - 0x07FF - зарезервировано Microsoft
#define SKMD_IO_BASE 0x0800
// Макрос упрощения генерации кода IOCTL
#define SKMD_IO(_code,_read,_write) \
CTL_CODE ((FILE_DEVICE_SKMD), \
((SKMD_IO_BASE) + (_code)), \
(METHOD_BUFFERED), \
(((_read) ? (FILE_READ_ACCESS) : 0) | \
((_write) ? (FILE_WRITE_ACCESS) : 0)))
// =================================================================
// (6) Kernel Mode Driver. Ну вот и сами номера
// функций
// =================================================================
#ifndef _RC_PASS_
// № read write
// Версия драйвера
// [null] -> (SKMD) -> [SKMD_VERSION_INFO]
#define SKMD_IO_VERSION_INFO SKMD_IO ( 0, TRUE, FALSE)
// Дескриптор сегмента
// [селектор (dword)] -> (SKMD) -> [SKMD_SEGMENT]
#define SKMD_IO_SEGMENT SKMD_IO ( 2, TRUE, FALSE)
// Дескриптор шлюза
// [селектор (dword)] -> (SKMD) -> [SKMD_INTERRUPT]
#define SKMD_IO_INTERRUPT SKMD_IO ( 3, TRUE, FALSE)
// Преобразование адреса
// [указатель(pointer)] -> (SKMD) -> [PHYSICAL_ADDRESS]
#define SKMD_IO_PHYSICAL SKMD_IO ( 4, TRUE, FALSE)
// Информация об регистрах
// [null] -> (SKMD) -> [SKMD_CPU_INFO]
#define SKMD_IO_CPU_INFO SKMD_IO ( 5, TRUE, FALSE)
// Возврат каталога страниц (4 кБ = 1024 элемента)
// для текущего процесса (не процесса драйвера!!??)
// [null] -> (SKMD) -> [SKMD_PDE_ARRAY]
#define SKMD_IO_PDE_ARRAY SKMD_IO ( 6, TRUE, FALSE)
// Возврат записи страницы линейного (виртуального ?!) драйвера
// [указатель(pointer)] -> (SKMD) -> [SKMD_PAGE_ENTRY]
#define SKMD_IO_PAGE_ENTRY SKMD_IO ( 7, TRUE, FALSE)
// Возврат блока памяти
// [SKMD_MEMORY_BLOCK] -> (SKMD) -> [SKMD_MEMORY_DATA]
#define SKMD_IO_MEMORY_DATA SKMD_IO ( 8, TRUE, FALSE)
// Возврат блока памяти
// [SKMD_MEMORY_BLOCK] -> (SKMD) -> [SKMD_MEMORY_DATA]
#define SKMD_IO_MEMORY_BLOCK SKMD_IO ( 9, TRUE, FALSE)
// Возврат блока информатии об объекте
// [HANDLE] -> (SKMD) -> [SKMD_HANDLE_INFO]
#define SKMD_IO_HANDLE_INFO SKMD_IO (10, TRUE, FALSE)
// Установить запись в PTE
// [SKMD_PTE_ENTRY_SET] -> (SKMD) -> [null]
#define SKMD_IO_SET_PTE_ENTRY SKMD_IO ( 97, TRUE, FALSE)
// PTE INDEX -> X86_PE
// [cardinal] -> (SKMD) -> [X86_PE]
#define SKMD_IO_PTE_ENTRY SKMD_IO ( 98, TRUE, FALSE)
#endif // _RC_PASS_