首先要知道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