SSDT InlineHook是在SSDT Hook 根本上来进一步Hook的,SSDTHook 是直接将SSDT表中的 Nt*函数替换成Fake函数,而SSDT Inline Hook是将原函数代码的前五个字节转变为 E9 _ _ _ _ ,后面跟的是Offset,也就是我们Fake函数的偏移地点,这样当Ring3层函数,好比OpenProcess在Ring3 层被挪用,,然后进入Ring0 层的NtOpenProcess,但是前五个字节已经被我们转变,酿成了跳板,就会进入我们实现写好的Fake函数中去。
Nt系列函数地点也是通过SSDT表来找到,上次写的SSDT Hook 中是用MmGetSystemRoutineAddress 来获取函数地点的,此次我通过手动的去找ntdll.dll中的导出表,找到的函数地点,然后找到索引,通过SSDT表找Nt*的函数地点。
1 ULONG GetSSDTFunctionIndexByName(CHAR * FunctionName) 2 { 3 NTSTATUS Status = STATUS_UNSUCCESSFUL; 4 ULONG Offset = 1; 5 WCHAR* FileFullPath = L"\\SystemRoot\\System32\\ntdll.dll"; 6 ULONG i; 7 SIZE_T MappingViewSize = 0; 8 PVOID MappingBaseAddress = NULL; 9 PIMAGE_NT_HEADERS ImageNtHeader = NULL; 10 PIMAGE_EXPORT_DIRECTORY ImageExportDirectory = NULL; 11 ULONG* AddressOfFunction = NULL; 12 ULONG* AddressOfName = NULL; 13 USHORT* AddressOfNameOrdinals = NULL; 14 CHAR* szFunctionName = NULL; 15 ULONG FunctionOrdinal = 0; 16 ULONG FunctionAddress = 0; 17 ULONG Index = 0; 18 //将Ntdll 映射到当前内核地点空间中 19 Status = MappingPeFile(FileFullPath, &MappingBaseAddress, &MappingViewSize); 20 if (!NT_SUCCESS(Status)) 21 { 22 return 0; 23 } 24 25 __try 26 { 27 ImageNtHeader = RtlImageNtHeader(MappingBaseAddress); 28 if (ImageNtHeader&&ImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) 29 { 30 ImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((ULONG_PTR)MappingBaseAddress + 31 ImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); 32 33 //函数名字表 34 AddressOfName = (ULONG*)((ULONG_PTR)MappingBaseAddress + ImageExportDirectory->AddressOfNames); 35 //函数序号表 36 AddressOfNameOrdinals = (USHORT*)((ULONG_PTR)MappingBaseAddress + ImageExportDirectory->AddressOfNameOrdinals); 37 //按照序号表中的序号 函数地点表 38 AddressOfFunction = (ULONG*)((ULONG_PTR)MappingBaseAddress + ImageExportDirectory->AddressOfFunctions); 39 40 for (i = 0;i < ImageExportDirectory->NumberOfNames;i++) 41 { 42 //获得函数名称 43 szFunctionName = (CHAR*)((ULONG_PTR)MappingBaseAddress + AddressOfName[i]); 44 if (_stricmp(szFunctionName, FunctionName) == 0) 45 { 46 //获得函数序号 47 FunctionOrdinal = AddressOfNameOrdinals[i]; 48 //获得函数地点 49 FunctionAddress = AddressOfFunction[FunctionOrdinal]+ (ULONG_PTR)MappingBaseAddress; 50 /* 51 2: kd> u ZwOpenProcess 52 nt!ZwOpenProcess: 53 8485acd8 b8be000000 mov eax,0BEh 54 8485acdd 8d542404 lea edx,[esp+4] 55 8485ace1 9c pushfd 56 8485ace2 6a08 push 8 57 8485ace4 e8d5190000 call nt!KiSystemService (8485c6be) 58 8485ace9 c21000 ret 10h 59 60 */ 61 Index = SSDT_INDEX(FunctionAddress); 62 break; 63 } 64 } 65 } 66 } 67 __except(1) 68 { 69 return 0; 70 } 71 ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress); 72 73 return Index ; 74 }