Почему не срабатывает перехват INT 2e? Изменяю указатель в IDT по смещению 0x170 (0x8 * 0x2e), перезапись проходит успешно, но следом идет перезагрузка? Да, дело было на xp sp2 Код (Text): void __declspec(naked) new_syscall(void) { __asm { pushad pushfd push fs mov di, 0x30 mov fs, di ; fs[0x30] -> struct _KPRC ; _KPCR[0x120] -> struct _KPRCB PrcbData; ; _KPRCB[0x4] -> struct _KTHREAD* CurrentThread; mov eax, fs:[0x124] ; _KTHREAD* ; _KTHREAD[0x34] -> struct _KAPC_STATE ApcState ; _KAPC_STATE[0x10] -> struct _KPROCESS* Process; mov eax, [eax+0x44] ; _KPROCESS* is EPROCESS address ;push eax ;call Xxxxxx pop fs popfd popad jmp old_int2e }; } void __int2e_hook() { IDT idt; PVOID p = &idt; __asm { pushad mov ecx, 0x176 rdmsr mov old_sysenter, eax mov eax, new_syscall xor edx, edx wrmsr sidt [idt] mov edi, [p] add edi, 0x02 mov ebx, [edi] ; 0x8 * 0x2e = 0x170 xchg [ebx + 170h], ax rol eax, 0x10 xchg [ebx + 0x176], ax ror eax, 0x10 mov old_int2e, eax popad } }
Пример есть в сорцах phunter, правда там не совсем корректно реализован перехват fast system call. на XP SP1 есть такие грабли, которые заключаются в том, что SYSENTER_ESP_MSR = 0, а следовательно стек в обработчике сискала недоступен, сначала надо загрузить esp. Примерно это будет выглядеть так: Код (Text): static _declspec(naked) NewKiFastcallEntry() { __asm { mov esp, ss:[0x0FFDFF040] mov esp, ss:[esp+4] pushad pushfd push fs push ds mov bx, 0x30 mov fs, bx mov bx, 0x24 mov ds, bx call ProcessSyscall pop ds pop fs popfd popad jmp [TrueKiFastcallEntry] } }
да, когда процессор более древней версии просто не поддерживает данную команду, поэтому перед было бы неплохо спрашивать у него cpuid/
Ага, и еще читать SYSENTER_CS_MSR, если он нулевой, то fast system call не используется. Код (Text): __asm { pushad mov eax, 1 cpuid and edx, 0x800 test edx, edx jz _exit mov ecx, 0x174 rdmsr mov [SeAddr], eax _exit: popad }