首页
社区
课程
招聘
[求助]一个关于inline hook问题,哪位兄弟进来帮个忙看看,没有代码的!!!
发表于: 2008-12-24 22:37 5161

[求助]一个关于inline hook问题,哪位兄弟进来帮个忙看看,没有代码的!!!

2008-12-24 22:37
5161
我想保护我的进程被其它程序非法关闭,现在我inline hook了NtTerminateProcess这个函数,
我的做法是:
1.我申请了一个非分页内存,把我的过滤代码写在了里面
2.保存了NtTerminateProcess函数开头5个字节,并把JMP指令写在了函数开头,这个JMP指令是跳到我申请的内存里(也就是我的过滤函数),在Ring3下获得的被保护进程的句柄已经传给过滤函数了
我想问的是:如果有程序调用NtTerminateProcess并且发现关闭的是被保护的进程,该怎样过滤呢??是把该函数的第一个参数设置为0或者其他数值,还是直接返回呢????或者是其他的什么操作??

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

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 581
活跃值: (149)
能力值: ( LV12,RANK:600 )
在线值:
发帖
回帖
粉丝
2
帖段以前的东东...有点烂...你自己再改改..效果比NtTerminateProcess好..注意多处理器....
#define STARTHOOK 1
#define UNHOOK  0

extern POBJECT_TYPE *PsProcessType;
char* ProtectName = "notepad.exe";

//原始函数的正确功能,没有返回状态
__declspec(naked) OldObReferenceObjectByHandle(
    IN HANDLE Handle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_TYPE ObjectType OPTIONAL,
    IN KPROCESSOR_MODE AccessMode,
    OUT PVOID *Object,
    OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL
    )
{
           _asm
{

   mov     edi,edi //-------->>>>执行被修改的前几个字节
   push    ebp
   mov     ebp,esp

   push   [ebp+0x1c] //------->>>参数压栈以便正确调用函数
   push   [ebp+0x18]
   push   [ebp+0x14]
   push   [ebp+0x10]
   push   [ebp+0xc]
   push   [ebp+8]

   mov   eax,ObReferenceObjectByHandle//------>>>>跳到ObReferenceObjectByHandle正常执行      
   add   eax,5            
   jmp   eax
   
}

}

//功能函数,完成过滤操作
ULONG FilterFunction(
    IN HANDLE Handle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_TYPE ObjectType OPTIONAL,
    IN KPROCESSOR_MODE AccessMode,
    OUT PVOID *Object,
    OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL
    )
{
        PEPROCESS Process;
        __try{
    if(*PsProcessType==ObjectType)//判断句柄所属对象类型是不是*PsProcessType
        {
                OldObReferenceObjectByHandle(Handle,DesiredAccess,ObjectType,AccessMode,&Process,NULL);
                //截获传递进来的参数,修改参数,调用原来的函数
                if (_stricmp((char*)((char*)Process+0x174), ProtectName) == 0 )
                        return 1;
        }
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
                return 0;
        }
        return 0;
}

//中间函数,根据过滤函数决定原函数是否正常运行
__declspec(naked) T_ObReferenceObjectByHandle(
    IN HANDLE Handle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_TYPE ObjectType OPTIONAL,
    IN KPROCESSOR_MODE AccessMode,
    OUT PVOID *Object,
    OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL
    ) {

     __asm
         {
                 mov     edi,edi
                 push    ebp
                 mov     ebp,esp

                 pushad
                 
                 push   [ebp+0x1c]
                 push   [ebp+0x18]
                 push   [ebp+0x14]
         push   [ebp+0x10]
         push   [ebp+0xc]
         push   [ebp+8]
                 
                 call   FilterFunction   
                 cmp   eax,1   
                 jz     end
                 
                 mov   eax,ObReferenceObjectByHandle      
                 add   eax,5            
                 jmp   eax   
end:
                 popad
/*                 mov   [ebp+8],-1 //--------->>无效句柄
                 mov   eax,ObReferenceObjectByHandle      
                 add   eax,5            
                 jmp   eax    */
                 mov esp,ebp
         pop ebp
                 ret 0x18
         }

}

//安装钩子和卸载钩子,关键看传入的test值
VOID HOOK_OR_UNHOOK(IN ULONG test)
{
        KIRQL CurrentIrql, OldIrql;
        PKDPC pKdpc;
        int JmpOffSet;
    unsigned char JmpCode[5] = { 0xe9, 0x00, 0x00, 0x00, 0x00 };
        unsigned char Code[5] = {0x8b,0xff,0x55,0x8b,0xec};//原始被修改的字节
     
        if(test==STARTHOOK)
        {
                JmpOffSet= (char*)T_ObReferenceObjectByHandle - (char*)ObReferenceObjectByHandle - 5;
                RtlCopyMemory ( JmpCode+1, &JmpOffSet, 4 );
        }
       
       
       
        // Raise IRQL here.
        CurrentIrql = KeGetCurrentIrql();
        OldIrql = CurrentIrql;
        if (CurrentIrql < DISPATCH_LEVEL)
                KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);

        pKdpc = GainExclusivity();
        __asm
        {
          CLI                          
          MOV     EAX, CR0           
          AND EAX, NOT 10000H
          MOV     CR0, EAX           
        }
       
        if(test==STARTHOOK)
    RtlCopyMemory ( ObReferenceObjectByHandle, JmpCode, 5 );
        else
        if(test==UNHOOK)
        RtlCopyMemory ( ObReferenceObjectByHandle, Code, 5 );
   
        __asm
        {
          MOV     EAX, CR0           
          OR     EAX, 10000H           
          MOV     CR0, EAX               
          STI                          
        }
   
        ReleaseExclusivity(pKdpc);
        KeLowerIrql(OldIrql);

}
2008-12-24 22:51
0
雪    币: 364
活跃值: (152)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
3
嘿嘿,比较ws的方法……顶~
2008-12-24 23:39
0
雪    币: 200
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
看了Sysnap的帖子,关于HOOK_OR_UNHOOK这个函数有两个疑问:
1,为什么要提高IRQL,是为了要调用GainExclusivity这个函数吗??
2:调用GainExclusivity有什么作用呢???GainExclusivity这个函数在MSDN上没查到
我实在挺笨的,希望在给我解释一下,我就能全看懂了
谢谢~~~~~~~~~~~~~~
2008-12-25 00:54
0
雪    币: 581
活跃值: (149)
能力值: ( LV12,RANK:600 )
在线值:
发帖
回帖
粉丝
5
不好意思...贴漏了GainExclusivity....安全INLINE 用....不过听说也不是很安全
LONG AllCPURaised; //0表示所有CPU还没提升到DISPATCH_LEVE上,,,否则为1
LONG NumberOfRaisedCPU; //表示有多少个CPU的IRQL提升到了DISPATCH_LEVEL

VOID RaiseCPUIrqlAndWait(IN PKDPC Dpc,
                                                 IN PVOID DeferredContext,
                                                 IN PVOID SystemArgument1,
                                                 IN PVOID SystemArgument2)
{
        InterlockedIncrement(&NumberOfRaisedCPU);
        while(!InterlockedCompareExchange(&AllCPURaised, 1, 1))
        {
                __asm nop;
        }
        InterlockedDecrement(&NumberOfRaisedCPU);

}

PKDPC GainExclusivity()
{
        NTSTATUS ns;
        ULONG u_currentCPU;
        CCHAR i;
        PKDPC pkdpc, temp_pkdpc;
       
        if (KeGetCurrentIrql() != DISPATCH_LEVEL)
                return NULL;
       
        // Initialize both globals to zero.
   InterlockedAnd(&AllCPURaised, 0);
   InterlockedAnd(&NumberOfRaisedCPU, 0);

   // Allocate room for our DPCs. This must be in NonPagedPool!
   temp_pkdpc = (PKDPC) ExAllocatePool(NonPagedPool,KeNumberProcessors*sizeof(KDPC));

   if (temp_pkdpc == NULL)
           return NULL; //STATUS_INSUFFICIENT_RESOURCES;

   u_currentCPU = KeGetCurrentProcessorNumber();

   pkdpc = temp_pkdpc;

   for (i = 0; i < KeNumberProcessors; i++, *temp_pkdpc++)
   {
           // Make sure we don't schedule a DPC on the current
           // processor. This would cause a deadlock.
          
           if (i != u_currentCPU)
           {
                   KeInitializeDpc(temp_pkdpc,
                                       RaiseCPUIrqlAndWait,
                                                   NULL);

         // Set the target processor for the DPC; otherwise,
                 // it will be queued on the current processor when
                 // we call KeInsertQueueDpc.
                  
                   KeSetTargetProcessorDpc(temp_pkdpc, i);
                   KeInsertQueueDpc(temp_pkdpc, NULL, NULL);
           }

   }

   while(InterlockedCompareExchange(&NumberOfRaisedCPU,KeNumberProcessors-1, KeNumberProcessors-1) !=KeNumberProcessors-1)
   {
           __asm nop;
   }

   return pkdpc; //STATUS_SUCCESS;

}

NTSTATUS ReleaseExclusivity(PVOID pkdpc)
{
        InterlockedIncrement(&AllCPURaised); // Each DPC will decrement
                                             // the count now and exit.
                                             // We need to free the memory allocated for the DPCs.
        while(InterlockedCompareExchange(&NumberOfRaisedCPU, 0, 0))
        {
                __asm nop;
        }
        if (pkdpc != NULL)
        {
                ExFreePool(pkdpc);
                pkdpc = NULL;
        }
        return STATUS_SUCCESS;

}
2008-12-25 08:18
0
游客
登录 | 注册 方可回帖
返回
//