在InlineHook中修改了zwOpenProcess函数的中的指令
与Resume HookSSDT同理 找出一个正确的值覆盖上去就行、
突发奇想 有没有可能上去一个驱动或者程序 直接卸载掉InlineHook 岂不是很爽
直接映射WCHAR wzFileFullPath[] = L"\SystemRoot\System32\ntdll.dll";
1 BOOLEAN 2 MappingPEFileInRing0Space(WCHAR* wzFileFullPath,OUT PVOID* MappingBaseAddress,PSIZE_T MappingViewSize) 3 { 4 UNICODE_STRING uniFileFullPath; 5 OBJECT_ATTRIBUTES oa; 6 NTSTATUS Status; 7 IO_STATUS_BLOCK Iosb; 8 9 HANDLE hFile = NULL; 10 HANDLE hSection = NULL; 11 12 if (!wzFileFullPath || !MappingBaseAddress){ 13 return FALSE; 14 } 15 16 RtlInitUnicodeString(&uniFileFullPath, wzFileFullPath); 17 InitializeObjectAttributes(&oa, 18 &uniFileFullPath, 19 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 20 NULL, 21 NULL 22 ); 23 24 25 //获得文件句柄 26 Status = IoCreateFile(&hFile, 27 GENERIC_READ | SYNCHRONIZE, 28 &oa, //文件绝对路径 29 &Iosb, 30 NULL, 31 FILE_ATTRIBUTE_NORMAL, 32 FILE_SHARE_READ, 33 FILE_OPEN, 34 FILE_SYNCHRONOUS_IO_NONALERT, 35 NULL, 36 0, 37 CreateFileTypeNone, 38 NULL, 39 IO_NO_PARAMETER_CHECKING 40 ); 41 if (!NT_SUCCESS(Status)) 42 { 43 44 return FALSE; 45 } 46 47 oa.ObjectName = NULL; 48 Status = ZwCreateSection(&hSection, 49 SECTION_QUERY | SECTION_MAP_READ, 50 &oa, 51 NULL, 52 PAGE_WRITECOPY, 53 SEC_IMAGE, //?? 指示内存对齐 54 hFile 55 ); 56 ZwClose(hFile); 57 if (!NT_SUCCESS(Status)) 58 { 59 60 return FALSE; 61 } 62 Status = ZwMapViewOfSection(hSection, 63 NtCurrentProcess(), //映射到当前进程的内存空间中 64 MappingBaseAddress, 65 0, 66 0, 67 0, 68 MappingViewSize, 69 ViewUnmap, 70 0, 71 PAGE_WRITECOPY 72 ); 73 ZwClose(hSection); 74 if (!NT_SUCCESS(Status)) 75 { 76 return FALSE; 77 } 78 79 return TRUE; 80 }
首先 先获取到ntoskrnl模块信息
1 BOOLEAN GetSystemMoudleInformationBySystemModuleNameInWin7_X64(char* szFindSystemModuleName,ULONG64* ulMoudleBaseAddress,ULONG32* ulModuleSize) 2 { 3 int i = 0; 4 NTSTATUS Status = STATUS_SUCCESS; 5 PVOID Information = NULL; 6 ULONG ulNeeds = 0; 7 8 Status = ZwQuerySystemInformation(SystemModuleInformation,NULL,0,&ulNeeds); 9 10 if (Status!=STATUS_INFO_LENGTH_MISMATCH) 11 { 12 return FALSE; 13 } 14 Information = ExAllocatePool(PagedPool,ulNeeds); //PagedPool(数据段 置换到磁盘) NonPagedPool(代码段 不置换到磁盘) 15 16 if (Information==NULL) 17 { 18 return FALSE; 19 } 20 Status = ZwQuerySystemInformation(SystemModuleInformation,Information,ulNeeds,&ulNeeds); 21 22 if (!NT_SUCCESS(Status)) 23 { 24 ExFreePool(Information); 25 return FALSE; 26 } 27 28 for (i=0;i<((PSYSTEM_MODULE_INFORMATION)Information)->NumberOfModules;i++) 29 { 30 31 if (strstr(((PSYSTEM_MODULE_INFORMATION)Information)->Modules[i].ImageName, 32 szFindSystemModuleName)!=NULL) //Ntoskernel.exe 33 { 34 *ulMoudleBaseAddress = ((PSYSTEM_MODULE_INFORMATION)Information)->Modules[i].Base; 35 *ulModuleSize = ((PSYSTEM_MODULE_INFORMATION)Information)->Modules[i].Size; 36 37 38 if (Information!=NULL) 39 { 40 ExFreePool(Information); 41 Information = NULL; 42 } 43 return TRUE; 44 45 } 46 47 } 48 49 50 if (Information!=NULL) 51 { 52 ExFreePool(Information); 53 Information = NULL; 54 } 55 56 return FALSE; 57 }
1 BOOLEAN GetSystemMoudleInformationBySystemModuleNameInWinXP_X86(char* szFindSystemModuleName,ULONG32* ulMoudleBaseAddress,ULONG32* ulModuleSize) 2 { 3 int i = 0; 4 NTSTATUS Status = STATUS_SUCCESS; 5 PVOID Information = NULL; 6 ULONG ulNeeds = 0; 7 8 Status = ZwQuerySystemInformation(SystemModuleInformation,NULL,0,&ulNeeds); 9 10 if (Status!=STATUS_INFO_LENGTH_MISMATCH) 11 { 12 return FALSE; 13 } 14 Information = ExAllocatePool(PagedPool,ulNeeds); //PagedPool(数据段 置换到磁盘) NonPagedPool(代码段 不置换到磁盘) 15 16 if (Information==NULL) 17 { 18 return FALSE; 19 } 20 Status = ZwQuerySystemInformation(SystemModuleInformation,Information,ulNeeds,&ulNeeds); 21 22 if (!NT_SUCCESS(Status)) 23 { 24 ExFreePool(Information); 25 return FALSE; 26 } 27 28 for (i=0;i<((PSYSTEM_MODULE_INFORMATION)Information)->NumberOfModules;i++) 29 { 30 31 if (strstr(((PSYSTEM_MODULE_INFORMATION)Information)->Modules[i].ImageName, 32 szFindSystemModuleName)!=NULL) //Ntoskernel.exe 33 { 34 *ulMoudleBaseAddress = ((PSYSTEM_MODULE_INFORMATION)Information)->Modules[i].Base; 35 *ulModuleSize = ((PSYSTEM_MODULE_INFORMATION)Information)->Modules[i].Size; 36 37 38 if (Information!=NULL) 39 { 40 ExFreePool(Information); 41 Information = NULL; 42 } 43 return TRUE; 44 45 } 46 47 } 48 49 50 if (Information!=NULL) 51 { 52 ExFreePool(Information); 53 Information = NULL; 54 } 55 56 return FALSE; 57 }
获取到SSDTAddress
1 BOOLEAN GetSSDTAddressInWin7_X64(ULONG64* SSDTAddress) 2 { 3 4 PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082); //fffff800`03ecf640 5 PUCHAR EndSearchAddress = StartSearchAddress + 0x500; 6 PUCHAR i = NULL; 7 UCHAR v1=0,v2=0,v3=0; 8 INT64 iOffset = 0; //002320c7 9 ULONG64 VariableAddress = 0; 10 *SSDTAddress = NULL; 11 for(i=StartSearchAddress;i<EndSearchAddress;i++) 12 { 13 if( MmIsAddressValid(i) && MmIsAddressValid(i+1) && MmIsAddressValid(i+2) ) 14 { 15 v1=*i; 16 v2=*(i+1); 17 v3=*(i+2); 18 if(v1==0x4c && v2==0x8d && v3==0x15 ) 19 { 20 memcpy(&iOffset,i+3,4); 21 *SSDTAddress = iOffset + (ULONG64)i + 7; 22 23 break; 24 } 25 } 26 } 27 28 if (*SSDTAddress==NULL) 29 { 30 return FALSE; 31 } 32 return TRUE; 33 }
1 BOOLEAN GetSSDTAddressInWinXP_X86(ULONG32* SSDTAddress) 2 { 3 //从NtosKernel.exe 模块中的导出表获得该导出变量 KeServiceDescriptorTable 4 5 /* 6 kd> dd KeServiceDescriptorTable 7 80563520 804e58a0 00000000 0000011c 805120bc 8 */ 9 *SSDTAddress = NULL; 10 *SSDTAddress = (ULONG32)GetExportVariableAddressFormNtosExportTableByVariableName(L"KeServiceDescriptorTable"); 11 12 if (*SSDTAddress!=NULL) 13 { 14 return TRUE; 15 } 16 17 return FALSE; 18 } 19 20 21 22 PVOID 23 GetExportVariableAddressFormNtosExportTableByVariableName(WCHAR *wzVariableName) 24 { 25 UNICODE_STRING uniVariableName; 26 PVOID VariableAddress = NULL; 27 28 if (wzVariableName && wcslen(wzVariableName) > 0) 29 { 30 RtlInitUnicodeString(&uniVariableName, wzVariableName); 31 32 //从Ntos模块的导出表中获得一个导出变量的地址 33 VariableAddress = MmGetSystemRoutineAddress(&uniVariableName); 34 } 35 36 return VariableAddress; 37 }
在通过函数名获取到函数索引
1 BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWinXP_X86(CHAR* szFindFunctionName, 2 ULONG32* SSDTFunctionIndex) 3 { 4 5 ULONG32 ulOffset_SSDTFunctionIndex = 1; 6 7 8 //从Ntdll模块的导出表中获得7c92d5e0 9 //使用内存映射将Ntdll模块映射到System进程的内存空间进行查找(Ntdll.dll模块的导出表中进行搜索) 10 ULONG i; 11 BOOLEAN bOk = FALSE; 12 WCHAR wzFileFullPath[] = L"\SystemRoot\System32\ntdll.dll"; 13 SIZE_T MappingViewSize = 0; 14 PVOID MappingBaseAddress = NULL; 15 PIMAGE_NT_HEADERS NtHeader = NULL; 16 PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL; 17 ULONG32* AddressOfFunctions = NULL; 18 ULONG32* AddressOfNames = NULL; 19 USHORT* AddressOfNameOrdinals = NULL; 20 CHAR* szFunctionName = NULL; 21 ULONG32 ulFunctionOrdinal = 0; 22 ULONG32 ulFunctionAddress = 0; 23 24 *SSDTFunctionIndex = -1; 25 26 27 //将Ntdll.dll 当前的空间中 28 bOk = MappingPEFileInRing0Space(wzFileFullPath,&MappingBaseAddress, &MappingViewSize); 29 if (bOk==FALSE) 30 { 31 return FALSE; 32 } 33 else 34 { 35 __try{ 36 NtHeader = RtlImageNtHeader(MappingBaseAddress); 37 if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) 38 { 39 ExportDirectory =(IMAGE_EXPORT_DIRECTORY*)((ULONG32)MappingBaseAddress + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); 40 41 42 43 AddressOfFunctions = (ULONG32*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfFunctions); 44 AddressOfNames = (ULONG32*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfNames); 45 AddressOfNameOrdinals = (USHORT*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfNameOrdinals); 46 for(i = 0; i < ExportDirectory->NumberOfNames; i++) 47 { 48 szFunctionName = (char*)((ULONG32)MappingBaseAddress + AddressOfNames[i]); //获得函数名称 49 if (_stricmp(szFunctionName, szFindFunctionName) == 0) 50 { 51 ulFunctionOrdinal = AddressOfNameOrdinals[i]; 52 ulFunctionAddress = (ULONG32)((ULONG32)MappingBaseAddress + AddressOfFunctions[ulFunctionOrdinal]); 53 54 55 *SSDTFunctionIndex = *(ULONG32*)(ulFunctionAddress+ulOffset_SSDTFunctionIndex); 56 break; 57 } 58 } 59 } 60 }__except(EXCEPTION_EXECUTE_HANDLER) 61 { 62 ; 63 } 64 } 65 66 67 ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress); 68 69 70 if (*SSDTFunctionIndex==-1) 71 { 72 return FALSE; 73 } 74 75 return TRUE; 76 }
1 BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWin7_X64(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex) 2 { 3 4 ULONG32 ulOffset_SSDTFunctionIndex = 4; 5 6 ULONG i; 7 BOOLEAN bOk = FALSE; 8 WCHAR wzFileFullPath[] = L"\SystemRoot\System32\ntdll.dll"; 9 SIZE_T MappingViewSize = 0; 10 PVOID MappingBaseAddress = NULL; 11 PIMAGE_NT_HEADERS NtHeader = NULL; 12 PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL; 13 ULONG32* AddressOfFunctions = NULL; 14 ULONG32* AddressOfNames = NULL; 15 USHORT* AddressOfNameOrdinals = NULL; 16 CHAR* szFunctionName = NULL; 17 ULONG32 ulFunctionOrdinal = 0; 18 ULONG64 ulFunctionAddress = 0; 19 20 *SSDTFunctionIndex = -1; 21 22 23 //将Ntdll.dll 当前的空间中 24 bOk = MappingPEFileInRing0Space(wzFileFullPath,&MappingBaseAddress, &MappingViewSize); 25 if (bOk==FALSE) 26 { 27 return FALSE; 28 } 29 else 30 { 31 __try{ 32 NtHeader = RtlImageNtHeader(MappingBaseAddress); 33 if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) 34 { 35 ExportDirectory =(IMAGE_EXPORT_DIRECTORY*)((ULONG64)MappingBaseAddress + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); 36 37 38 39 AddressOfFunctions = (ULONG32*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfFunctions); 40 AddressOfNames = (ULONG32*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfNames); 41 AddressOfNameOrdinals = (USHORT*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfNameOrdinals); 42 for(i = 0; i < ExportDirectory->NumberOfNames; i++) 43 { 44 szFunctionName = (char*)((ULONG64)MappingBaseAddress + AddressOfNames[i]); //获得函数名称 45 if (_stricmp(szFunctionName, szFindFunctionName) == 0) 46 { 47 ulFunctionOrdinal = AddressOfNameOrdinals[i]; 48 ulFunctionAddress = (ULONG64)((ULONG64)MappingBaseAddress + AddressOfFunctions[ulFunctionOrdinal]); 49 50 51 *SSDTFunctionIndex = *(ULONG32*)(ulFunctionAddress+ulOffset_SSDTFunctionIndex); 52 break; 53 } 54 } 55 } 56 }__except(EXCEPTION_EXECUTE_HANDLER) 57 { 58 ; 59 } 60 } 61 62 63 ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress); 64 65 66 if (*SSDTFunctionIndex==-1) 67 { 68 return FALSE; 69 } 70 71 return TRUE; 72 }
得到索引后 就能得到函数的地址
找到函数的地址 然后在映射的内存中取出争取的地址 回复回去