PsSetLoadImageNotifyRoutine回调函数中使用NtProtectVirtualMemory卡死原因

来源:互联网 发布:linux top怎么退出 编辑:程序博客网 时间:2024/04/30 00:12

dll加载的回调应该是在MiMapViewOfSection->MiMapViewOfImageSection里吧,首先在前者调用后者前 会KeAcquireGuardedMutex (&((PROCESS)->AddressCreationLock));来进行同步NtProtectVirtualMemory->MiProtectVirtualMemory也会使用宏LOCK_ADDRESS_SPACE (Process);同样需要这个AddressCreationLock,可能会因此卡死吧。


以下部分内容来自WRK
先看两个宏
代码:


#define LOCK_ADDRESS_SPACE(PROCESS)                                  \
            KeAcquireGuardedMutex (&((PROCESS)->AddressCreationLock));
            
#define UNLOCK_ADDRESS_SPACE(PROCESS)                               \
            KeReleaseGuardedMutex (&((PROCESS)->AddressCreationLock));


这个锁的位置在EPROCESS里面,偏移在各个系统应该也不一样,所以要用的话得自己根据系统版本硬编码了。下面这个是XP的:
代码:
nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x06c ProcessLock      : _EX_PUSH_LOCK
   +0x070 CreateTime       : _LARGE_INTEGER
   +0x078 ExitTime         : _LARGE_INTEGER
   +0x080 RundownProtect   : _EX_RUNDOWN_REF
   +0x084 UniqueProcessId  : Ptr32 Void
   +0x088 ActiveProcessLinks : _LIST_ENTRY
   +0x090 QuotaUsage       : [3] Uint4B
   +0x09c QuotaPeak        : [3] Uint4B
   +0x0a8 CommitCharge     : Uint4B
   +0x0ac PeakVirtualSize  : Uint4B
   +0x0b0 VirtualSize      : Uint4B
   +0x0b4 SessionProcessLinks : _LIST_ENTRY
   +0x0bc DebugPort        : Ptr32 Void
   +0x0c0 ExceptionPort    : Ptr32 Void
   +0x0c4 ObjectTable      : Ptr32 _HANDLE_TABLE
   +0x0c8 Token            : _EX_FAST_REF
   +0x0cc WorkingSetLock   : _FAST_MUTEX
   +0x0ec WorkingSetPage   : Uint4B
   +0x0f0 AddressCreationLock : _FAST_MUTEX   
   +0x110 HyperSpaceLock   : Uint4B
   +0x114 ForkInProgress   : Ptr32 _ETHREAD
   +0x118 HardwareTrigger  : Uint4B


在加载PE文件时NtMapViewOfSection会调用这个:  
代码:
          
MmMapViewOfSection
{
//
    // Get the address creation mutex to block multiple threads
    // creating or deleting address space at the same time.
    //
  
    LOCK_ADDRESS_SPACE (Process);
    
    //Map Image
    status = MiMapViewOfImageSection (ControlArea,
              Process,
              CapturedBase,
              SectionOffset,
              CapturedViewSize,
              Section,
              InheritDisposition,
              ZeroBits,
              AllocationType,
              ImageCommitment);
                                              
  UNLOCK_ADDRESS_SPACE (Process);


}


//在这个函数里调用回调
MiMapViewOfImageSection
{
    ......
    PsCallImageNotifyRoutines();//此时锁是Lock状态
    ......
}
所以,你要在NotifyRoutine里先UNLOCK_ADDRESS_SPACE,然后调用ZwProtectVirturlMemory修改属性,完事儿再LOCK_ADDRESS_SPACE,这样就可以愉快地Patch了。
但是用了硬编码,感觉就不完美了。。。

0 0
原创粉丝点击