Появилась задача: добавить новый сервис в SDT. Предполагался план: 1) получаю кол-во сервисов через MAX = KeServiceDescriptorTable->ServiceLimit 2) по адресу KeServiceDescriptorTable->ServiceTable[MAX + 1] записываю число MAX + 1 3) увеличиваю KeServiceDescriptorTable->ServiceLimit 4) по адресу KeServiceDescriptorTable->ServiceTable[MAX] записываю адрес своей функции Второй пункт сделан для того, что подправить странную вещь (наверное какое-то контрольное значение), что после последнего элемента в SDT следует кол-во элементов этой SDT. Если что-то не так с ним сделать то работать ничего не будет. И вот после таких дeйствия получаю BSOD Вот код. Код (Text): #include <ntddk.h> typedef struct _SYS_SERVICE_TABLE { ULONG* ServiceTable; ULONG CounterTable; ULONG ServiceLimit; void** ArgumentsTable; } SYS_SERVICE_TABLE, *PSYS_SERVICE_TABLE; extern PSYS_SERVICE_TABLE KeServiceDescriptorTable; UINT32 MyTestProcID = 0xFFFFFFFF; // если 0xFFFFFFFF значит сервис не был добавлен // безопасным способом записывает ULONG значение по указанному адресу int SetULONG(void* Addr, ULONG Value) { int ret = 0; PHYSICAL_ADDRESS PhysicalAddr; void* VirtualAddr; PhysicalAddr = MmGetPhysicalAddress(Addr); if (PhysicalAddr.QuadPart) { VirtualAddr = MmMapIoSpace(PhysicalAddr, 4, 0); if (VirtualAddr) { *(ULONG*)VirtualAddr = Value; ret = 1; MmUnmapIoSpace(VirtualAddr, 4); } } return ret; } // Добавляет процедуру в SDT // на входе адрес процедуры // на выходе номер в SDT. В случае ошибка вернем 0xFFFFFFFF UINT32 AddMyProcToSdt(void* ProcAddr) { UINT32 ret = 0xFFFFFFFF; UINT32 max; max = KeServiceDescriptorTable->ServiceLimit; // получаем кол-во сервисов if (SetULONG(&KeServiceDescriptorTable->ServiceTable[max + 1], max + 1)) // добавим новое контрольное значение { // увеличиваем кол-во сервисов if (SetULONG(&KeServiceDescriptorTable->ServiceLimit, max + 1)) { // Если норм, то прописываем адрес своего сервиса if (SetULONG(&KeServiceDescriptorTable->ServiceTable[max], (ULONG)ProcAddr)) { DbgPrint("Set OK"); ret = max; // вернем адрес нашего сервиса } else // если ошибка добавления адреса сервиса { // вернем на место кол-во сервисов SetULONG(&KeServiceDescriptorTable->ServiceLimit, max); } } } return ret; } // тестовая функция NTSTATUS __stdcall MyTestProc(ULONG param) { DbgPrint("MyTestProc"); return STATUS_SUCCESS; } void DriverUnload(IN PDRIVER_OBJECT DriverObject) { UINT32 max; DbgPrint("DRV UNLOAD"); if (MyTestProcID != 0xFFFFFFFF) // если добавили удачно всё { max = KeServiceDescriptorTable->ServiceLimit; // получим кол-во элементов if (max - 1 == MyTestProcID) // если больше никто не добавлял свои сервисы { // пропатчим значение SetULONG(&KeServiceDescriptorTable->ServiceTable[max - 1], max - 1); // уменьшим кол-во сервисов SetULONG(&KeServiceDescriptorTable->ServiceLimit, max - 1); } } return; } NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath) { DbgPrint("DRV LOAD"); DriverObject->DriverUnload = DriverUnload; // добавляем нашу процедуру в sdt MyTestProcID = AddMyProcToSdt(MyTestProc); if (MyTestProcID != 0xFFFFFFFF) // если добавили удачно { DbgPrint("ADD OK. MyTestProc ID = %0.8X", MyTestProcID); } return STATUS_SUCCESS; } Всё добавляется нормально, но потом через секунду BSOD вылетает.
При этом, если убрать правку контрольного значения, то всё норм пашет, но при попытки вызвать новый сервис вываливается сообщение STATUS_INVALID_SYSTEM_SERVICE. Вообще необходимо добавить сервис в таблицу, неважно куда, главное чтобы его можно было вызвать из юзермода через sysenter
BSOD происходит потому что ты затираешь nt!KiArgumentTable Код (Text): kd> dps nt!KeServiceDescriptorTable L4 8089f7e0 80831b20 nt!KiServiceTable 8089f7e4 00000000 8089f7e8 00000128 8089f7ec 80831fc4 nt!KiArgumentTable kd> db nt!KiServiceTable+(128+1)*4 80831fc4 18 20 2c 2c 40 2c 40 44-0c 08 08 18 18 08 04 04 . ,,@,@D........ 80831fd4 0c 10 18 08 08 08 0c 04-08 08 04 04 0c 08 0c 04 ................ 80831fe4 04 20 08 10 0c 14 0c 2c-10 0c 0c 1c 20 10 38 10 . .....,.... .8. 80831ff4 14 20 24 24 1c 14 10 20-10 34 14 08 0c 08 04 04 . $$... .4...... 80832004 04 04 04 0c 08 28 04 1c-18 08 08 18 0c 18 08 18 .....(.......... 80832014 0c 08 0c 04 10 00 0c 10-28 08 08 10 1c 04 08 0c ........(....... 80832024 04 10 08 00 08 04 08 0c-10 28 08 04 10 04 04 0c .........(...... 80832034 0c 28 04 04 24 28 30 0c-0c 0c 18 0c 0c 0c 0c 30 .(..$(0........0 p.s. почитай про KeAddSystemServiceTable