Устанавливаю перехват методом замены первых байт функции Код (Text): //-------------------------------------------------------------------------------------- void InsertByte( ULONG Addr, unsigned char Byte ) { *((unsigned char*)Addr) = Byte; } //-------------------------------------------------------------------------------------- void InsertDword( ULONG Addr, ULONG dWord ) { *((PULONG)Addr) = dWord; } //-------------------------------------------------------------------------------------- #define SIZEOFJUMP 5 #define ASMNOP 0x90 #define ASMJMP 0xe9 void GenJmp(ULONG From, ULONG To) { InsertDword(From + 1, To - From - 5); // dst - src - 5 InsertByte(From, ASMJMP); // jmp ... } //-------------------------------------------------------------------------------------- //Устанавливает хук PVOID Hook( PVOID Addr, PVOID NewFunc, PULONG CollectedSpace ) { PVOID CallGate, Inst = Addr; ULONG Size = 0, CallGateSize = 0; if (Addr == NULL) return 0; *CollectedSpace = 0; while (*CollectedSpace < SIZEOFJUMP) { GetInstLenght(Inst, &Size); (ULONG)Inst += Size; *CollectedSpace += Size; } CallGateSize = *CollectedSpace + SIZEOFJUMP; CallGate = (PVOID)ExAllocatePool(NonPagedPool, CallGateSize); DbgPrint("Function addr : 0x%.8x\n", Addr); DbgPrint("Handler addr : 0x%.8x\n", NewFunc); DbgPrint("CallGate at : 0x%.8x; size : %d\n", CallGate, CallGateSize); memset(CallGate, ASMNOP, CallGateSize); memcpy(CallGate, Addr, *CollectedSpace); memset(Addr, ASMNOP, *CollectedSpace); GenJmp( (ULONG)CallGate + *CollectedSpace, (ULONG)Addr + SIZEOFJUMP ); GenJmp( (ULONG)Addr, (ULONG)NewFunc ); return CallGate; } //-------------------------------------------------------------------------------------- //Устанавливаем ловушки void InstallHooks(void) { ULONG CR0Reg; __asm { cli mov eax,cr0 mov CR0Reg,eax and eax,0xFFFEFFFF mov cr0,eax } OldZwOpenProcess = ( funcZwOpenProcess ) Hook((PVOID)NTCALL(ZwOpenProcessInfo.FunctionAddress), NewZwOpenProcess, &ZwOpenProcessInfo.CollectedSpace ); OldNtWriteVirtualMemory = ( funcNtWriteVirtualMemory ) Hook((PVOID)NTCALL(NtWriteVirtualMemoryInfo.FunctionAddress), NewNtWriteVirtualMemory, &NtWriteVirtualMemoryInfo.CollectedSpace ); __asm { mov eax,CR0Reg mov cr0,eax sti } } Снимаю перехват вот так : Код (Text): //Снимаем ловушки void RemoveHooks(void) { ULONG CR0Reg; __asm { cli mov eax,cr0 mov CR0Reg,eax and eax,0xFFFEFFFF mov cr0,eax } memcpy( (PVOID)NTCALL(ZwOpenProcessInfo.FunctionAddress), OldZwOpenProcess, ZwOpenProcessInfo.CollectedSpace ); memcpy( (PVOID)NTCALL(NtWriteVirtualMemoryInfo.FunctionAddress), OldNtWriteVirtualMemory, NtWriteVirtualMemoryInfo.CollectedSpace ); __asm { mov eax,CR0Reg mov cr0,eax sti } } После снятия - БСОД. Что не так делаю. Все вроде верно. Я запоминаю CollectedSpace и копирую это кол-во байт из моего Калгейта на место оригинально функции.
WaterGhost Если просто нужно подменить функцию и метод неважен, то прочти это: http://rootkits.ru/viewtopic.php?id=39&action=new. Ключевые слова - SSDT, MDL.
Нет,подмена адреса в таблице мне не годится. Мне необходимо конкретно реализовать этот случай. Я никак не могу понять что я делаю не так =\
Тему можно закрывать. Вопрос решен. Причина : Все верно делал Просто оказывается при выгрузке драйвера забыл снять Routine создания\удаления процессов. После выгрузки обработчик моей Routine уничтожался и при первом же запуске\уничтожении процесса Windows уходила в БСОД обращаясь к несуществующему обработчику.
WaterGhost раз ты теперь во всем разобрался, можно нубский вопрос? Вот ты, как я понял, защищаешься от разного рода казусов многозадачности с помощью cli и sti, но ведь это запрещает прерывания только на одном процессоре, а что если их несколько?
Но ведь можно наверно запретить прерывания на контроллере прерываний К тому же несовсем я понял что значит перевести все процессоры в DISPATCH_LEVEL