HookSSDT 通过HookOpenProcess函数阻止暴力枚举进程
首先要知道Ring3层调用OpenProcess的流程
//当Ring3调用OpenProcess
//1从自己的模块(.exe)的导入表中取值
//2Ntdll.dll模块的导出表中执行ZwOpenProcess(取索引 进入Ring0层)
//3进入Ring0 从Ntoskernel.exe模块的导出表中执行ZwOpenProcess(取索引 获得SSDT服务地址)
//4通过索引在SSDT表中取值(NtOpenProcess的地址)
//5真正调用NtOpenProcess函数
我们可以通过在第4部通过索引将NtOpenProcess 换成 Base[索引] = FakeNtOpenProcess;
1.我们要获取SSDT的结构信息
XP 32位的SSDT在Ntos模块导出表中有
- //SSDT表的基地址32位(4Bytes)64位(8Bytes)
- //XP 32位Ntos模块导出表中有 Win7 64 Ntos模块导出表中无
- BOOLEAN GetSSDTAddressInWinXP_X86(ULONG32* SSDTAddress)
- {
- //从NtosKernel.exe 模块中的导出表获得该导出变量 KeServiceDescriptorTable
- /*
- kd> dd KeServiceDescriptorTable
- 80563520 804e58a0 00000000 0000011c 805120bc
- */
- *SSDTAddress = NULL;
- *SSDTAddress = (ULONG32)GetExportVariableAddressFormNtosExportTableByVariableName(L"KeServiceDescriptorTable");
- if (*SSDTAddress!=NULL)
- {
- return TRUE;
- }
- return FALSE;
- }
获取SSDT的地址32
win7 64位没有被导出 但可以通过读取制定的msr得出
// 来自 作者:胡文亮
Msr 的中文全称是就是“特别模块寄存器” (model specific
register) ,它控制 CPU 的工作环境和标示 CPU 的工作状态等信息(例如倍频、最大 TDP、
危险警报温度) ,它能够读取,也能够写入,但是无论读取还是写入,都只能在 Ring 0 下
进行。我们通过读取 C0000082 寄存器,能够得到 KiSystemCall64 的地址,然后从
KiSystemCall64 的地址开始,往下搜索 0x500 字节左右(特征码是 4c8d15) ,就能得到
KeServiceDescriptorTable 的地址了。同理,我们换一下特征码(4c8d1d) ,就能获得
KeServiceDescriptorTableShadow 的地址了。
- BOOLEAN GetSSDTAddressInWin7_X64(ULONG64* SSDTAddress)
- {
- /*
- kd> rdmsr c0000082
- msr[c0000082] = fffff800`03ecf640
- kd> u fffff800`03ecf640 l 50
- nt!KiSystemCall64:
- fffff800`03ecf640 0f01f8 swapgs
- fffff800`03ecf643 654889242510000000 mov qword ptr gs:[10h],rsp
- fffff800`03ecf64c 65488b2425a8010000 mov rsp,qword ptr gs:[1A8h]
- fffff800`03ecf655 6a2b push 2Bh
- fffff800`03ecf657 65ff342510000000 push qword ptr gs:[10h]
- fffff800`03ecf65f 4153 push r11
- fffff800`03ecf661 6a33 push 33h
- fffff800`03ecf663 51 push rcx
- fffff800`03ecf664 498bca mov rcx,r10
- fffff800`03ecf667 4883ec08 sub rsp,8
- fffff800`03ecf66b 55 push rbp
- fffff800`03ecf66c 4881ec58010000 sub rsp,158h
- fffff800`03ecf673 488dac2480000000 lea rbp,[rsp+80h]
- fffff800`03ecf67b 48899dc0000000 mov qword ptr [rbp+0C0h],rbx
- fffff800`03ecf682 4889bdc8000000 mov qword ptr [rbp+0C8h],rdi
- fffff800`03ecf689 4889b5d0000000 mov qword ptr [rbp+0D0h],rsi
- fffff800`03ecf690 c645ab02 mov byte ptr [rbp-55h],2
- fffff800`03ecf694 65488b1c2588010000 mov rbx,qword ptr gs:[188h]
- fffff800`03ecf69d 0f0d8bd8010000 prefetchw [rbx+1D8h]
- fffff800`03ecf6a4 0fae5dac stmxcsr dword ptr [rbp-54h]
- fffff800`03ecf6a8 650fae142580010000 ldmxcsr dword ptr gs:[180h]
- fffff800`03ecf6b1 807b0300 cmp byte ptr [rbx+3],0
- fffff800`03ecf6b5 66c785800000000000 mov word ptr [rbp+80h],0
- fffff800`03ecf6be 0f848c000000 je nt!KiSystemCall64+0x110 (fffff800`03ecf750)
- fffff800`03ecf6c4 488945b0 mov qword ptr [rbp-50h],rax
- fffff800`03ecf6c8 48894db8 mov qword ptr [rbp-48h],rcx
- fffff800`03ecf6cc 488955c0 mov qword ptr [rbp-40h],rdx
- fffff800`03ecf6d0 f6430303 test byte ptr [rbx+3],3
- fffff800`03ecf6d4 4c8945c8 mov qword ptr [rbp-38h],r8
- fffff800`03ecf6d8 4c894dd0 mov qword ptr [rbp-30h],r9
- fffff800`03ecf6dc 7405 je nt!KiSystemCall64+0xa3 (fffff800`03ecf6e3)
- fffff800`03ecf6de e80d140000 call nt!KiSaveDebugRegisterState (fffff800`03ed0af0)
- fffff800`03ecf6e3 f6430380 test byte ptr [rbx+3],80h
- fffff800`03ecf6e7 7442 je nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
- fffff800`03ecf6e9 b9020100c0 mov ecx,0C0000102h
- fffff800`03ecf6ee 0f32 rdmsr
- fffff800`03ecf6f0 48c1e220 shl rdx,20h
- fffff800`03ecf6f4 480bc2 or rax,rdx
- fffff800`03ecf6f7 483983b8000000 cmp qword ptr [rbx+0B8h],rax
- fffff800`03ecf6fe 742b je nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
- fffff800`03ecf700 483983b0010000 cmp qword ptr [rbx+1B0h],rax
- fffff800`03ecf707 7422 je nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
- fffff800`03ecf709 488b93b8010000 mov rdx,qword ptr [rbx+1B8h]
- fffff800`03ecf710 0fba6b4c0b bts dword ptr [rbx+4Ch],0Bh
- fffff800`03ecf715 66ff8bc4010000 dec word ptr [rbx+1C4h]
- fffff800`03ecf71c 48898280000000 mov qword ptr [rdx+80h],rax
- fffff800`03ecf723 fb sti
- fffff800`03ecf724 e8170b0000 call nt!KiUmsCallEntry (fffff800`03ed0240)
- fffff800`03ecf729 eb0f jmp nt!KiSystemCall64+0xfa (fffff800`03ecf73a)
- fffff800`03ecf72b f6430340 test byte ptr [rbx+3],40h
- fffff800`03ecf72f 7409 je nt!KiSystemCall64+0xfa (fffff800`03ecf73a)
- fffff800`03ecf731 f00fbaab0001000008 lock bts dword ptr [rbx+100h],8
- fffff800`03ecf73a 488b45b0 mov rax,qword ptr [rbp-50h]
- fffff800`03ecf73e 488b4db8 mov rcx,qword ptr [rbp-48h]
- fffff800`03ecf742 488b55c0 mov rdx,qword ptr [rbp-40h]
- fffff800`03ecf746 4c8b45c8 mov r8,qword ptr [rbp-38h]
- fffff800`03ecf74a 4c8b4dd0 mov r9,qword ptr [rbp-30h]
- fffff800`03ecf74e 6690 xchg ax,ax
- fffff800`03ecf750 fb sti
- fffff800`03ecf751 48898be0010000 mov qword ptr [rbx+1E0h],rcx
- fffff800`03ecf758 8983f8010000 mov dword ptr [rbx+1F8h],eax
- nt!KiSystemServiceStart:
- fffff800`03ecf75e 4889a3d8010000 mov qword ptr [rbx+1D8h],rsp
- fffff800`03ecf765 8bf8 mov edi,eax
- fffff800`03ecf767 c1ef07 shr edi,7
- fffff800`03ecf76a 83e720 and edi,20h
- fffff800`03ecf76d 25ff0f0000 and eax,0FFFh
- nt!KiSystemServiceRepeat:
- fffff800`03ecf772 4c8d15c7202300 lea r10,[nt!KeServiceDescriptorTable (fffff800`04101840)]
- fffff800`03ecf772 + 002320c7 + 7 = fffff800`04101840
- */
- PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082); //fffff800`03ecf640
- PUCHAR EndSearchAddress = StartSearchAddress + 0x500;
- PUCHAR i = NULL;
- UCHAR v1=,v2=,v3=;
- INT64 iOffset = ; //002320c7
- ULONG64 VariableAddress = ;
- *SSDTAddress = NULL;
- for(i=StartSearchAddress;i<EndSearchAddress;i++)
- {
- if( MmIsAddressValid(i) && MmIsAddressValid(i+) && MmIsAddressValid(i+) )
- {
- v1=*i;
- v2=*(i+);
- v3=*(i+);
- if(v1==0x4c && v2==0x8d && v3==0x15 )
- {
- memcpy(&iOffset,i+,);
- *SSDTAddress = iOffset + (ULONG64)i + ;
- break;
- }
- }
- }
- if (*SSDTAddress==NULL)
- {
- return FALSE;
- }
- /*
- kd> dq fffff800`04101840
- fffff800`04101840 fffff800`03ed1300 00000000`00000000
- fffff800`04101850 00000000`00000191 fffff800`03ed1f8c
- */
- return TRUE;
- }
获取SSDT
2从Ntdll模块中的导出表获得要Hook的函数索引
- BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWinXP_X86(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex)
- {
- /*
- 0:001> u zwopenprocess
- ntdll!ZwOpenProcess:
- 7c92d5e0 b87a000000 mov eax,7Ah
- 7c92d5e5 ba0003fe7f mov edx,offset SharedUserData!SystemCallStub (7ffe0300)
- 7c92d5ea ff12 call dword ptr [edx]
- 7c92d5ec c21000 ret 10h
- 7c92d5ef 90 nop
- */
- ULONG32 ulOffset_SSDTFunctionIndex = ;
- //从Ntdll模块的导出表中获得7c92d5e0
- //使用内存映射将Ntdll模块映射到System进程的内存空间进行查找(Ntdll.dll模块的导出表中进行搜索)
- ULONG i;
- BOOLEAN bOk = FALSE;
- WCHAR wzFileFullPath[] = L"\\SystemRoot\\System32\\ntdll.dll";
- SIZE_T MappingViewSize = ;
- PVOID MappingBaseAddress = NULL;
- PIMAGE_NT_HEADERS NtHeader = NULL;
- PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
- ULONG32* AddressOfFunctions = NULL;
- ULONG32* AddressOfNames = NULL;
- USHORT* AddressOfNameOrdinals = NULL;
- CHAR* szFunctionName = NULL;
- ULONG32 ulFunctionOrdinal = ;
- ULONG32 ulFunctionAddress = ;
- *SSDTFunctionIndex = -;
- //将Ntdll.dll 当前的空间中
- bOk = MappingPEFileInRing0Space(wzFileFullPath,&MappingBaseAddress, &MappingViewSize);
- if (bOk==FALSE)
- {
- return FALSE;
- }
- else
- {
- __try{
- NtHeader = RtlImageNtHeader(MappingBaseAddress);
- if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
- {
- ExportDirectory =(IMAGE_EXPORT_DIRECTORY*)((ULONG32)MappingBaseAddress + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
- AddressOfFunctions = (ULONG32*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfFunctions);
- AddressOfNames = (ULONG32*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfNames);
- AddressOfNameOrdinals = (USHORT*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfNameOrdinals);
- for(i = ; i < ExportDirectory->NumberOfNames; i++)
- {
- szFunctionName = (char*)((ULONG32)MappingBaseAddress + AddressOfNames[i]); //获得函数名称
- if (_stricmp(szFunctionName, szFindFunctionName) == )
- {
- ulFunctionOrdinal = AddressOfNameOrdinals[i];
- ulFunctionAddress = (ULONG32)((ULONG32)MappingBaseAddress + AddressOfFunctions[ulFunctionOrdinal]);
- *SSDTFunctionIndex = *(ULONG32*)(ulFunctionAddress+ulOffset_SSDTFunctionIndex);
- break;
- }
- }
- }
- }__except(EXCEPTION_EXECUTE_HANDLER)
- {
- ;
- }
- }
- ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress);
- if (*SSDTFunctionIndex==-)
- {
- return FALSE;
- }
- return TRUE;
- }
获取函数索引32
- BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWin7_X64(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex)
- {
- /*
- 0:004> u zwopenprocess
- ntdll!NtOpenProcess:
- 00000000`774ddc10 4c8bd1 mov r10,rcx
- 00000000`774ddc13 b823000000 mov eax,23h
- 00000000`774ddc18 0f05 syscall
- 00000000`774ddc1a c3 ret
- 00000000`774ddc1b 0f1f440000 nop dword ptr [rax+rax]
- */
- ULONG32 ulOffset_SSDTFunctionIndex = ;
- ULONG i;
- BOOLEAN bOk = FALSE;
- WCHAR wzFileFullPath[] = L"\\SystemRoot\\System32\\ntdll.dll";
- SIZE_T MappingViewSize = ;
- PVOID MappingBaseAddress = NULL;
- PIMAGE_NT_HEADERS NtHeader = NULL;
- PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
- ULONG32* AddressOfFunctions = NULL;
- ULONG32* AddressOfNames = NULL;
- USHORT* AddressOfNameOrdinals = NULL;
- CHAR* szFunctionName = NULL;
- ULONG32 ulFunctionOrdinal = ;
- ULONG64 ulFunctionAddress = ;
- *SSDTFunctionIndex = -;
- //将Ntdll.dll 当前的空间中
- bOk = MappingPEFileInRing0Space(wzFileFullPath,&MappingBaseAddress, &MappingViewSize);
- if (bOk==FALSE)
- {
- return FALSE;
- }
- else
- {
- __try{
- NtHeader = RtlImageNtHeader(MappingBaseAddress);
- if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
- {
- ExportDirectory =(IMAGE_EXPORT_DIRECTORY*)((ULONG64)MappingBaseAddress + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
- AddressOfFunctions = (ULONG32*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfFunctions);
- AddressOfNames = (ULONG32*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfNames);
- AddressOfNameOrdinals = (USHORT*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfNameOrdinals);
- for(i = ; i < ExportDirectory->NumberOfNames; i++)
- {
- szFunctionName = (char*)((ULONG64)MappingBaseAddress + AddressOfNames[i]); //获得函数名称
- if (_stricmp(szFunctionName, szFindFunctionName) == )
- {
- ulFunctionOrdinal = AddressOfNameOrdinals[i];
- ulFunctionAddress = (ULONG64)((ULONG64)MappingBaseAddress + AddressOfFunctions[ulFunctionOrdinal]);
- *SSDTFunctionIndex = *(ULONG32*)(ulFunctionAddress+ulOffset_SSDTFunctionIndex);
- break;
- }
- }
- }
- }__except(EXCEPTION_EXECUTE_HANDLER)
- {
- ;
- }
- }
- ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress);
- if (*SSDTFunctionIndex==-)
- {
- return FALSE;
- }
- return TRUE;
- }
获取函数索引64
3.保存原先函数的地址
64位与32位不同 64为中存放的并不是SSDT函数的完整地址而是其相对于
ServiceTableBase[Index]>>4 的数据(称它为偏移地址)
4.在32位中换掉Base中索引里的数据 NtOpenProcess Base[索引] == FakeNtOpenProcess -->HookSSDT
在32位中 直接替换就可以了但是......................
/* 一系列的说明 作者:胡文亮 */
HOOK SSDT 就很简单了,首先获得待 HOOK 函数的序号
Index,然后通过公式把自己的代理函数的地址转化为偏移地址,然后把偏移地
址的数据填入 ServiceTableBase[Index]。也许有些读者看到这里,已经觉得胜
利在望了,我当时也是如此。但实际上我在这里栽了个大跟头,整整郁闷了很长
时间!因为我低估了设计这套算法的工程师的智商,我没有考虑一个问题,为什
么 WIN64 的 SSDT 表存放地址的形式这么奇怪?只存放偏移地址,而不存放完整
地址?难道是为了节省内存?这肯定是不可能的,要知道现在内存白菜价。那么
不是为了节省内存,唯一的可能性就是要给试图挂钩 SSDT 的人制造麻烦!要知
道,WIN64 内核里每个驱动都 不在同一个 B 4GB 里,而 4 字节的整数只能表示 4GB
的范围!所以无论你怎么修改这个值,都跳不出 ntoskrnl 的手掌心。如果你想
通过修改这个值来跳转到你的代理函数, 那是绝对不可能的。 因为你的驱动的地
址不 可能跟 l ntoskrnl 在同一个 B 4GB 里。然而,这位工程师也低估了我们中国人
的智商, 在中国有两句成语, 这位工程师一定没听过, 叫 “明修栈道, 暗渡陈仓”
以及“上有政策,下有对策” 。虽然不能直接用 4 字节来表示自己的代理函数所
在的地址, 但是还是可以修改这个值的。 要知道, ntoskrnl 虽然有很多地方的代
码通常是不会被执行的, 比如 KeBugCheckEx。 所以我的办法是: 修改这个偏移地
址的值,使之跳转到 KeBugCheckEx ,然后在 x KeBugCheckEx 的头部写一个 2 12 字
节的 mov - - jmp , 这是一个可以跨越 4GB B ! 的跳转, 跳到我们的函数里!
- VOID HookSSDTWin7_X64(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG64 ulFakeVariable)
- {
- //寻找一个内核不常用的函数(KeBugCheckEx) 进行InlineHook使其跳转到Fake_NtOpenProcess函数
- ULONG32 ulVariable = ;
- WPOFF();
- InlineHook(KeBugCheckEx,ulFakeVariable,szOldKeBugCheckExCode,);
- WPON();
- //寻找一个内核不常用的函数(KeBugCheckEx) 计算SSDT中的偏移 进行置换
- ulVariable = CalcFunctionOffsetInSSDT(KeBugCheckEx,);
- WPOFF();
- ServiceTableBase[ulSSDTFunctionIndex] = (ULONG32)ulVariable;
- WPON();
- }
HookSSDT64
- VOID HookSSDTWinXP_X86(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG32 ulFakeVariable)
- {
- WPOFF();
- ServiceTableBase[ulSSDTFunctionIndex] = (ULONG32)ulFakeVariable;
- WPON();
- }
HookSSDT32
完整代码
- #ifndef CXX_HOOKSSDT_H
- # include "HookSSDT.h"
- #endif
- //1获得SSDT表的结构信息 Base
- //2从Ntdll模块中的导出表获得要Hook的函数索引
- //3换掉Base中索引里的数据 NtOpenProcess Base[索引] == FakeNtOpenProcess --->HookSSDT
- PULONG32 ServiceTableBase = NULL;
- ULONG32 SSDT_NtOpenProcessIndex = ;
- pfnNtOpenProcess Old_NtOpenProcess = NULL;
- ULONG32 Old_NtOpenProcessOffset = ; //针对Win7 x64
- UCHAR szOldKeBugCheckExCode[] = {};
- NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegisterPath)
- {
- #ifdef _WIN64
- ULONG64 SSDTAddress = NULL;
- ULONG32 ulVariable = ;
- CHAR szFindFunctionName[] = "ZwOpenProcess";
- if (GetSSDTAddressInWin7_X64(&SSDTAddress)==FALSE)
- {
- return STATUS_UNSUCCESSFUL;
- }
- DbgPrint("Win7x64 SSDT:%p\r\n",SSDTAddress);
- DbgPrint("Win7x64 SSDTBase:%p\r\n",((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase);
- /*
- kd> dd FFFFF80003E8B300 l 200
- fffff800`03e8b300 040d9a00 02f55c00 fff6ea00 02e87805
- fffff800`03e8b310 031a4a06 03116a05 02bb9901 02b4f200
- fffff800`03e8b320 0312cc40 03dd7400 02c84700 02e7d100
- fffff800`03e8b330 02f68100 02e02301 02dd0601 02d96100
- fffff800`03e8b340 02df4602 02f18600 02ad0500 02cefe01
- fffff800`03e8b350 02d01d02 02f69902 03101101 0323ca01
- fffff800`03e8b360 0455c305 02ed29c0 02b2e703 ffec1d00
- fffff800`03e8b370 043c2800 02f51040 02c52c01 03126c00
- fffff800`03e8b380 02d96302 02d30380 02ec7301 02d1fec0(NtOpenProcess Offset)
- */
- /*
- kd> u NtOpenProcess
- nt!NtOpenProcess:
- fffff800`0415d2ec 4883ec38 sub rsp,38h
- fffff800`0415d2f0 65488b042588010000 mov rax,qword ptr gs:[188h]
- fffff800`0415d2f9 448a90f6010000 mov r10b,byte ptr [rax+1F6h]
- fffff800`0415d300 4488542428 mov byte ptr [rsp+28h],r10b
- fffff800`0415d305 4488542420 mov byte ptr [rsp+20h],r10b
- fffff800`0415d30a e851fcffff call nt!PsOpenProcess (fffff800`0415cf60)
- fffff800`0415d30f 4883c438 add rsp,38h
- fffff800`0415d313 c3 ret
- */
- //fffff8000415d2ec - FFFFF80003E8B300 = 2D1FEC<<4 = 2D1FEC0
- DbgPrint("Win7x64 SSDTNumberOfService:%d\r\n",((PSYSTEM_SERVICE_TABLE)SSDTAddress)->NumberOfServices);
- if (GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWin7_X64(szFindFunctionName,&SSDT_NtOpenProcessIndex)==FALSE)
- {
- return STATUS_UNSUCCESSFUL;
- }
- DbgPrint("Win7x64 SSDT_NtOpenProcessIndex:%d\r\n",SSDT_NtOpenProcessIndex);
- ServiceTableBase = (PULONG32)((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase;
- Old_NtOpenProcessOffset = (ULONG32)(ServiceTableBase[SSDT_NtOpenProcessIndex]);
- ulVariable = Old_NtOpenProcessOffset>>;
- Old_NtOpenProcess = (ULONG64)((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase + ulVariable;
- DbgPrint("Win7x64 Old_NtOpenProcess:%p\r\n",ulVariable);
- /*
- kd> u FFFFF8000415D2EC
- nt!NtOpenProcess:
- fffff800`0415d2ec 4883ec38 sub rsp,38h
- fffff800`0415d2f0 65488b042588010000 mov rax,qword ptr gs:[188h]
- fffff800`0415d2f9 448a90f6010000 mov r10b,byte ptr [rax+1F6h]
- fffff800`0415d300 4488542428 mov byte ptr [rsp+28h],r10b
- fffff800`0415d305 4488542420 mov byte ptr [rsp+20h],r10b
- fffff800`0415d30a e851fcffff call nt!PsOpenProcess (fffff800`0415cf60)
- fffff800`0415d30f 4883c438 add rsp,38h
- fffff800`0415d313 c3 ret
- */
- HookSSDTWin7_X64(ServiceTableBase,SSDT_NtOpenProcessIndex,(ULONG64)Fake_NtOpenProcess);
- #else
- ULONG32 SSDTAddress = NULL;
- CHAR szFindFunctionName[] = "ZwOpenProcess";
- if (GetSSDTAddressInWinXP_X86(&SSDTAddress)==FALSE)
- {
- return STATUS_UNSUCCESSFUL;
- }
- DbgPrint("WinXPx86 SSDT:%p\r\n",SSDTAddress);
- DbgPrint("WinXPx86 SSDTBase:%p\r\n",((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase);
- /*
- kd> dd 804E58A0 l 200 SSDTBase
- 804e58a0 80591bfb 80585356 805e1f35 805dbc47
- 804e58b0 805e1fbc 80640cc2 80642e4b 80642e94
- 804e58c0 805835b2 80650bbb 8064047d 805e1787
- 804e58d0 8063878a 80586fa1 805e08e8 8062f432
- 804e58e0 805d9781 80571d45 805e8258 805e939e
- 804e58f0 804e5eb4 80650ba7 805cd537 804ed812
- 804e5900 805719b7 80570af2 805e1b65 80656cec
- 804e5910 805e0ff3 805887b7 80656f5b 80586563
- 804e5920 804e221d 8066239e 805aa76b 8057dd2d
- 804e5930 8065120c 8057d330 805db662 805d6cd6
- 804e5940 80638c31 80578925 805d7e7f 805803c0
- 804e5950 80589caa 805b5823 8059a02a 805b1470
- 804e5960 8058c7cd 8065182d 8056eb66 8057b9e4
- 804e5970 805e7e56 80587c43 80598cb2 805a7ada
- 804e5980 805ab552 80663519 80663673 8056fb07
- 804e5990 805ddc8b 80650ba7 805d64ac 80594334
- 804e59a0 80642eef 80592f8b 805899a6 805b6cd8
- 804e59b0 8058221e 80584451 80650bbb 80579e1c
- 804e59c0 80650b93 80588691 8062e3f1 805cf473
- 804e59d0 805e36f2 80586ceb 80588bf9 805da3bb
- 804e59e0 805e9ab6 8062fc8f 8062f7e5 805723df
- 804e59f0 805813f3 80636711 80634be3 8059c497
- 804e5a00 8054070f 80599bde 805e0d66 8058968d
- 804e5a10 805aad25 806349af 80638ae7 80634bca
- 804e5a20 805aab94 805a9f96 805cf7e5 805cf944
- 804e5a30 805de058 805cece7 805c8155 805af0d5
- 804e5a40 805e804c 805e8113 8062ea8e 8062eee7
- 804e5a50 8057f371 80650ba7 805de2ef 805e318f
- 804e5a60 805e2fa1 8058b0b6 8058aa51 806512fd
- 804e5a70 8057d4a4 806220ab 80638e89 80573bfc
- 804e5a80 8058046e 805ea252 8058270a(NtOpenProcess) 80578308
- */
- DbgPrint("WinXPx86 SSDTNumberOfService:%d\r\n",((PSYSTEM_SERVICE_TABLE)SSDTAddress)->NumberOfServices);
- if (GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWinXP_X86(szFindFunctionName,&SSDT_NtOpenProcessIndex)==FALSE)
- {
- return STATUS_UNSUCCESSFUL;
- }
- DbgPrint("WinXPx86 SSDT_NtOpenProcessIndex:%d\r\n",SSDT_NtOpenProcessIndex);
- //先保存原先的函数地址
- ServiceTableBase = (PULONG32)((PSYSTEM_SERVICE_TABLE)SSDTAddress)->ServiceTableBase;
- Old_NtOpenProcess = (pfnNtOpenProcess)(ServiceTableBase[SSDT_NtOpenProcessIndex]);
- DbgPrint("WinXPx86 Old_NtOpenProcess:%p\r\n",Old_NtOpenProcess);
- /*
- kd> u 8058270A
- nt!NtOpenProcess:
- 8058270a 68c4000000 push 0C4h
- 8058270f 68d8524f80 push offset nt!ObWatchHandles+0x25c (804f52d8)
- 80582714 e85a17f6ff call nt!_SEH_prolog (804e3e73)
- 80582719 33f6 xor esi,esi
- 8058271b 8975d4 mov dword ptr [ebp-2Ch],esi
- 8058271e 33c0 xor eax,eax
- 80582720 8d7dd8 lea edi,[ebp-28h]
- 80582723 ab stos dword ptr es:[edi]
- */
- HookSSDTWinXP_X86(ServiceTableBase,SSDT_NtOpenProcessIndex,(ULONG32)Fake_NtOpenProcess);
- #endif
- DriverObject->DriverUnload = UnloadDriver;
- return STATUS_SUCCESS;
- }
- //SSDT表的基地址32位(4Bytes)64位(8Bytes)
- //XP 32位Ntos模块导出表中有 Win7 64 Ntos模块导出表中无
- BOOLEAN GetSSDTAddressInWinXP_X86(ULONG32* SSDTAddress)
- {
- //从NtosKernel.exe 模块中的导出表获得该导出变量 KeServiceDescriptorTable
- /*
- kd> dd KeServiceDescriptorTable
- 80563520 804e58a0 00000000 0000011c 805120bc
- */
- *SSDTAddress = NULL;
- *SSDTAddress = (ULONG32)GetExportVariableAddressFormNtosExportTableByVariableName(L"KeServiceDescriptorTable");
- if (*SSDTAddress!=NULL)
- {
- return TRUE;
- }
- return FALSE;
- }
- BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWinXP_X86(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex)
- {
- /*
- 0:001> u zwopenprocess
- ntdll!ZwOpenProcess:
- 7c92d5e0 b87a000000 mov eax,7Ah
- 7c92d5e5 ba0003fe7f mov edx,offset SharedUserData!SystemCallStub (7ffe0300)
- 7c92d5ea ff12 call dword ptr [edx]
- 7c92d5ec c21000 ret 10h
- 7c92d5ef 90 nop
- */
- ULONG32 ulOffset_SSDTFunctionIndex = ;
- //从Ntdll模块的导出表中获得7c92d5e0
- //使用内存映射将Ntdll模块映射到System进程的内存空间进行查找(Ntdll.dll模块的导出表中进行搜索)
- ULONG i;
- BOOLEAN bOk = FALSE;
- WCHAR wzFileFullPath[] = L"\\SystemRoot\\System32\\ntdll.dll";
- SIZE_T MappingViewSize = ;
- PVOID MappingBaseAddress = NULL;
- PIMAGE_NT_HEADERS NtHeader = NULL;
- PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
- ULONG32* AddressOfFunctions = NULL;
- ULONG32* AddressOfNames = NULL;
- USHORT* AddressOfNameOrdinals = NULL;
- CHAR* szFunctionName = NULL;
- ULONG32 ulFunctionOrdinal = ;
- ULONG32 ulFunctionAddress = ;
- *SSDTFunctionIndex = -;
- //将Ntdll.dll 当前的空间中
- bOk = MappingPEFileInRing0Space(wzFileFullPath,&MappingBaseAddress, &MappingViewSize);
- if (bOk==FALSE)
- {
- return FALSE;
- }
- else
- {
- __try{
- NtHeader = RtlImageNtHeader(MappingBaseAddress);
- if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
- {
- ExportDirectory =(IMAGE_EXPORT_DIRECTORY*)((ULONG32)MappingBaseAddress + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
- AddressOfFunctions = (ULONG32*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfFunctions);
- AddressOfNames = (ULONG32*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfNames);
- AddressOfNameOrdinals = (USHORT*)((ULONG32)MappingBaseAddress + ExportDirectory->AddressOfNameOrdinals);
- for(i = ; i < ExportDirectory->NumberOfNames; i++)
- {
- szFunctionName = (char*)((ULONG32)MappingBaseAddress + AddressOfNames[i]); //获得函数名称
- if (_stricmp(szFunctionName, szFindFunctionName) == )
- {
- ulFunctionOrdinal = AddressOfNameOrdinals[i];
- ulFunctionAddress = (ULONG32)((ULONG32)MappingBaseAddress + AddressOfFunctions[ulFunctionOrdinal]);
- *SSDTFunctionIndex = *(ULONG32*)(ulFunctionAddress+ulOffset_SSDTFunctionIndex);
- break;
- }
- }
- }
- }__except(EXCEPTION_EXECUTE_HANDLER)
- {
- ;
- }
- }
- ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress);
- if (*SSDTFunctionIndex==-)
- {
- return FALSE;
- }
- return TRUE;
- }
- BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWin7_X64(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex)
- {
- /*
- 0:004> u zwopenprocess
- ntdll!NtOpenProcess:
- 00000000`774ddc10 4c8bd1 mov r10,rcx
- 00000000`774ddc13 b823000000 mov eax,23h
- 00000000`774ddc18 0f05 syscall
- 00000000`774ddc1a c3 ret
- 00000000`774ddc1b 0f1f440000 nop dword ptr [rax+rax]
- */
- ULONG32 ulOffset_SSDTFunctionIndex = ;
- ULONG i;
- BOOLEAN bOk = FALSE;
- WCHAR wzFileFullPath[] = L"\\SystemRoot\\System32\\ntdll.dll";
- SIZE_T MappingViewSize = ;
- PVOID MappingBaseAddress = NULL;
- PIMAGE_NT_HEADERS NtHeader = NULL;
- PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
- ULONG32* AddressOfFunctions = NULL;
- ULONG32* AddressOfNames = NULL;
- USHORT* AddressOfNameOrdinals = NULL;
- CHAR* szFunctionName = NULL;
- ULONG32 ulFunctionOrdinal = ;
- ULONG64 ulFunctionAddress = ;
- *SSDTFunctionIndex = -;
- //将Ntdll.dll 当前的空间中
- bOk = MappingPEFileInRing0Space(wzFileFullPath,&MappingBaseAddress, &MappingViewSize);
- if (bOk==FALSE)
- {
- return FALSE;
- }
- else
- {
- __try{
- NtHeader = RtlImageNtHeader(MappingBaseAddress);
- if (NtHeader && NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
- {
- ExportDirectory =(IMAGE_EXPORT_DIRECTORY*)((ULONG64)MappingBaseAddress + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
- AddressOfFunctions = (ULONG32*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfFunctions);
- AddressOfNames = (ULONG32*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfNames);
- AddressOfNameOrdinals = (USHORT*)((ULONG64)MappingBaseAddress + ExportDirectory->AddressOfNameOrdinals);
- for(i = ; i < ExportDirectory->NumberOfNames; i++)
- {
- szFunctionName = (char*)((ULONG64)MappingBaseAddress + AddressOfNames[i]); //获得函数名称
- if (_stricmp(szFunctionName, szFindFunctionName) == )
- {
- ulFunctionOrdinal = AddressOfNameOrdinals[i];
- ulFunctionAddress = (ULONG64)((ULONG64)MappingBaseAddress + AddressOfFunctions[ulFunctionOrdinal]);
- *SSDTFunctionIndex = *(ULONG32*)(ulFunctionAddress+ulOffset_SSDTFunctionIndex);
- break;
- }
- }
- }
- }__except(EXCEPTION_EXECUTE_HANDLER)
- {
- ;
- }
- }
- ZwUnmapViewOfSection(NtCurrentProcess(), MappingBaseAddress);
- if (*SSDTFunctionIndex==-)
- {
- return FALSE;
- }
- return TRUE;
- }
- BOOLEAN GetSSDTAddressInWin7_X64(ULONG64* SSDTAddress)
- {
- /*
- kd> rdmsr c0000082
- msr[c0000082] = fffff800`03ecf640
- kd> u fffff800`03ecf640 l 50
- nt!KiSystemCall64:
- fffff800`03ecf640 0f01f8 swapgs
- fffff800`03ecf643 654889242510000000 mov qword ptr gs:[10h],rsp
- fffff800`03ecf64c 65488b2425a8010000 mov rsp,qword ptr gs:[1A8h]
- fffff800`03ecf655 6a2b push 2Bh
- fffff800`03ecf657 65ff342510000000 push qword ptr gs:[10h]
- fffff800`03ecf65f 4153 push r11
- fffff800`03ecf661 6a33 push 33h
- fffff800`03ecf663 51 push rcx
- fffff800`03ecf664 498bca mov rcx,r10
- fffff800`03ecf667 4883ec08 sub rsp,8
- fffff800`03ecf66b 55 push rbp
- fffff800`03ecf66c 4881ec58010000 sub rsp,158h
- fffff800`03ecf673 488dac2480000000 lea rbp,[rsp+80h]
- fffff800`03ecf67b 48899dc0000000 mov qword ptr [rbp+0C0h],rbx
- fffff800`03ecf682 4889bdc8000000 mov qword ptr [rbp+0C8h],rdi
- fffff800`03ecf689 4889b5d0000000 mov qword ptr [rbp+0D0h],rsi
- fffff800`03ecf690 c645ab02 mov byte ptr [rbp-55h],2
- fffff800`03ecf694 65488b1c2588010000 mov rbx,qword ptr gs:[188h]
- fffff800`03ecf69d 0f0d8bd8010000 prefetchw [rbx+1D8h]
- fffff800`03ecf6a4 0fae5dac stmxcsr dword ptr [rbp-54h]
- fffff800`03ecf6a8 650fae142580010000 ldmxcsr dword ptr gs:[180h]
- fffff800`03ecf6b1 807b0300 cmp byte ptr [rbx+3],0
- fffff800`03ecf6b5 66c785800000000000 mov word ptr [rbp+80h],0
- fffff800`03ecf6be 0f848c000000 je nt!KiSystemCall64+0x110 (fffff800`03ecf750)
- fffff800`03ecf6c4 488945b0 mov qword ptr [rbp-50h],rax
- fffff800`03ecf6c8 48894db8 mov qword ptr [rbp-48h],rcx
- fffff800`03ecf6cc 488955c0 mov qword ptr [rbp-40h],rdx
- fffff800`03ecf6d0 f6430303 test byte ptr [rbx+3],3
- fffff800`03ecf6d4 4c8945c8 mov qword ptr [rbp-38h],r8
- fffff800`03ecf6d8 4c894dd0 mov qword ptr [rbp-30h],r9
- fffff800`03ecf6dc 7405 je nt!KiSystemCall64+0xa3 (fffff800`03ecf6e3)
- fffff800`03ecf6de e80d140000 call nt!KiSaveDebugRegisterState (fffff800`03ed0af0)
- fffff800`03ecf6e3 f6430380 test byte ptr [rbx+3],80h
- fffff800`03ecf6e7 7442 je nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
- fffff800`03ecf6e9 b9020100c0 mov ecx,0C0000102h
- fffff800`03ecf6ee 0f32 rdmsr
- fffff800`03ecf6f0 48c1e220 shl rdx,20h
- fffff800`03ecf6f4 480bc2 or rax,rdx
- fffff800`03ecf6f7 483983b8000000 cmp qword ptr [rbx+0B8h],rax
- fffff800`03ecf6fe 742b je nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
- fffff800`03ecf700 483983b0010000 cmp qword ptr [rbx+1B0h],rax
- fffff800`03ecf707 7422 je nt!KiSystemCall64+0xeb (fffff800`03ecf72b)
- fffff800`03ecf709 488b93b8010000 mov rdx,qword ptr [rbx+1B8h]
- fffff800`03ecf710 0fba6b4c0b bts dword ptr [rbx+4Ch],0Bh
- fffff800`03ecf715 66ff8bc4010000 dec word ptr [rbx+1C4h]
- fffff800`03ecf71c 48898280000000 mov qword ptr [rdx+80h],rax
- fffff800`03ecf723 fb sti
- fffff800`03ecf724 e8170b0000 call nt!KiUmsCallEntry (fffff800`03ed0240)
- fffff800`03ecf729 eb0f jmp nt!KiSystemCall64+0xfa (fffff800`03ecf73a)
- fffff800`03ecf72b f6430340 test byte ptr [rbx+3],40h
- fffff800`03ecf72f 7409 je nt!KiSystemCall64+0xfa (fffff800`03ecf73a)
- fffff800`03ecf731 f00fbaab0001000008 lock bts dword ptr [rbx+100h],8
- fffff800`03ecf73a 488b45b0 mov rax,qword ptr [rbp-50h]
- fffff800`03ecf73e 488b4db8 mov rcx,qword ptr [rbp-48h]
- fffff800`03ecf742 488b55c0 mov rdx,qword ptr [rbp-40h]
- fffff800`03ecf746 4c8b45c8 mov r8,qword ptr [rbp-38h]
- fffff800`03ecf74a 4c8b4dd0 mov r9,qword ptr [rbp-30h]
- fffff800`03ecf74e 6690 xchg ax,ax
- fffff800`03ecf750 fb sti
- fffff800`03ecf751 48898be0010000 mov qword ptr [rbx+1E0h],rcx
- fffff800`03ecf758 8983f8010000 mov dword ptr [rbx+1F8h],eax
- nt!KiSystemServiceStart:
- fffff800`03ecf75e 4889a3d8010000 mov qword ptr [rbx+1D8h],rsp
- fffff800`03ecf765 8bf8 mov edi,eax
- fffff800`03ecf767 c1ef07 shr edi,7
- fffff800`03ecf76a 83e720 and edi,20h
- fffff800`03ecf76d 25ff0f0000 and eax,0FFFh
- nt!KiSystemServiceRepeat:
- fffff800`03ecf772 4c8d15c7202300 lea r10,[nt!KeServiceDescriptorTable (fffff800`04101840)]
- fffff800`03ecf772 + 002320c7 + 7 = fffff800`04101840
- */
- PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082); //fffff800`03ecf640
- PUCHAR EndSearchAddress = StartSearchAddress + 0x500;
- PUCHAR i = NULL;
- UCHAR v1=,v2=,v3=;
- INT64 iOffset = ; //002320c7
- ULONG64 VariableAddress = ;
- *SSDTAddress = NULL;
- for(i=StartSearchAddress;i<EndSearchAddress;i++)
- {
- if( MmIsAddressValid(i) && MmIsAddressValid(i+) && MmIsAddressValid(i+) )
- {
- v1=*i;
- v2=*(i+);
- v3=*(i+);
- if(v1==0x4c && v2==0x8d && v3==0x15 )
- {
- memcpy(&iOffset,i+,);
- *SSDTAddress = iOffset + (ULONG64)i + ;
- break;
- }
- }
- }
- if (*SSDTAddress==NULL)
- {
- return FALSE;
- }
- /*
- kd> dq fffff800`04101840
- fffff800`04101840 fffff800`03ed1300 00000000`00000000
- fffff800`04101850 00000000`00000191 fffff800`03ed1f8c
- */
- return TRUE;
- }
- PVOID
- GetExportVariableAddressFormNtosExportTableByVariableName(WCHAR *wzVariableName)
- {
- UNICODE_STRING uniVariableName;
- PVOID VariableAddress = NULL;
- if (wzVariableName && wcslen(wzVariableName) > )
- {
- RtlInitUnicodeString(&uniVariableName, wzVariableName);
- //从Ntos模块的导出表中获得一个导出变量的地址
- VariableAddress = MmGetSystemRoutineAddress(&uniVariableName);
- }
- return VariableAddress;
- }
- VOID UnloadDriver(PDRIVER_OBJECT DriverObject)
- {
- #ifdef _WIN64
- UnHookSSDTWin7_X64(ServiceTableBase,SSDT_NtOpenProcessIndex,(ULONG32)Old_NtOpenProcessOffset);
- #else
- UnHookSSDTWinXP_X86(ServiceTableBase,SSDT_NtOpenProcessIndex,(ULONG32)Old_NtOpenProcess);
- #endif
- }
- VOID HookSSDTWin7_X64(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG64 ulFakeVariable)
- {
- //寻找一个内核不常用的函数(KeBugCheckEx) 进行InlineHook使其跳转到Fake_NtOpenProcess函数
- ULONG32 ulVariable = ;
- WPOFF();
- InlineHook(KeBugCheckEx,ulFakeVariable,szOldKeBugCheckExCode,);
- WPON();
- //寻找一个内核不常用的函数(KeBugCheckEx) 计算SSDT中的偏移 进行置换
- ulVariable = CalcFunctionOffsetInSSDT(KeBugCheckEx,);
- WPOFF();
- ServiceTableBase[ulSSDTFunctionIndex] = (ULONG32)ulVariable;
- WPON();
- }
- VOID HookSSDTWinXP_X86(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG32 ulFakeVariable)
- {
- WPOFF();
- ServiceTableBase[ulSSDTFunctionIndex] = (ULONG32)ulFakeVariable;
- WPON();
- }
- VOID
- UnHookSSDTWin7_X64(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG32 ulOldVariable)
- {
- WPOFF();
- UnInlineHook(KeBugCheckEx,szOldKeBugCheckExCode,);
- WPON();
- WPOFF();
- ServiceTableBase[ulSSDTFunctionIndex] = (ULONG32)ulOldVariable;
- WPON();
- }
- VOID
- UnHookSSDTWinXP_X86(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG32 ulOldVariable)
- {
- WPOFF();
- ServiceTableBase[ulSSDTFunctionIndex] = (ULONG32)ulOldVariable;
- WPON();
- }
- //将Ntdll.dll 模块映射到System.exe进程空间中
- BOOLEAN
- MappingPEFileInRing0Space(WCHAR* wzFileFullPath,OUT PVOID* MappingBaseAddress,PSIZE_T MappingViewSize)
- {
- UNICODE_STRING uniFileFullPath;
- OBJECT_ATTRIBUTES oa;
- NTSTATUS Status;
- IO_STATUS_BLOCK Iosb;
- HANDLE hFile = NULL;
- HANDLE hSection = NULL;
- if (!wzFileFullPath || !MappingBaseAddress){
- return FALSE;
- }
- RtlInitUnicodeString(&uniFileFullPath, wzFileFullPath);
- InitializeObjectAttributes(&oa,
- &uniFileFullPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL
- );
- //获得文件句柄
- Status = IoCreateFile(&hFile,
- GENERIC_READ | SYNCHRONIZE,
- &oa, //文件绝对路径
- &Iosb,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ,
- FILE_OPEN,
- FILE_SYNCHRONOUS_IO_NONALERT,
- NULL,
- ,
- CreateFileTypeNone,
- NULL,
- IO_NO_PARAMETER_CHECKING
- );
- if (!NT_SUCCESS(Status))
- {
- return FALSE;
- }
- oa.ObjectName = NULL;
- Status = ZwCreateSection(&hSection,
- SECTION_QUERY | SECTION_MAP_READ,
- &oa,
- NULL,
- PAGE_WRITECOPY,
- SEC_IMAGE, //?? 指示内存对齐
- hFile
- );
- ZwClose(hFile);
- if (!NT_SUCCESS(Status))
- {
- return FALSE;
- }
- Status = ZwMapViewOfSection(hSection,
- NtCurrentProcess(), //映射到当前进程的内存空间中
- MappingBaseAddress,
- ,
- ,
- ,
- MappingViewSize,
- ViewUnmap,
- ,
- PAGE_WRITECOPY
- );
- ZwClose(hSection);
- if (!NT_SUCCESS(Status))
- {
- return FALSE;
- }
- return TRUE;
- }
- VOID WPOFF()
- {
- //选择性编译,是给编译器看的
- #if (defined(_M_AMD64) || defined(_M_IA64)) && !defined(_REALLY_GET_CALLERS_CALLER_)
- _disable();
- __writecr0(__readcr0() & (~(0x10000)));
- #else
- __asm
- {
- CLI ;
- MOV EAX, CR0;
- AND EAX, NOT 10000H;
- MOV CR0, EAX;
- }
- #endif
- }
- VOID WPON()
- {
- #if (defined(_M_AMD64) || defined(_M_IA64)) && !defined(_REALLY_GET_CALLERS_CALLER_)
- __writecr0(__readcr0() ^ 0x10000);
- _enable();
- #else
- __asm
- {
- MOV EAX, CR0;
- OR EAX, 10000H;
- MOV CR0, EAX;
- STI;
- }
- #endif
- }
- NTSTATUS Fake_NtOpenProcess(
- PHANDLE ProcessHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId)
- {
- PEPROCESS EProcess = PsGetCurrentProcess(); //进程上下背景文
- if (EProcess!=NULL)
- {
- //通过EProcess 获得进程名称
- char *szProcessImageName = PsGetProcessImageFileName(EProcess);
- if (strstr(szProcessImageName,"EnumProcess")!=)
- {
- return STATUS_ACCESS_DENIED;
- }
- }
- Old_NtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
- }
- ULONG32 CalcFunctionOffsetInSSDT(ULONG64 ulFunctionAddress,ULONG32 ulParamCount)
- {
- /*
- kd> rdmsr c0000082
- msr[c0000082] = fffff800`03edd640
- kd>u fffff800`03edd640
- fffff800`03edd751 48898be0010000 mov qword ptr [rbx+1E0h],rcx
- fffff800`03edd758 8983f8010000 mov dword ptr [rbx+1F8h],eax
- nt!KiSystemServiceStart:
- fffff800`03edd75e 4889a3d8010000 mov qword ptr [rbx+1D8h],rsp
- fffff800`03edd765 8bf8 mov edi,eax
- fffff800`03edd767 c1ef07 shr edi,7
- fffff800`03edd76a 83e720 and edi,20h
- fffff800`03edd76d 25ff0f0000 and eax,0FFFh
- nt!KiSystemServiceRepeat:
- fffff800`03edd772 4c8d15c7202300 lea r10,[nt!KeServiceDescriptorTable (fffff800`0410f840)]
- kd> dq fffff800`0410f840
- fffff800`0410f840 fffff800`03edf300 00000000`00000000
- fffff800`0410f850 00000000`00000191 fffff800`03edff8c
- fffff800`0410f860 00000000`00000000 00000000`00000000
- fffff800`0410f870 00000000`00000000 00000000`00000000
- kd> dd fffff800`03edf300
- fffff800`03edf300 040d9a00 02f55c00 fff6ea00 02e87805
- fffff800`03edf310 031a4a06 03116a05 02bb9901 02b4f200
- fffff800`03edf300 + (02e87805>>4) = FFFFF800041C7A80
- kd> u FFFFF800041C7A80
- nt!NtReadFile:
- fffff800`041c7a80 4c8bdc mov r11,rsp
- fffff800`041c7a83 4d894b20 mov qword ptr [r11+20h],r9
- fffff800`041c7a87 4d894318 mov qword ptr [r11+18h],r8
- fffff800`041c7a8b 49895310 mov qword ptr [r11+10h],rdx
- fffff800`041c7a8f 53 push rbx
- 5 --->9
- 6 --->10
- 如果一个函数的参数个数小于等于4 就是0
- */
- ULONG32 ulVariable = ,i;
- CHAR v1 = ;
- CHAR szBits[] = {};
- ulVariable = (ULONG32)(ulFunctionAddress-(ULONG64)ServiceTableBase);
- ulVariable = ulVariable<<;
- if(ulParamCount>)
- {
- ulParamCount = ulParamCount-; //NtReadFile 9个参数
- }
- else
- {
- ulParamCount = ;
- }
- //处理低四位,填写参数个数 如果一个函数的参数为5 那么dwTemp的低4位就是 0001 如果参数是6 就是0002 因为 6要减4
- #define SETBIT(x,y) x|=(1<<y) //将X的第Y位置1
- #define CLRBIT(x,y) x&=~(1<<y) //将X的第Y位清0
- #define GETBIT(x,y) (x & (1 << y)) //取X的第Y位,返回0或非0
- for(i=;i<;i++) //一个16进制 4个二进制 0000
- {
- szBits[i]=GETBIT(ulParamCount,i);
- if(szBits[i])
- {
- SETBIT(v1,i);
- }
- else
- {
- CLRBIT(v1,i);
- }
- }
- /*
- ulParamCount i szBits[i] b i b
- 0101 0 1 0000 0 0001 set
- 0101 1 0 0001 1 0001 clr
- 0101 2 1 0001 2 0101 set
- 0101 3 0 0101 3 0101 clr
- */
- //把数据复制回去
- memcpy(&ulVariable,&v1,);
- return ulVariable;
- }
- VOID InlineHook(ULONG64 ulOldVariable,ULONG64 ulFakeVariable,UCHAR* szOldCode,ULONG32 ulOldeCodeLength)
- {
- ULONG64 ulVariable = ;
- UCHAR szNewCode[]="\xFF\x25\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; //InlineHook
- ulVariable = ulFakeVariable;
- memcpy(szOldCode,(PVOID)ulOldVariable,ulOldeCodeLength);
- memcpy(szNewCode+,&ulVariable,);
- memset((PVOID)ulOldVariable,0x90,ulOldeCodeLength);
- memcpy((PVOID)ulOldVariable,szNewCode,);
- }
- VOID UnInlineHook(ULONG64 ulOldVariable,UCHAR* szOldCode,ULONG32 ulOldCodeLength)
- {
- memcpy((PVOID)ulOldVariable,szOldCode,ulOldCodeLength);
- }
.c
- #ifndef CXX_HOOKSSDT_H
- #define CXX_HOOKSSDT_H
- #include <ntifs.h>
- #include <ntimage.h>
- #define SEC_IMAGE 0x01000000
- //定义SSDT表的结构
- typedef struct _SYSTEM_SERVICE_TABLE_X64{
- PVOID ServiceTableBase;
- PVOID ServiceCounterTableBase;
- ULONG64 NumberOfServices; //SSDT表中的函数个数 0x191
- PVOID ParamTableBase;
- } SYSTEM_SERVICE_TABLE_X64, *PSYSTEM_SERVICE_TABLE_X64;
- typedef struct _SYSTEM_SERVICE_TABLE_X86 {
- PVOID ServiceTableBase;
- PVOID ServiceCounterTableBase;
- ULONG32 NumberOfServices; //SSDT表中的函数个数 0x11c
- PVOID ParamTableBase;
- } SYSTEM_SERVICE_TABLE_X86, *PSYSTEM_SERVICE_TABLE_X86;
- #ifdef _WIN64
- #define PSYSTEM_SERVICE_TABLE PSYSTEM_SERVICE_TABLE_X64
- #else
- #define PSYSTEM_SERVICE_TABLE PSYSTEM_SERVICE_TABLE_X86
- #endif
- /*
- ServiceTableBase [][][][][][][][]
- */
- extern
- char* PsGetProcessImageFileName(PEPROCESS EProcess);
- extern
- PIMAGE_NT_HEADERS
- NTAPI
- RtlImageNtHeader(PVOID BaseAddress);
- typedef
- NTSTATUS
- (*pfnNtOpenProcess)(
- PHANDLE ProcessHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId);
- NTSTATUS Fake_NtOpenProcess(
- PHANDLE ProcessHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId);
- VOID UnloadDriver(PDRIVER_OBJECT DriverObject);
- BOOLEAN GetSSDTAddressInWinXP_X86(ULONG32* SSDTAddress);
- BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWinXP_X86(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex);
- BOOLEAN GetSSDTAddressInWin7_X64(ULONG64* SSDTAddress);
- BOOLEAN GetSSDTFunctionIndexFromNtdllExportTableByFunctionNameInWin7_X64(CHAR* szFindFunctionName,ULONG32* SSDTFunctionIndex);
- ULONG32 CalcFunctionOffsetInSSDT(ULONG64 ulFunctionAddress,ULONG32 ulParamCount);
- VOID InlineHook(ULONG64 ulOldVariable,ULONG64 ulFakeVariable,UCHAR* szOldCode,ULONG32 ulOldeCodeLength);
- VOID UnInlineHook(ULONG64 ulOldVariable,UCHAR* szOldCode,ULONG32 ulOldCodeLength);
- PVOID GetExportVariableAddressFormNtosExportTableByVariableName(WCHAR *wzVariableName);
- BOOLEAN MappingPEFileInRing0Space(WCHAR* wzFileFullPath,OUT PVOID* MappingBaseAddress,PSIZE_T MappingViewSize);
- VOID WPOFF();
- VOID WPON();
- VOID HookSSDTWinXP_X86(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG32 ulFakeVariable);
- VOID HookSSDTWin7_X64(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG64 ulFakeVariable);
- VOID UnHookSSDTWinXP_X86(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG32 ulOldVariable);
- VOID UnHookSSDTWin7_X64(PULONG32 ServiceTableBase,ULONG32 ulSSDTFunctionIndex,ULONG32 ulOldVariable);
- #endif
.h
HookSSDT 通过HookOpenProcess函数阻止暴力枚举进程的更多相关文章
- 教你用免费的hihttps开源WEB应用防火墙阻止暴力破解密码
教你用免费的hihttps开源WEB应用防火墙阻止暴力破解密码 很多企业都有自己的网站,需要用户登录后才能访问,但有大量的黑客攻击软件可以暴力破解网站密码,即使破解不了也非常恶心.有没有免费的解决办法 ...
- ZwQueryVirtualMemory暴力枚举进程模块
0x01 前言 同学问过我进程体中EPROCESS的三条链断了怎么枚举模块,这也是也腾讯面试题.我当时听到也是懵逼的. 后来在网上看到了一些内存暴力枚举的方法ZwQueryVirtualMemory. ...
- ring0 暴力枚举进程
原理:遍历进程ID,然后openprocess,能打开的都枚举出来 ring0 : #include "EnumProcessByForce.h" extern char* PsG ...
- addevent兼容函数 && 阻止默认行为 && 阻止传播
function addEvent(a, b, c, d) { a.addEventListener ? a.addEventListener(b, c, d) : a.attachEvent(&qu ...
- Fail2ban 阻止暴力破解
简介: Fail2ban 能够监控系统日志,匹配日志中的错误信息(使用正则表达式),执行相应的屏蔽动作(支持多种,一般为调用 iptables ),是一款很实用.强大的软件. 如:攻击者不断尝试穷举 ...
- DVWA Brute Force:暴力破解篇
DVWA Brute Force:暴力破解篇 前言 暴力破解是破解用户名密码的常用手段,主要是利用信息搜集得到有用信息来构造有针对性的弱口令字典,对网站进行爆破,以获取到用户的账号信息,有可能利用其权 ...
- 增强VPS SSH账号安全:改端口,禁用Root,密钥登录,Denyhosts防暴力攻击
VPS SSH账号是我们日常管理VPS的主要登入方式,尤其是Root账号,对Linux系统安全至关重要.以前好多站长喜欢用Putty中文版,这实际是别人修改官方Putty汉化而来,这些软件被植入了后门 ...
- gohook 一个支持运行时替换 golang 函数的库实现
运行时替换函数对 golang 这类静态语言来说并不是件容易的事情,语言层面的不支持导致只能从机器码层面做些奇怪 hack,往往艰难,但如能成功,那挣脱牢笼带来的成就感,想想就让人兴奋. gohook ...
- Nowcoder 挑战赛23 B 游戏 ( NIM博弈、SG函数打表 )
题目链接 题意 : 中文题.点链接 分析 : 前置技能是 SG 函数.NIM博弈变形 每次可取石子是约数的情况下.那么就要打出 SG 函数 才可以去通过异或操作判断一个局面的胜负 打 SG 函数的时候 ...
随机推荐
- 表单美化-原生javascript和jQuery下拉列表(兼容IE6)
效果: 思想:用其他标签配合脚本和隐藏的input并通过传值模拟表单元素中的select <!DOCTYPE HTML> <html lang="en-US"&g ...
- 常用sql(转)
1增 1.1[插入单行]insert [into] <表名> (列名) values (列值)例:insert into Strdents (姓名,性别,出生日期) values ('开心 ...
- Switch用法
package com.cz.test; public class SwitchExample1 { /** * @param args */ public static void main(Stri ...
- js输出26个字母两种方法(js fromCharCode的使用)
方法一 var character = new Array("A","B","C","D","E", ...
- ajax 、ajax的交互模型、如何解决跨域问题
1.ajax是什么? — AJAX全称为“AsynchronousJavaScript and XML”(异步JavaScript和XML),是一种创建交互式网页应用的网页开发技术. — 不是一种新技 ...
- js获取select字段值的方法
var index = obj.selectedIndex; // 选中索引 var value = obj.options[index].value; // 选中值 var schoolName = ...
- Python学习(16)File(文件)方法
Python File(文件) 方法 file 对象使用 open 函数来创建,下表列出了 file 对象常用的函数: 序号 方法及描述 1 file.close() 关闭文件.关闭后文件不能再进行读 ...
- Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
Android 高手进阶(21) 版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请注明出处:http://blog.csdn.net/xiaanming/article/detail ...
- python语法笔记(一)
1. python中多个函数或者类定义可以放在一个.py 文件中,视为一个模块.模块的.py文件中,一般要写 if __name__ == '__mian__' 用来单独执行该模块内的某些函数. 2. ...
- OpenCV3编程入门笔记(6)自我验证各函数程序代码
// asw.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <opencv2/opencv.hpp> usi ...