能力值:
( LV3,RANK:20 )
|
-
-
2 楼
DWORD KeStackAttachProcess_5d,NtOpenProcessAddr_21e,NtOpenThread_214;
DWORD ObOpenObjectByPointeraddr,KiAttachProcessaddr;
DWORD Real_NtReadVirtualMemory_7,Real_NtWriteVirtualMemory_7;
DWORD readpush,writepush;
DWORD SSDTAddr;
DWORD oldReadvirtualMemoryAddr,oldWritevirtualMemoryAddr,oldKeAttachProcess;
/************************************************************************
* 函数名称:My_KeStackAttachProcess
* 功能描述:对TP Hook住的KeStackAttachProcess中的KiAttachProcess进行修复
* 参数列表:无
* 返回 值:无
* 修改必要:否
*************************************************************************/
#pragma PAGEDCODE
__declspec(naked)VOID My_KeStackAttachProcess()
{
//KdPrint(("My_KeStackAttachProcess\n"));
__asm
{
//还原jmp占用处指令字节指令KeStackAttachProcess+5d
push dword ptr [ebp+0ch]
push dword ptr [ebp+8]
push edi
push esi
//计算返回地址KeStackAttachProcess+0x5d+d==返回地址
mov eax,KeStackAttachProcess_5d
add eax,0xd
push eax //压入返回地址
//KiAttachProcess 前7字节,TP的校验这里~~~
mov edi,edi
push ebp
mov ebp,esp
push ebx
push esi
//jmp至KiAttachProcess+7处执行,然后返回KeStackAttachProcess+0x5d+d处继续执行
mov eax, KiAttachProcessaddr
add eax,7
jmp eax //跳到了KiAttachProcess+7位置
}
}
/************************************************************************
* 函数名称:My_KeAttachProcess
* 功能描述:对TP Hook住的KeAttachProcess中的KiAttachProcess进行修复
* 参数列表:无
* 返回 值:无
* 修改必要:否
*************************************************************************/
#pragma PAGEDCODE
__declspec(naked)VOID My_KeAttachProcess()
{
//KdPrint(("My_KeAttachProcess\n"));
__asm
{
//还原jmp占用处指令字节指令KeAttachProcess+0x3c
push dword ptr [ebp+8]
push edi
push esi
//call KiAttachProcess
push endCall //压栈返回地址,跳到标号处
//KiAttachProcess 前7字节,TP的校验这里~~~
mov edi,edi
push ebp
mov ebp,esp
push ebx
push esi
//jmp至KiAttachProcess+7处执行,然后返回KeAttachProcess+0x3c+d处继续执行
mov eax,KiAttachProcessaddr
add eax,7
jmp eax //跳到了KiAttachProcess+7位置
endCall:
pop edi
pop esi
pop ebp
ret 4
}
}
/************************************************************************
* 函数名称:My_NtReadVirtualMemory
* 功能描述:对TP Hook住的NtReadVirtualMemory前2句进行修复
* 参数列表:无
* 返回 值:无
* 修改必要:否
*************************************************************************/
#pragma PAGEDCODE
__declspec(naked) VOID My_NtReadVirtualMemory()
{
//KdPrint(("My_NtReadVirtualMemory\n"));
__asm
{
//恢复前2条指令
push 0x1c
push readpush //压栈参数
jmp Real_NtReadVirtualMemory_7
}
}
/************************************************************************
* 函数名称:My_NtWriteVirtualMemory
* 功能描述:对TP Hook住的NtWriteVirtualMemory前2句进行修复
* 参数列表:无
* 返回 值:无
* 修改必要:否
*************************************************************************/
#pragma PAGEDCODE
__declspec(naked)VOID My_NtWriteVirtualMemory()
{
//KdPrint(("My_NtWriteVirtualMemory\n"));
__asm
{
push 0x1c
push writepush //压栈参数
jmp Real_NtWriteVirtualMemory_7
}
}
/************************************************************************
* 函数名称:My_OpenProcess
* 功能描述:对TP Hook住的NtOpenProcess+0x224进行修复
* 参数列表:无
* 返回 值:无
* 修改必要:否
*************************************************************************/
#pragma PAGEDCODE
__declspec(naked)VOID My_NtOpenProcess()
{
//KdPrint(("My_OpenProcess\n"));
__asm
{
//还原jmp占用处指令字节指令NtOpenProcess+0x21e
push dword ptr [ebp-38h]
push dword ptr [ebp-24h]
//计算返回地址NtOpenProcess+0x21e+b
mov eax,NtOpenProcessAddr_21e
add eax,0bh
push eax //压入返回地址
jmp ObOpenObjectByPointeraddr
}
}
/************************************************************************
* 函数名称:My_OpenTread
* 功能描述:对TP Hook住的NtOpenTread+0x21A进行修复
* 参数列表:无
* 返回 值:无
* 修改必要:否
*************************************************************************/
#pragma PAGEDCODE
__declspec(naked)VOID My_NtOpenTread()
{
//KdPrint(("My_OpenTread\n"));
__asm
{
//还原jmp占用处指令字节指令NtOpenThread+0x214
push dword ptr [ebp-34h]
push dword ptr [ebp-20h]
//计算返回地址NtOpenProcess+0x214+b
mov eax,NtOpenThread_214
add eax,0bh
push eax //压入返回地址
jmp ObOpenObjectByPointeraddr
}
}
/************************************************************************
* 函数名称:Findcodeaddr
* 功能描述:根据特征码寻找要跳转地址
* 参数列表:code1
code2
prcaddr获得函数地址函数导出函数地址
* 返回 值:无
* 修改必要:否
*************************************************************************/
#pragma PAGEDCODE
__declspec(naked) DWORD __stdcall Findcodeaddr(DWORD code1,WORD code2,DWORD prcaddr)
{
__asm
{
//遍历代码
mov edx,[esp+0x0c] //导出函数地址
mov ecx,1000h //4096个字节左右
//while(ecx>0)
start:
sub ecx,1h //循环次数减
add edx,1h //地址加1
mov ebx,dword ptr [edx] //取出地址中的内容
xor eax,eax //eax清零
mov ax,word ptr [edx+4h] //传入4字节0000:总体思想:+1查后4
test ecx,ecx //循环完了
jz end
cmp ebx,[esp+4] //code1
jnz start
cmp ax,[esp+8] //code2
jnz start
end:
mov eax,edx //返回特征码的地址
ret 0x0c
}
}
/************************************************************************
* 函数名称:PassTPhook
* 功能描述:用SSDTHook对抗TP的InLineHook
* 参数列表:无
* 返回 值:无
* 修改必要:否
*************************************************************************/
#pragma PAGEDCODE
VOID PassTPhook()
{
UNICODE_STRING g_ProcessAddr,g_ThreadAddr;
UNICODE_STRING g_KeAttachAddr,g_PointerAddr,g_KeStackAttachProcess;
RtlInitUnicodeString(&g_ProcessAddr,L"NtOpenProcess");
RtlInitUnicodeString(&g_ThreadAddr,L"NtOpenThread");
RtlInitUnicodeString(&g_PointerAddr,L"ObOpenObjectByPointer");
RtlInitUnicodeString(&g_KeAttachAddr,L"KeAttachProcess");
RtlInitUnicodeString(&g_KeStackAttachProcess,L"KeStackAttachProcess");
__asm
{
//Hook KeStackAttachProcess
lea eax,g_KeStackAttachProcess //传入字符串地址
push eax
call DWORD ptr DS:[ MmGetSystemRoutineAddress] //调用MmGetSystemRoutineAddress
push eax //将返回的函数地址压栈(参数3)
push 0875h //修改当句特征码(参数2)
push 0FF0C75FFh //前一句特征码(参数1)
call Findcodeaddr
mov KeStackAttachProcess_5d,eax //此时eax已经是偏移了
//Hooked
lea ebx,My_KeStackAttachProcess
sub ebx,eax
sub ebx,5
mov BYTE ptr [eax],0E9h
mov dword ptr [eax+1],ebx
//Hook NtOpenProcess
lea eax,g_ProcessAddr
push eax
call DWORD ptr DS:[ MmGetSystemRoutineAddress]
push eax //传入 NtOpenProcess地址
push 0dc75h
push 0ffc875ffh
call Findcodeaddr
mov NtOpenProcessAddr_21e,eax
//Hook NtOpenThread
lea eax, g_ThreadAddr
push eax
call DWORD ptr DS:[ MmGetSystemRoutineAddress]
push eax ////传入 NtOpenThread地址
push 0e075h
push 0ffcc75ffh
call Findcodeaddr
mov NtOpenThread_214,eax //////存放 NtOpenThread 里 CALL ObOpenObjectByPointer的地址
//不需要Hook
lea eax,g_PointerAddr
push eax
call DWORD ptr DS:[ MmGetSystemRoutineAddress]
mov ObOpenObjectByPointeraddr,eax //存放 ObOpenObjectByPointer地址
//Hook KeAttachProcess就间接Hook了KiAttachProcess
lea eax,g_KeAttachAddr
push eax
call DWORD ptr DS:[ MmGetSystemRoutineAddress]
push eax // 传入KeAttachProcess
push 0e856h
push 570875ffh //是这句push dword ptr [ebp+8]
call Findcodeaddr //查找KiAttachProcess地址
mov oldKeAttachProcess,eax
add eax,6h //指向 804f9b64// 804f9b63 e890feffff call nt!KiAttachProcess (804f99f8)
mov ebx,dword ptr [eax] //取CALL 地址
add ebx,eax //当前地址+取出地址+4
add ebx,4h
/*取出地址=要跳转地址-当前地址-5
要跳转地址=取出地址+当前+5
1804F9A09=fffffe90+804f9b74+5(举例)
应该是804f9a08
前面的1会舍去,后面多的1是因为不是jmp,所以用4字节
(要跳转地址=取出地址+当前+4)正确公式
*/
mov KiAttachProcessaddr,ebx //计算出 KiAttachProcess 这个未导出函数地址
sub eax,6h //再次回到特征码处,与上面的add eax,6h遥相呼应
//Hooked
mov dword ptr[eax],0xE9 //jmp
lea ebx,My_KeAttachProcess //Hook了KeStackAttachProcess就间接Hook了KiAttachProcess
sub ebx,eax
sub ebx,5
mov dword ptr[eax+1],ebx
//取得readpush地址,然后Hook NtReadVirtualMemory
mov eax, KeServiceDescriptorTable
mov eax,[eax] //address of KeServiceDescriptorTable
mov SSDTAddr,eax
//取得NtReadVirtualMemory
mov eax,SSDTAddr
add eax,2e8h
mov eax,DWORD PTR [eax] //0xBA * 4 NtReadVirtualMemory ssdt186
//保存原地址
mov oldReadvirtualMemoryAddr,eax
//取得[eax]中push 第二句地址
mov oldReadvirtualMemoryAddr,eax
mov ebx,DWORD PTR [eax+3h]
mov readpush,ebx
add eax,7h
mov Real_NtReadVirtualMemory_7,eax
//取得NtReadVirtualMemory
mov eax,SSDTAddr
add eax,454h
mov eax,DWORD ptr[eax] //0x115 * 4 NtWriteVirtualMemory ssdt227
//保存原地址
mov oldWritevirtualMemoryAddr,eax
//取得[eax]中push 第二句地址
mov ebx,DWORD ptr [eax+3h]
mov writepush,ebx
add eax,7h
mov Real_NtWriteVirtualMemory_7,eax
//开中断
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
//SSDT Hooked
mov ebx,SSDTAddr
mov eax,My_NtReadVirtualMemory
mov DWORD ptr [ebx+2e8h],eax
//SSDT Hooked
mov eax,My_NtWriteVirtualMemory
mov DWORD ptr [ebx+454h],eax
//Inline Hooked
mov ebx,NtOpenProcessAddr_21e
mov BYTE ptr[ebx],0e9h
mov eax,offset My_NtOpenProcess //作用相等
lea eax,My_NtOpenProcess //
sub eax,ebx
sub eax,5h
mov DWORD ptr [ebx+1h],eax
//Inline Hooked
mov ebx,NtOpenThread_214
mov BYTE ptr [ebx],0e9h
mov eax,offset My_NtOpenTread
sub eax,ebx
sub eax,5h //计算跳转地址
mov DWORD ptr [ebx+1h],eax //紧接着 E9后边写 跳转地址
//关中断
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}
/************************************************************************
* 函数名称:UnPassTPhook
* 功能描述:卸载自己的驱动,还原代码,防止蓝屏
* 参数列表:无
* 返回 值:无
* 修改必要:否
*************************************************************************/
VOID UnPassTPhook()
{
__asm
{
pushad
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
mov eax,SSDTAddr
mov ebx,oldReadvirtualMemoryAddr
mov DWORD ptr [eax+0x2e8],ebx
mov ebx,oldWritevirtualMemoryAddr
mov DWORD ptr [eax+454h],ebx
mov eax,KeStackAttachProcess_5d
mov DWORD ptr [eax],0FF0C75FFh
mov WORD ptr [eax+4h],0875h
mov eax,oldKeAttachProcess
mov DWORD ptr [eax],570875ffh
mov WORD ptr [eax+4h],0e856h
mov eax,NtOpenProcessAddr_21e
mov DWORD ptr [eax],0ffc875ffh
mov WORD ptr [eax+4h],0dc75h
mov eax,NtOpenThread_214
mov DWORD PTR [eax],0ffcc75ffh
mov WORD ptr [eax+4h],0e075h
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
popad
}
}
|