R3下猥琐NTDLL钩子

链 接:  http://bbs.pediy.com/showthread.php?t=163658


在R3下对NTDLL里面的Zw函数的HOOK 大部分都是在函数前几个字节做HOOK,或者IAT之类的.这样的HOOK 虽然比较方便,不过也存在一个很大的弊端,就是函数HOOK 很容易被检测,所以我们需要一种更猥琐的HOOK方式.当然这只是相对.而不是真的很猥琐......

NTDLL里面的ZW函数大部分都是这样的
代码:
MOV EAX,1
MOV EDX,7FFE0300
CALL DWORD PTR DS:[EDX]
RETN 20
NTDLL里面的ZW函数都是通过系统全局共享内存7FFE0300调用KiFastSystemCall进入内核,所以我们要做的就是HOOK这个函数.
代码:
77866190 >  8BD4             MOV EDX,ESP
77866192    0F34             SYSENTER
77866194 >  C3               RETN
大家看到了,大小5个字节 而且还有个返回函数,所以我们只能短跳再长跳.....


代码:
void HookSystemCall_HOOK()
{
  DWORD dwOldProtect;
  HMODULE hModule = GetModuleHandleA("NTDLL.dll");

  DWORD dwKiFastSystemCall = PtrToUlong(GetProcAddress(hModule, "KiFastSystemCall"));
  VirtualProtect(ULongToPtr(dwKiFastSystemCall - 0xA), 100, PAGE_EXECUTE_READWRITE, &dwOldProtect);


  *(PWORD)ULongToPtr(dwKiFastSystemCall) = 0xF4EB;
  *(PBYTE)ULongToPtr(dwKiFastSystemCall - 0xA) = 0xE9;
  *(PDWORD)ULongToPtr(dwKiFastSystemCall - 0x9) = PtrToUlong(KiFastSystemCall) - (dwKiFastSystemCall - 0xA) - 5;
}
接下来就是JMP到我们的函数里面了.接下来要处理的就是把我们要的ZW函数给分拣出来.大家肯定注意到ZW的汇编代码MOV EAX,1,没错这个1就是ZW函数的序号.既然如此分拣出我们要的函数也不是什么问题

代码:
__declspec(naked) void KiFastSystemCall()
{
  
  __asm{
      cmp         eax,1 ;EAX保存着我们需要的函数的序号.我们跳.....
      jz          Label
      jmp         KiFastSystemCallEx
      ;其他的返回原始KiFastSystemCall的地方,当然,原来的函数已经被我们JMP出来啦.需要特别处理
Label:
      add         esp,4
      ;不再返回到原始的ZwAccessCheck函数里面.而是直接返回调用ZwAccessCheck的函数.
      jmp         MyZwAccessCheck ;
  }
}
上面的函数就是我们的KiFastSystemCall啦.接下来就是我们的MyZwAccessCheck函数.还有一个我们需要自己进入内核的KiFastSystemCallEx函数,我们自己构造一个.当然我们还需要构造一个新的ZwAccessCheck函数,原始的那个函数调用的KiFastSystemCall已经被我们HOOK了.
代码:
//自己构造一个KiFastSystemCall  这样原始的RETN问题就解决了.
__declspec(naked) void KiFastSystemCallEx()
{
  __asm  {
    mov edx,esp
    __emit 0x0F
    __emit 0x34
    retn
  }
}

//跳板函数  
__declspec(naked) NTSTATUS NTAPI ZwAccessCheck(
    IN PSECURITY_DESCRIPTOR SecurityDescriptor,
    IN HANDLE ClientToken,
    IN ACCESS_MASK DesiredAccess,
    IN PGENERIC_MAPPING GenericMapping,
    OUT PPRIVILEGE_SET PrivilegeSet,
    OUT PULONG ReturnLength,
    OUT PACCESS_MASK GrantedAccess,
    OUT PNTSTATUS AccessStatus)
{
    __asm
  {
    MOV EAX,1
    CALL KiFastSystemCallEx
    RETN 20
  }
}

NTSTATUS NTAPI MyZwAccessCheck(
    IN PSECURITY_DESCRIPTOR SecurityDescriptor,
    IN HANDLE ClientToken,
    IN ACCESS_MASK DesiredAccess,
    IN PGENERIC_MAPPING GenericMapping,
    OUT PPRIVILEGE_SET PrivilegeSet,
    OUT PULONG ReturnLength,
    OUT PACCESS_MASK GrantedAccess,
    OUT PNTSTATUS AccessStatus)
{
    return ZwAccessCheck(
    ISecurityDescriptor,
    ClientToken,
    DesiredAccess,
    GenericMapping,
    PrivilegeSet,
    ReturnLength,
    GrantedAccess,
    AccessStatus);
}
差不多一个意思....剩下的就是依葫芦画瓢....自由发挥了. 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值