首页
社区
课程
招聘
[求助]过某游戏驱动保护的代码,启动时蓝屏
发表于: 2011-11-19 23:59 12500

[求助]过某游戏驱动保护的代码,启动时蓝屏

2011-11-19 23:59
12500
刚学驱动,有兴趣从网上找了份过d_N_f的驱动代码,按照自己机器上的地址把代码改了改,编译成功,但驱动一启动就蓝屏,蓝屏代码为7E,搞了半天也不知道哪里出错了,请各位大大们帮俺看看吧,(另:纯属个人兴趣,没有别的意思)
贴出源代码:
#include <ntddk.h>
#include <windef.h>

#define INITCODE code_seg("INIT") /*运行一次就释放内存*/
#define PAGECODE code_seg("PAGE") /*分页内存*/

VOID CloseMemoryProtect(); //关闭写保护
VOID OpenMemoryProtect(); //开启写保护
VOID MyDriver_Unload(PDRIVER_OBJECT pDriverObject); //卸载函数

#pragma pack(1) //一字节对齐
typedef struct JmpCode {
        BYTE bytecode; //0xBA , mov edx,MyFunctionAddress,自定义HOOK类型
        ULONG Address; //MyFunctionAddress
        USHORT JmpEdx; //D2FF ,  jmp edx
} JmpCode, *PJmpCode;
#pragma pack()

typedef struct ServiceDescriptorEntry {
    unsigned int *ServiceTableBase;
    unsigned int *ServiceCounterTableBase;
    unsigned int NumberOfServices;
    unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry;
extern PServiceDescriptorTableEntry KeServiceDescriptorTable; //SSDT表,声明指针用extern

ULONG MyGetFunAddress( IN PCWSTR FunctionName)
{
  UNICODE_STRING UniCodeFunctionName;
  RtlInitUnicodeString( &UniCodeFunctionName, FunctionName );
  return (ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName );   
}

ULONG Readdizhi,Writedizhi,OldRead,OldWrite; //读,写
JmpCode CopyCode,CopyCodeT; //保存进程,线程被HOOK的代码,以便卸载时恢复
PJmpCode OldAddress,OldAddressT; //要HOOK的进程和线程地址
PEPROCESS processEPROCESS = NULL,TprocessEPROCESS = NULL; //保存访问者的EPROCESS
ANSI_STRING p_str1,p_str2,p_str3; //保存进程名称

//用SSDT  HOOK对抗TP保护的INLINE  HOOK
//读内存
static __declspec(naked) NTSTATUS __stdcall MyNtReadVirtualMemory(HANDLE ProcessHandle,
                                                           PVOID BaseAddress,
                                                           PVOID Buffer,
                                                           ULONG NumberOfBytesToRead,
                                                           PULONG NumberOfBytesReaded)
{
    //跳过去
    __asm
    {
        push    0x1C
        push    0x804DA4E0
        mov     edx,0x80538F40
        jmp     edx
    }
}

//写内存
static __declspec(naked) NTSTATUS __stdcall MyNtWriteVirtualMemory(HANDLE ProcessHandle,
                                                            PVOID BaseAddress,
                                                            PVOID Buffer,
                                                            ULONG NumberOfBytesToWrite,
                                                            PULONG NumberOfBytesReaded)
{
    //跳过去
    __asm
    {
        push    0x1C
        push    0x804DA4F8
        mov     edx,0x80538F40
        jmp     edx
    }
}

BYTE    *ObOpenObjectByPointerAddress  = NULL;
static __declspec(naked) VOID MyFunction() //NtOpenProcess调用ObOpenObjectByPointer的处理
{
  __asm
  {
    push eax
    push dword ptr [ebp-38h]
    push dword ptr [ebp-24h]
  }

  
  //获得访问者的EPROCESS
  processEPROCESS = IoGetCurrentProcess();
  ObOpenObjectByPointerAddress = (BYTE*)MyGetFunAddress(L"ObOpenObjectByPointer");

  //将调用者的进程名保存到p_str2中
  RtlInitAnsiString(&p_str2,(PCSZ)((ULONG)processEPROCESS+0x174));

  if (RtlCompareString(&p_str1,&p_str2,TRUE) == 0)
  {
    //说明是DNF进程访问了这里,让其调用TP模块的函数跟Ring3通信,不被报非法模块
    __asm
    {
      push 0x805C253F
      mov  edx,0x805C253B
      mov  edx,dword ptr [edx]
      add  edx,0x805C253F
      jmp  edx  //TP模块的函数,DNF程序不从这里过,就报非法模块
    }
  }

  else
  {
    //说明是其他进程访问了这里,直接调用ObOpenObjectByPointer,CE就可以附加了
    __asm
    {
      push 0x805C253F
      mov  edx,ObOpenObjectByPointerAddress  //ObOpenObjectByPointer
      jmp  edx
    }
  }
}

static __declspec(naked) VOID MyFunctionT() //NtOpenThread调用ObOpenObjectByPointer的处理
{
  __asm
  {
    push eax
    push dword ptr [ebp-34h]
    push dword ptr [ebp-20h]
  }
   
  //获得访问者的EPROCESS
  TprocessEPROCESS = IoGetCurrentProcess();
  ObOpenObjectByPointerAddress = (BYTE*)MyGetFunAddress(L"ObOpenObjectByPointer");
   
  //将调用者的进程名保存到p_str3中
  RtlInitAnsiString(&p_str3,(PCSZ)((ULONG)TprocessEPROCESS+0x174));

  if (RtlCompareString(&p_str1,&p_str3,TRUE) == 0)
  {
    //说明是DNF进程访问了这里,让其调用TP模块的函数跟Ring3通信,不被报非法模块
    __asm
    {
      push 0x805C27C1
      mov  edx,0x805C27BD
      mov  edx,dword ptr [edx]
      add  edx,0x805C27C1
      jmp  edx  //TP模块的函数,DNF程序不从这里过,就报非法模块
    }
  }

  else
  {
    //说明是其他进程访问了这里,直接调用ObOpenObjectByPointer,但是OD附加就蓝屏
    __asm
    {
      push 0x805C27C1
      mov  edx,ObOpenObjectByPointerAddress //ObOpenObjectByPointer
      jmp  edx
    }
  }
}

#pragma PAGECODE
VOID CloseMemoryProtect() //去掉页面保护
{
  __asm
  {
    cli
    mov eax,cr0
    and eax,not 10000h
    mov cr0,eax
  }
}

#pragma PAGECODE
VOID OpenMemoryProtect() //恢复页面保护
{
  __asm
  {
    mov eax,cr0
    or  eax,10000h
    mov cr0,eax
    sti
  }
}

#pragma INITCODE
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pRegistryPath)
{
  ULONG jizhi;

  //初始化驱动卸载函数
  pDriverObject->DriverUnload = MyDriver_Unload;

  jizhi = (ULONG)KeServiceDescriptorTable->ServiceTableBase; //获取SSDT表基址
  
  Readdizhi = jizhi+186*4; //获取NtReadVirtualMemory
  OldRead = *(PULONG)Readdizhi; //保存NtReadVirtualMemory原始地址
  KdPrint(("Readdizhi地址为 %x",Readdizhi));
  
  Writedizhi = jizhi+277*4; //获取NtWriteVirtualMemory
  OldWrite = *(PULONG)Writedizhi; //保存NtWriteVirtualMemory原始地址
  KdPrint(("Writedizhi地址为 %x",Writedizhi));

  //保存原始代码,NtOpenProcess调用ObOpenObjectByPointer之前的7个字节
  OldAddress = (PJmpCode)0x805C2533;
  CopyCode.bytecode = OldAddress->bytecode;
  CopyCode.Address = OldAddress->Address;
  CopyCode.JmpEdx = OldAddress->JmpEdx;

  //保存原始代码,NtOpenThread调用ObOpenObjectByPointer之前的7个字节
  OldAddressT = (PJmpCode)0x805C27B5;
  CopyCodeT.bytecode = OldAddressT->bytecode;
  CopyCodeT.Address = OldAddressT->Address;
  CopyCodeT.JmpEdx = OldAddressT->JmpEdx;  

  //将DNF.exe进程名放入p_str1中,以便判断
  RtlInitAnsiString(&p_str1,"DNF.exe");

  CloseMemoryProtect(); //去掉页面保护

  //HOOK绕过TP保护读内存,写内存
  *(PULONG)Readdizhi = (ULONG)MyNtReadVirtualMemory;
  *(PULONG)Writedizhi = (ULONG)MyNtWriteVirtualMemory;

  //HOOK绕过NtOpenProcess调用ObOpenObjectByPointer
  OldAddress->bytecode = 0xBA;
  OldAddress->Address = (ULONG)MyFunction;
  OldAddress->JmpEdx = 0xE2FF;

  //HOOK绕过NtOpenThread调用ObOpenObjectByPointer
  OldAddressT->bytecode = 0xBA;
  OldAddressT->Address = (ULONG)MyFunctionT;
  OldAddressT->JmpEdx = 0xE2FF;

  OpenMemoryProtect(); //恢复页面保护

  KdPrint(("MyFunction地址为 %x",(ULONG)MyFunction));
  KdPrint(("MyFunctionT地址为 %x",(ULONG)MyFunctionT));

  KdPrint(("驱动加载成功..."));

  return STATUS_SUCCESS;
}

#pragma PAGECODE
VOID MyDriver_Unload(PDRIVER_OBJECT pDriverObject)
{
  CloseMemoryProtect(); //去掉页面保护

  //代码恢复,读内存,写内存
  *(PULONG)Readdizhi = OldRead;
  *(PULONG)Writedizhi = OldWrite;

  //代码恢复
  OldAddress->bytecode = CopyCode.bytecode;
  OldAddress->Address = CopyCode.Address;
  OldAddress->JmpEdx = CopyCode.JmpEdx;
  //代码恢复
  OldAddressT->bytecode = CopyCodeT.bytecode;
  OldAddressT->Address = CopyCodeT.Address;
  OldAddressT->JmpEdx = CopyCodeT.JmpEdx;

  OpenMemoryProtect(); //恢复页面保护

  KdPrint(("驱动已被卸载..."));
}

[课程]Android-CTF解题方法汇总!

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 500
活跃值: (860)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
新的问题,游戏开始后加载驱动 电脑马上重启了
2011-11-20 00:37
0
雪    币: 95
活跃值: (11)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
3
硬编码的。自己调试着看看。。是哪里问题了。看dump撒。。哪有有问题。改哪里
2012-1-15 12:34
0
雪    币: 208
活跃值: (148)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
解铃还须系铃人,自己慢慢研究吧!别人帮不来你 的
2012-1-15 13:12
0
雪    币: 160
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
坛子里面之前就已经有人放出过TP的源码了,自己搜索一下!
2012-1-15 14:56
0
雪    币: 585
活跃值: (568)
能力值: ( LV13,RANK:290 )
在线值:
发帖
回帖
粉丝
6
把dump文件传上来,最好是  核心内存转储
2012-1-15 15:43
0
雪    币: 508
活跃值: (202)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
7
可能是硬编码有误;
通过特征码找到关健地方在HOOK
2012-1-17 12:06
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
满屏幕的xx还能不蓝屏嘛,想不蓝屏重启就调试好tp驱动再来写代码吧。
2012-1-17 14:42
0
雪    币: 101
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
加入 int 3断点 一步一步跟跟看,基本就是你写的 那几个0xXXXXXXX 中 有1个以上的错误,细心点会找到的
2012-2-5 21:04
0
游客
登录 | 注册 方可回帖
返回
//