首页
社区
课程
招聘
[求助]关于在NtOpenProcess中加Inline hook
发表于: 2013-7-14 16:48 5831

[求助]关于在NtOpenProcess中加Inline hook

2013-7-14 16:48
5831
非常感谢各位大佬能帮我解决的一下这个问题,非常感谢。
我参考了看雪中http://bbs.pediy.com/showthread.php?t=126802的一篇文章,里面有将关于绕过DNF的Inline hook,大概就是在 NtOpenProcess 反汇编后,里面有一处是 CALL ObOpenObjectByPointer,然后它就在CALL obopenobjectbypointer前面有6个字节的指令 push    dword ptr [ebp-38h] push    dword ptr [ebp-24h]
它的做法是修改前面6个字节 跳转到自己定义的中继函数哪里 绕过DNF的检测。

我的问题是:1. 为什么一修改 就蓝屏啊,是不是代码有问题啊?我用kernel dec直接把前面的6个字节全部改成NOP都没问题啊?我实在虚拟机上调试的。
                  2. 我定位到RtlCopyMemory(p_MyHookAddress,JmpAddress,6);这句出了问题,一般蓝屏这种,我要如何定位问题所在啊?

小弟是新手,请各位大佬帮助我一下 谢谢大家乐。

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 32
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
//NtOpenProcess用到的全局变量[为了方便堆栈平衡的处理使用全局变量]
PEPROCESS  processEPROCESS = NULL;  //保存访问者的EPROCESS
ANSI_STRING  p_str1,p_str2;      //保存进程名称
BYTE    *ObOpenObjectByPointerAddress  = NULL; //ObOpenObjectByPointer的地址
BYTE    *p_TpHookAddress = NULL;        //TP的HOOK函数地址
BYTE    *p_ReturnAddress = NULL;        //返回到的地址
BYTE    *p_MyHookAddress = NULL;        //我们的HOOK函数在哪写入
#define DNF_EXE  "DNF.exe"  //要检索的进程名
//////////////////////////////////////////////////////////////////////
//  名称:  Nakd_NtOpenProcess
//  功能:  My_RecoveryHook_NtOpenProcess的中继函数
//  参数:  
//  返回:  
//////////////////////////////////////////////////////////////////////
static NAKED VOID  Nakd_NtOpenProcess()
{

  //获得调用者的EPROCESS,每个进程都有一个 EPROCESS 结构,里面保存着进程的各种信息,
  //和相关结构的指针。EPROCESS 结构位于系统地址空间,所以访问这个结构需要有ring0的权限
  processEPROCESS = IoGetCurrentProcess();

  //将调用者的进程名保存到str1中
  RtlInitAnsiString(&p_str1,(char*)processEPROCESS+0x174);

  //将我们要比对的进程名放入str2
  RtlInitAnsiString(&p_str2,DNF_EXE);
  if (RtlCompareString(&p_str1,&p_str2,TRUE) == 0)
  {
    //说明是DNF进程访问了这里
    __asm
    {
      push    dword ptr [ebp-38h]//这个是HOOK之前的代码
      push    dword ptr [ebp-24h]
      push  p_ReturnAddress
      mov    eax,p_TpHookAddress
      jmp    eax
    }
  }
  else
  {
    __asm
    {
      push    dword ptr [ebp-38h]
      push    dword ptr [ebp-24h]
      push  p_ReturnAddress
      mov    eax,ObOpenObjectByPointerAddress
      jmp    eax
    }
  }

}

//保存5字节代码的结构
#pragma pack(1)
typedef struct _TOP5CODE
{
  UCHAR  instruction;  //指令
  ULONG  address;    //地址
}TOP5CODE,*PTOP5CODE;
#pragma pack( )

//////////////////////////////////////////////////////////////////////
//  名称:  My_RecoveryHook_NtOpenProcess
//  功能:  解除游戏保护对NtOpenProcess的HOOK
//  参数:  
//  返回:  状态
//////////////////////////////////////////////////////////////////////
NTSTATUS My_RecoveryHook_NtOpenProcess()
{
  BYTE    *NtOpenProcessAddress      = NULL;  //NtOpenProcess的地址
  BYTE    *p = NULL;      //临时
  TOP5CODE  *top5code = NULL;  //保存5字节内容
  BYTE    JmpAddress[6] = {0xE9,0,0,0,0,0x90};//0XE9 表示 JMP, 0X90 表示NOP
  KIRQL    Irql;

    //获取NtOpenProcess的地址
    NtOpenProcessAddress = (BYTE*)MyGetFunAddress(L"NtOpenProcess");
        DbgPrint( "NtOpenProcessAddress Addr: %x\n", NtOpenProcessAddress);
    if (NtOpenProcessAddress == NULL)
    {
      KdPrint(("NtOpenProcess地址获取失败\n"));
      return  FAILED_TO_OBTAIN_FUNCTION_ADDRESSES;
    }

    //获取ObOpenObjectByPointer的地址
    ObOpenObjectByPointerAddress = (BYTE*)MyGetFunAddress(L"ObOpenObjectByPointer");
    if (ObOpenObjectByPointerAddress == NULL)
    {
      KdPrint(("ObOpenObjectByPointer地址获取失败\n"));
      return  FAILED_TO_OBTAIN_FUNCTION_ADDRESSES;
    }

    //将p指向NtOpenProcess函数开始处
    p = NtOpenProcessAddress;
    //用一个无限循环来判断给定的特征码来确定被HOOK位置
    while (1)
    {
      if ((*(p-7)    == 0x50) &&
        (*(p-0xE)  == 0x56) &&
        (*(p+0xd)  == 0x50) &&
        (*(p+0x16)  == 0x3b) &&
        (*(p+0x17)  == 0xce) &&
        (*p      == 0xE8) &&
        (*(p+5)    == 0x8b) &&
        (*(p+6)    == 0xf8))
      {
        KdPrint(("%0X \n",(ULONG)p));
        break;
      }
      //推动指针向前走
      p++;
    }

    //将top5code指向 p 的当前处,E8= CALL ,后面4个字节是地址
    //用以取出 call [地址] 这5字节里面的地址
    top5code = (TOP5CODE*)p;
    p_TpHookAddress = (BYTE*)((ULONG)p+5+top5code->address);//DNF修改的call跳转地址

    //找到我们写入自定义函数的地址
    p_MyHookAddress = p-6;//放我们自己钩子的地方,前面两条指令占6位
    //保存调用ObOpenObjectByPointer函数以后的返回地址
    p_ReturnAddress = p+5;//CALL ObOpenObjectByPointer后面指令的地址

    //将一条JMP Nakd_NtOpenProcess写入到数组中
    *(ULONG *)(JmpAddress+1)=(ULONG)Nakd_NtOpenProcess - ((ULONG)p_MyHookAddress+5);

    WPOFF();  //清除CR0
    //提升IRQL中断级
    Irql=KeRaiseIrqlToDpcLevel();
    //写入
    RtlCopyMemory(p_MyHookAddress,JmpAddress,6);
    //恢复Irql
    KeLowerIrql(Irql);
    WPON();    //恢复CR0
  
  return  STATUS_SUCCESS;
}
2013-7-14 16:49
0
雪    币: 32
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
2013-7-14 17:42
0
雪    币: 21
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
代码贴上看看啊
2013-7-15 15:27
0
雪    币: 73
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
是不是 这几行代码有检测啊 你改别的地方试试啊
2013-7-23 16:07
0
雪    币: 220
活跃值: (117)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
为啥不直接HOOK ObOpenObjectByPointer
2013-7-24 14:41
0
雪    币: 39
活跃值: (158)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我也遇到这样的问题,现在一直没解决
2013-8-1 09:51
0
游客
登录 | 注册 方可回帖
返回
//