首页
社区
课程
招聘
[原创]恢复KiFastCallEntry的hook,用任务管理器结束360
发表于: 2011-6-26 09:18 14796

[原创]恢复KiFastCallEntry的hook,用任务管理器结束360

2011-6-26 09:18
14796

今天闲来无事,打开任务管理器,想结束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的进程了,达到了预期的效果,没有技术含量,大牛们别笑话。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (19)
雪    币: 656
活跃值: (448)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
2
虽然早就有类似的文章了,不过还是顶一下!
2011-6-26 09:27
0
雪    币: 492
活跃值: (53)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
3
进不了ring0,一切都是白搭啊。。。
2011-6-26 09:36
0
雪    币: 1040
活跃值: (1293)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
进了R0还原了HOOK然后再用任务管理器杀……亮点……
2011-6-26 09:46
0
雪    币: 72
活跃值: (52)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
蛋疼之举,只是练练手而已。。。
2011-6-26 09:47
0
雪    币: 601
活跃值: (256)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
6
顶一下,厉害了
2011-6-26 10:00
0
雪    币: 143
活跃值: (61)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
7
原来如此…了解了。
2011-6-26 10:47
0
雪    币: 90
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
你在什么环境编译的
2011-6-26 10:56
0
雪    币: 72
活跃值: (52)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
9
WDK呗,还有个头文件Driver.h

#pragma once

#ifdef __cplusplus
extern "C"
{
#endif
#include <NTDDK.h>
#ifdef __cplusplus
}
#endif

#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")

#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA data_seg("INIT")

VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);
2011-6-26 11:02
0
雪    币: 228
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
10
果然十分有亮点.....

话说KiFastCallEntry是可以直接获得地址的.
2011-6-26 11:10
0
雪    币: 72
活跃值: (52)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
11
唉。。没办法 菜鸟嘛没办法才去搜特征码的,楼上还请指点指点怎么直接获取啊
2011-6-26 11:13
0
雪    币: 270
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
顶一个,学习学习
2011-6-26 11:14
0
雪    币: 220
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
有两点,可以看看
2011-6-26 11:48
0
雪    币: 1149
活跃值: (888)
能力值: ( LV13,RANK:260 )
在线值:
发帖
回帖
粉丝
14
原创 就顶.....努力分享 就值得顶.....
2011-6-26 12:29
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
15
顶一下,人家玩玩而以,想进Ring0干啥
2011-6-26 12:32
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
16
很多人等着干坏事的代码呢
2011-6-26 12:33
0
雪    币: 27
活跃值: (127)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
17
支持楼主的研究精神
2011-6-26 14:40
0
雪    币: 233
活跃值: (285)
能力值: ( LV12,RANK:270 )
在线值:
发帖
回帖
粉丝
18
DbgPrint("the function bei hook\n");
这句写得很亮啊~~~

定位KiFastCallEntry函数的话,可以看看360的hookport.sys是怎么做的,网上也有分析的文章。

也可以通过MSR寄存器获取KiFastCallEntry的地址,不过不太可靠~~~
2011-6-26 15:10
0
雪    币: 72
活跃值: (52)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
19
丢人了。。英语水平那个差啊,明天的英语考试正发愁那...
2011-6-26 15:27
0
雪    币: 2314
活跃值: (2205)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
20
你进了R0, 360就不防你了.
2011-6-26 16:07
0
游客
登录 | 注册 方可回帖
返回
//