今天闲来无事,打开任务管理器,想结束360的进程,怎料只听噔的一声,弹出一对话框,提示无法结束该进程...
为啥结束不了它的进程呢?我便有了一探究竟的想法。研究了半天,发现原来是360 hook了KiFastCallEntry这个函数。我打开XueTr,恢复了这个inline hook,可怎想一刷新还有这个hook ,我想一定是360通过什么方法来检测hook是否被还原。不管它,先进入他跳转的地址看看。进来一看又是一个跳转,再跟进才是它真正的过滤函数。我想让第二个跳转跳转到中转函数,然后再跳到原来地址加5的地方继续执行,应该可以恢复了这个hook。
我郁闷,不会插图片,蛋疼了...
开始想用MmGetSystemRoutineAddress直接得到这个函数的地址,可这个函数是个未导出函数,由于本人很菜,没别的办法,我只会通过这个特征码搜索这个函数的地址,那么看代码吧。 #include "Driver.h"
#define SystemModuleInformation 11 ULONG Address;
extern "C" NTSTATUS NTAPI ZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength
); typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY {
HANDLE Section;
PVOID MappedBase;
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT PathLength;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY; typedef struct _SYSTEM_MODULE_INFORMATION {
ULONG Count;
SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; ULONG getAddress(ULONG ntosknlBase,ULONG ntosknlEndAddr)//根据特征码搜出被HOOK的地址
{
ULONG code1_sp2=0x01244c80,code2_sp2=0xff1b6a02,code3_sp2=0xdf030435,code4_sp2=0x55006aff,i;
for(i=ntosknlBase;i<=ntosknlEndAddr;i++)
{
if(*(PULONG)i==code1_sp2 && (*(PULONG)(i+4))==code2_sp2 && (*(PULONG)(i+8))==code3_sp2 && (*(PULONG)(i+12))==code4_sp2)
{
return i-0x20;
}
} } _declspec(naked) myFunction() //中转函数,跳到被hook的地址加5的地方继续执行
{
ULONG jmpAddress;
jmpAddress=Address+5;
_asm
{
sub esp,ecx
shr ecx,2
jmp jmpAddress
}
} void hooking(ULONG jmpCode,ULONG Address2) //hook函数,把第二个跳转地址改成中转函数的地址
{
KIRQL oldIRQL;
UCHAR Jmp[5] = {0xE9,0,0,0,0};
*(ULONG *)(Jmp+1)=jmpCode; oldIRQL=KeRaiseIrqlToDpcLevel();
_asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
RtlCopyMemory((PUCHAR)Address2,Jmp,5); _asm
{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
KeLowerIrql(oldIRQL);
DbgPrint("hook successfule\n");
return;
} ULONG GetUndocumentFunctionAddress() \\根据特征码,搜索出KiFastCallEntry的地址
{
ULONG i,Modcnt=0;
ULONG size,index;
PULONG buf;
PSYSTEM_MODULE_INFORMATION module;
PSYSTEM_MODULE_INFORMATION_ENTRY pSysModuleInfo,pModInfo;
ULONG ntosknlBase;
ULONG ntosknlEndAddr;
ULONG funAddr;
NTSTATUS status;
ZwQuerySystemInformation(SystemModuleInformation,&size,0,&size);
if(NULL==(buf=(PULONG)ExAllocatePool(PagedPool,size)))
{
DbgPrint("failed alloc memerry\n");
return 0;
}
status=ZwQuerySystemInformation(SystemModuleInformation,buf,size,0);
if(!NT_SUCCESS(status))
{
DbgPrint("failed query\n");
return 0;
}
pSysModuleInfo=(PSYSTEM_MODULE_INFORMATION_ENTRY)((PULONG)buf+1);
DbgPrint("%d\t0x%08X 0x%08X %s\n",pSysModuleInfo->LoadOrderIndex,pSysModuleInfo->Base,pSysModuleInfo->Size,pSysModuleInfo->ImageName);
ntosknlBase = (ULONG)pSysModuleInfo->Base;
ntosknlEndAddr = pSysModuleInfo->Size+ntosknlBase;
funAddr=getAddress(ntosknlBase,ntosknlEndAddr);
for(i=funAddr;i<funAddr+0x200;i++)
{
if((*(PULONG)(i-4)==0x1c8b3f8b) && (*(PULONG)(i-8)==0x180c8ac9))
{
DbgPrint("the hook Address is %x\n",i+1);
return i+1;
} }
} void unhook(ULONG Address)
{
ULONG Address2,Address3,jmpCode;
if((UCHAR)(*(PULONG)Address)==0xe9)//如果被hook了则执行下面代码
{
DbgPrint("the function bei hook\n");
Address2=*(PULONG)(Address+1)+Address+5;
DbgPrint("the jump Address is %x\n",Address2);
jmpCode=(ULONG)myFunction-Address2-5;
DbgPrint("the jmpCode is %x\n",jmpCode);
hooking(jmpCode,Address2);
}
else //没有被HOOK打出下面一句话
{
DbgPrint("no hook\n");
} }
//主函数
#pragma INITCODE
extern "C" NTSTATUS DriverEntry (
IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath )
{
DbgPrint("Enter DriverEntry\n");
Address=GetUndocumentFunctionAddress();
unhook(Address);
DbgPrint("leave DriverEntry\n");
return STATUS_SUCCESS;
} #pragma PAGEDCODE
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject)
{
DbgPrint("leave unload!!!\n");
} 编译运行后,果然在任务管理器里能结束360的进程了,达到了预期的效果,没有技术含量,大牛们别笑话。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!