吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 18365|回复: 40
收起左侧

[其他转载] 过掉DNF游戏保护,仅供学习研究。不得用于非法途径

    [复制链接]
渐陌 发表于 2010-11-9 13:51
第一步,这也是最起码的,你必须要能够打开游戏进程和线程,能够开打进程和线程后不被检测到
第二步,能够读写进村内存
第三步,能够用OD附加游戏进程
第四步,能够下硬件断点而不被检测

跳过NtReadVirtualMemory,NtWriteVirtualMemory函数头的钩子

代码:
[code#include<ntddk.h>

typedef struct _SERVICE_DESCRIPTOR_TABLE
{
  PVOID   ServiceTableBase;
  PULONG  ServiceCounterTableBase;
  ULONG   NumberOfService;
  ULONG   ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE; //由于KeServiceDescriptorTable只有一项,这里就简单点了
extern PSERVICE_DESCRIPTOR_TABLE    KeServiceDescriptorTable;//KeServiceDescriptorTable为导出函数

/////////////////////////////////////
VOID Hook();
VOID Unhook();
VOID OnUnload(IN PDRIVER_OBJECT DriverObject);
//////////////////////////////////////
ULONG JmpAddress;//跳转到NtOpenProcess里的地址
ULONG JmpAddress1;//跳转到NtOpenProcess里的地址
ULONG OldServiceAddress;//原来NtOpenProcess的服务地址
ULONG OldServiceAddress1;//原来NtOpenProcess的服务地址
//////////////////////////////////////
__declspec(naked) NTSTATUS __stdcall MyNtReadVirtualMemory(HANDLE ProcessHandle,
               PVOID BaseAddress,
               PVOID Buffer,
               ULONG NumberOfBytesToRead,
         PULONG NumberOfBytesReaded)
{
  //跳过去
  __asm
  {
    push    0x1c
    push    804eb560h  //共十个字节
    jmp     [JmpAddress]   
  }
}

__declspec(naked) NTSTATUS __stdcall MyNtWriteVirtualMemory(HANDLE ProcessHandle,
               PVOID BaseAddress,
               PVOID Buffer,
               ULONG NumberOfBytesToWrite,
         PULONG NumberOfBytesReaded)
{
  //跳过去
  __asm
  {
    push    0x1c
    push    804eb560h  //共十个字节
    jmp     [JmpAddress1]
  }
}
///////////////////////////////////////////////////
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
  DriverObject->DriverUnload = OnUnload;
  DbgPrint("Unhooker load");
  Hook();
  return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////
VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
  DbgPrint("Unhooker unload!");
  Unhook();
}
/////////////////////////////////////////////////////
VOID Hook()
{
  ULONG  Address, Address1;
  Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0xBA * 4;//0x7A为NtOpenProcess服务ID
  Address1 = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x115 * 4;//0x7A为NtOpenProcess服务ID

  DbgPrint("Address:0x%08X",Address);

  OldServiceAddress = *(ULONG*)Address;//保存原来NtOpenProcess的地址
  OldServiceAddress1 = *(ULONG*)Address1;//保存原来NtOpenProcess的地址
  DbgPrint("OldServiceAddress:0x%08X",OldServiceAddress);
  DbgPrint("OldServiceAddress1:0x%08X",OldServiceAddress1);

  DbgPrint("MyNtOpenProcess:0x%08X",MyNtReadVirtualMemory);
  DbgPrint("MyNtOpenProcess:0x%08X",MyNtWriteVirtualMemory);

  JmpAddress = (ULONG)0x805b528a + 7; //跳转到NtOpenProcess函数头+10的地方,这样在其前面写的JMP都失效了
  JmpAddress1 = (ULONG)0x805b5394 + 7;
  DbgPrint("JmpAddress:0x%08X",JmpAddress);
  DbgPrint("JmpAddress1:0x%08X",JmpAddress1);
   
  __asm
  {    //去掉内存保护
    cli
        mov  eax,cr0
    and  eax,not 10000h
    mov  cr0,eax
  }

  *((ULONG*)Address) = (ULONG)MyNtReadVirtualMemory;//HOOK SSDT
  *((ULONG*)Address1) = (ULONG)MyNtWriteVirtualMemory;

  __asm
  {    //恢复内存保护  
        mov  eax,cr0
    or   eax,10000h
    mov  cr0,eax
    sti
  }
}
//////////////////////////////////////////////////////
VOID Unhook()
{
  ULONG  Address, Address1;
  Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0xBA * 4;//查找SSDT
  Address1 = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x115 * 4;

  __asm{
    cli
          mov  eax,cr0
    and  eax,not 10000h
    mov  cr0,eax
  }

  *((ULONG*)Address) = (ULONG)OldServiceAddress;//还原SSDT
  *((ULONG*)Address1) = (ULONG)OldServiceAddress1;//还原SSDT

  __asm{  
         mov  eax,cr0
    or   eax,10000h
    mov  cr0,eax
    sti
  }

  DbgPrint("Unhook");
}
由于它不断对DebugPort清零,所以要修改调试相关函数,使得所有的访问DebugPort的地方全部访问EPROCESS中的ExitTime字节,这样它怎么清零都无效了,也检测不到

代码:
.386
.model flat, stdcall
option casemap:none

include dnf_hook.inc

.const
Dspdo_1 equ 80643db6h
Dmpp_1 equ 80642d5eh
Dmpp_2 equ 80642d64h
Dct_1 equ 806445d3h
Dqm_1 equ 80643089h
Kde_1 equ 804ff5fdh
Dfe_1 equ 80644340h
Pcp_1 equ 805d1a0dh
Mcp_1 equ 805b0c06h
Mcp_2 equ 805b0d7fh
Dmvos_1 equ 8064497fh
Dumvos_1 equ 80644a45h
Pet_1 equ 805d32f8h
Det_1 equ 8064486ch
Dep_1 equ 806448e6h

.code
;还原自己的Hook
DriverUnload proc pDriverObject:PDRIVER_OBJECT
  ret  
DriverUnload endp

ModifyFuncAboutDbg proc addrOdFunc, cmd_1, cmd_2
  pushad
  mov  ebx, addrOdFunc
  mov  eax, cmd_1
  mov   DWORD ptr [ebx], eax
  mov  eax, cmd_2
  mov   DWORD ptr [ebx + 4], eax
  popad
  ret
ModifyFuncAboutDbg endp

DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
  cli
        mov   eax, cr0
        and   eax, not 10000h
        mov   cr0, eax
        
  invoke ModifyFuncAboutDbg, Dspdo_1, 90784789h, 0fde89090h
  invoke ModifyFuncAboutDbg, Dmpp_1, 90787e39h, 950f9090h
  invoke ModifyFuncAboutDbg, Dct_1, 90785e39h, 840f9090h
  invoke ModifyFuncAboutDbg, Dqm_1, 9078408bh, 45899090h
  invoke ModifyFuncAboutDbg, Kde_1, 90787839h, 13749090h
  invoke ModifyFuncAboutDbg, Dfe_1, 9078418bh, 0d2329090h
  invoke ModifyFuncAboutDbg, Pcp_1, 90784389h, 45f69090h
  invoke ModifyFuncAboutDbg, Mcp_1, 90785e39h, 950f9090h
  invoke ModifyFuncAboutDbg, Mcp_2, 90784a89h, 5e399090h
  invoke ModifyFuncAboutDbg, Dmvos_1, 9078498bh, 0cb3b9090h
  invoke ModifyFuncAboutDbg, Dumvos_1, 00787983h, 74909090h
  invoke ModifyFuncAboutDbg, Pet_1, 00787f83h, 74909090h
  invoke ModifyFuncAboutDbg, Det_1, 9078498bh, 0c9859090h
  invoke ModifyFuncAboutDbg, Dep_1, 9078498bh, 0c9859090h
  ;invoke ModifyFuncAboutDbg, Dmpp_2, 8bc0950fh, 8b90c032h
  
  mov  eax, pDriverObject
  assume   eax : ptr DRIVER_OBJECT
  mov   [eax].DriverUnload, offset DriverUnload
  assume   eax : nothing
  
  mov  eax, cr0
        or  eax, 10000h
        mov   cr0, eax
        sti
        
        mov  eax, STATUS_SUCCESS
     ret
DriverEntry endp
end DriverEntry
绕过NtOpenProcess,NtOpenThread,KiAttachProcess
以及最重要的,不能让它检测到有硬件断点,所以要对CONTEXT做一些伪装,把真实的DR0~DR7的数据存放到别的地方,OD访问的时候返回正确的数据,如果是DNF要获取上下文,就稍微做下手脚

代码:
.386
.model flat, stdcall
option casemap:none

include dnf_hook.inc

.const
NtOpenProcessHookAddr equ 805cc626h
NtOpenProcessRetAddr equ 805cc631h
NtOpenProcessNoChange equ 805cc62ch

NtOpenThreadHookAddr equ 805cc8a8h
NtOpenThreadRetAddr equ 805cc8b3h
NtOpenThreadNoChange equ 805cc8aeh

KiAttachProcessAddr equ 804f9a08h
KiAttachProcessRetAddr equ 804f9a0fh

ObOpenObjectByPointerAddr equ 805bcc78h

NtGetContextThreadAddr equ 805d2551h;805c76a3h
NtGetContextThreadRetAddr equ 805c76a7h;805d2555h

.data
nameOffset dd ?
threadCxtLink dd 0
tmpLink dd ?

.code
GetProcessName proc
  invoke PsGetCurrentProcess
  mov  ebx, eax
  add   ebx, nameOffset
  invoke DbgPrint, $CTA0("\n")
  push  ebx
  invoke DbgPrint, ebx
  pop  ebx
  invoke strncmp, $CTA0("DNF.exe"), ebx, 6
  push  eax
  invoke DbgPrint, $CTA0("\n")
  pop  eax
  ret
GetProcessName endp

HookCode proc
  ;执行被覆盖的代码
  push    dword ptr [ebp-38h]
  push    dword ptr [ebp-24h]
  ;判断是否dnf的进程
  invoke  GetProcessName
  .if  !eax  ;如果是DNF自己的进程,那么跳转回去执行它的Hook代码
    pushad
    invoke DbgPrint, $CTA0("\nNotUnHook\n")
    popad
    mov  eax, NtOpenProcessNoChange;805c13e6h
    jmp  eax
  .else    ;如果不是DNF自己的进程,那么直接调用ObOpenObjectByPointer,再返回到后面
    pushad
    invoke DbgPrint, $CTA0("\nUnHook\n")
    popad
    mov  eax, ObOpenObjectByPointerAddr;805b13f0h
    call  eax
    mov  ebx, NtOpenProcessRetAddr;805c13ebh
    jmp  ebx
  .endif
HookCode endp

;获取系统名称偏移
GetNameOffset proc epe
  local tmpOffset
  pushad
  mov  ebx, epe
  invoke strlen, $CTA0("System")
  xor  ecx, ecx
@@:
  push  eax
  push  ecx
  invoke strncmp, $CTA0("System"), ebx, eax
  pop  ecx
  .if  !eax
    pop  eax
    mov  tmpOffset, ecx
    popad
    mov  eax, tmpOffset
    ret
  .elseif
    pop  eax
    inc  ebx
    inc  ecx
    cmp  ecx, 4096
    je  @F
    jmp  @B
  .endif
@@:
  popad
  mov  eax, -1
  ret
GetNameOffset endp

Hook proc
  pushad
  ;头5字节跳转
  mov  eax, offset HookCode
  sub  eax, NtOpenProcessHookAddr;805c13e0h;805c13edh
  sub  eax, 5
  mov  ebx, NtOpenProcessHookAddr;805c13e0h;805c13edh
  mov  cl, 0E9h
  mov  BYTE PTR [ebx], cl
  mov  DWORD PTR [ebx + 1], eax
  popad
  ret
Hook endp

HookThreadCode proc
  ;执行被覆盖的代码
  push    dword ptr [ebp-34h]
  push    dword ptr [ebp-20h]
  ;判断是否dnf的进程
  invoke  GetProcessName
  .if  !eax  ;如果是DNF自己的进程,那么跳转回去执行它的Hook代码
    pushad
    invoke DbgPrint, $CTA0("\nNotUnHook\n")
    popad
    mov  eax, NtOpenThreadNoChange;805c13e6h
    jmp  eax
  .else    ;如果不是DNF自己的进程,那么直接调用ObOpenObjectByPointer,再返回到后面
    pushad
    invoke DbgPrint, $CTA0("\nUnHook\n")
    popad
    mov  eax, ObOpenObjectByPointerAddr;805b13f0h
    call  eax
    mov  ebx, NtOpenThreadRetAddr;805c13ebh
    jmp  ebx
  .endif
  
HookThreadCode endp

HookThread proc
  pushad
  ;头5字节跳转
  mov  eax, offset HookThreadCode
  sub  eax, NtOpenThreadHookAddr;805c13e0h;805c13edh
  sub  eax, 5
  mov  ebx, NtOpenThreadHookAddr;805c13e0h;805c13edh
  mov  cl, 0E9h
  mov  BYTE PTR [ebx], cl
  mov  DWORD PTR [ebx + 1], eax
  popad
  ret
HookThread endp

HookDbg proc
  mov     edi, edi
  push    ebp
  mov     ebp, esp
  push    ebx
  push    esi
  mov  esi, KiAttachProcessRetAddr
  jmp  esi
HookDbg endp

Dbg proc
  pushad
  ;头5字节跳转
  mov  eax, offset HookDbg
  sub  eax, KiAttachProcessAddr;805c13e0h;805c13edh
  sub  eax, 5
  mov  ebx, KiAttachProcessAddr;805c13e0h;805c13edh
  mov  cl, 0E9h
  mov  BYTE PTR [ebx], cl
  mov  DWORD PTR [ebx + 1], eax
  popad
  ret
Dbg endp

;还原自己的Hook
DriverUnload proc pDriverObject:PDRIVER_OBJECT
  cli
        mov   eax, cr0
        and   eax, not 10000h
        mov   cr0, eax

  ;还原进程处理
  mov  eax, 0ffc875ffh
  mov  ebx, 805cc656h
  mov   DWORD ptr [ebx], eax
  mov   eax, 43e8dc75h
  mov  DWORD ptr [ebx + 4], eax
  ;还原线程处理
  mov  eax, 0ffcc75ffh
  mov  ebx, 805cc8d8h
  mov   DWORD ptr [ebx], eax
  mov   eax, 0c1e8e075h
  mov  DWORD ptr [ebx + 4], eax
  ;还原调试处理
  mov  eax, 08b55ff8bh
  mov  ebx, 804f9a08h
  mov   DWORD ptr [ebx], eax
  mov  eax, 08b5653ech
  mov   DWORD ptr [ebx + 4], eax

  mov  eax, cr0
        or  eax, 10000h
        mov   cr0, eax
        sti

  ret  
DriverUnload endp

;显示LinkTable的信息
ShowLinkTableInfo proc ptrLT
  pushad
  invoke   DbgPrint, $CTA0("\nThe LinkTable Info:\n")
  
  mov  ebx, ptrLT
  mov  eax, (LinkTable ptr [ebx]).ThreadHandle
  invoke   DbgPrint, $CTA0("ThreadHandle:%0X\n"), eax
  
  mov  ebx, ptrLT
  mov  eax, (LinkTable ptr [ebx]).Dr0Seg
  invoke   DbgPrint, $CTA0("Dr0Seg:%0X\n"), eax
  
  mov  ebx, ptrLT
  mov  eax, (LinkTable ptr [ebx]).Dr1Seg
  invoke   DbgPrint, $CTA0("Dr1Seg:%0X\n"), eax
  
  mov  ebx, ptrLT
  mov  eax, (LinkTable ptr [ebx]).Dr2Seg
  invoke   DbgPrint, $CTA0("Dr2Seg:%0X\n"), eax
  
  mov  ebx, ptrLT
  mov  eax, (LinkTable ptr [ebx]).Dr3Seg
  invoke   DbgPrint, $CTA0("Dr3Seg:%0X\n"), eax
  
  mov  ebx, ptrLT
  mov  eax, (LinkTable ptr [ebx]).Dr6Seg
  invoke   DbgPrint, $CTA0("Dr6Seg:%0X\n"), eax
  
  mov  ebx, ptrLT
  mov  eax, (LinkTable ptr [ebx]).Dr7Seg
  invoke   DbgPrint, $CTA0("Dr7Seg:%0X\n"), eax
  
  mov  ebx, ptrLT
  mov  eax, (LinkTable ptr [ebx]).LinkPtr
  invoke   DbgPrint, $CTA0("LinkPtr:%0X\n"), eax
  
  mov  ebx, ptrLT
  mov  eax, (LinkTable ptr [ebx]).NextLinkPtr
  invoke   DbgPrint, $CTA0("NextLinkPtr:%0X\n"), eax
  popad
  ret
ShowLinkTableInfo endp

;判断该线程是否存在
;如果不存在则返回0,存在则返回指向该链表的指针,1代表链表为空
ExsitsLinkTable proc pHandle
  pushad
  mov  eax, threadCxtLink
  .if  !eax  ;链表为空
    pushad
    invoke   DbgPrint, $CTA0("\nLinkTable Is Null.\n")
    popad   
   
    popad
    mov  eax, 1
    ret
  .endif
@@:
  mov  ebx, (LinkTable ptr [eax]).ThreadHandle
  cmp  ebx, pHandle  ;如果匹配已经存在
  je  @F
  mov  eax, (LinkTable ptr [eax]).NextLinkPtr
  .if  !eax  ;已经到达末尾,没有找到匹配
    pushad
    invoke   DbgPrint, $CTA0("\pHandle Is Not Found.\n")
    popad
   
    popad
    xor  eax, eax
    ret
  .endif
  jmp  @B
@@:
  pushad
  invoke   DbgPrint, $CTA0("\npHandle Is Exsits.\n")
  popad
  invoke   ShowLinkTableInfo, eax
  ;返回链表指针
  mov  tmpLink, eax
  popad
  mov  eax, tmpLink
  ret
ExsitsLinkTable endp

;拷贝Context到LinkTable中
CopyContextToLinkTable proc ptrContext, ptrLT
  pushad
  mov  ebx, ptrContext
  mov  edx, ptrLT
  mov  ecx, 4
@@:
  mov  eax, DWORD ptr [ebx + ecx]
  mov  DWORD ptr [edx + ecx], eax
  add  ecx, 4
  cmp  ecx, 18h
  jbe  @B
  popad
  ret
CopyContextToLinkTable endp

;添加LinkTable表
AddLinkTable proc pHandle, ptrContext
  pushad
  invoke  ExsitsLinkTable, pHandle
  .if  eax > 1
    ;已经存在只需要更新dr寄存器即可
    invoke  CopyContextToLinkTable, eax, ptrContext
  .else
    push  eax
    invoke   ExAllocatePool, 1, size LinkTable
    .if  eax
      ;申请内存成功
      mov  ebx, eax
      pop  eax
      ;置地一个元素
      mov  ecx, pHandle
      mov  (LinkTable ptr [ebx]).ThreadHandle, ecx
      ;拷贝dr寄存器的值
      invoke  CopyContextToLinkTable, ptrContext, ebx
      ;置另外两个元素
      mov  (LinkTable ptr [ebx]).LinkPtr, ebx
      mov  (LinkTable ptr [ebx]).NextLinkPtr, 0
      invoke  ShowLinkTableInfo, ebx
      
      ;把新的链表项添加到链表中
      .if  eax == 1
        ;如果链表为空,直接加在表头
        mov  threadCxtLink, ebx
      .else
        ;如果链表不为空则加到末尾
        mov  eax, threadCxtLink
@@:
        ;指向下一个元素
        mov  ecx, (LinkTable ptr [eax]).NextLinkPtr
        test  ecx, ecx
        je  @F
        mov  eax, ecx
        jmp  @B
@@:
        mov  (LinkTable ptr [eax]).NextLinkPtr, ebx
      .endif
    .else
      ;申请内存失败
      pop  eax
      pushad
      invoke DbgPrint, $CTA0("\nAlloc Memory Faild.\n")
      popad
      jmp  @F
    .endif
  .endif
@@:
  popad
  ret
AddLinkTable endp

;判断进程是否过虑进程
;如果是需要过虑的进程返回值为1,否则返回0
IsFilterProcess proc
  pushad
  ;获取当前进程名
  invoke   PsGetCurrentProcess
  mov  ebx, eax
  add   ebx, nameOffset
  invoke   DbgPrint, $CTA0("\n%s: Call NtGetContextThread \n"), ebx
  invoke   strncmp, $CTA0("DNF.exe"), ebx, 7
  test  eax, eax
  jne  @F
  popad
  mov  eax, 1
  ret
@@:
  popad
  xor  eax, eax
  ret
IsFilterProcess endp

;显示Context的调试寄存器
ShowDrRegInfo proc ptrContext
  pushad
  invoke   DbgPrint, $CTA0("\nThe Context Info:\n")
  
  mov  ebx, ptrContext
  mov  eax, DWORD ptr [ebx + 4]
  invoke   DbgPrint, $CTA0("Dr0:%0X\n"), eax
  
  mov  ebx, ptrContext
  mov  eax, DWORD ptr [ebx + 8]
  invoke   DbgPrint, $CTA0("Dr1:%0X\n"), eax
  
  mov  ebx, ptrContext
  mov  eax, DWORD ptr [ebx + 0ch]
  invoke   DbgPrint, $CTA0("Dr2:%0X\n"), eax
  
  mov  ebx, ptrContext
  mov  eax, DWORD ptr [ebx + 10h]
  invoke   DbgPrint, $CTA0("Dr3:%0X\n"), eax
  
  mov  ebx, ptrContext
  mov  eax, DWORD ptr [ebx + 14h]
  invoke   DbgPrint, $CTA0("Dr6:%0X\n"), eax
  
  mov  ebx, ptrContext
  mov  eax, DWORD ptr [ebx + 18h]
  invoke   DbgPrint, $CTA0("Dr7:%0X\n"), eax
  popad
  ret
ShowDrRegInfo endp

;恢复被隐藏的dr寄存器
RecoveryDrReg proc ptrContext, pHandle
  pushad
  ;定位到LinkTable
  mov  ebx, threadCxtLink
NEXT:
  test  ebx, ebx
  jne  @F  ;如果没有遍历完
  popad
  ret
@@:
  mov  eax, (LinkTable ptr [ebx]).ThreadHandle
  cmp  eax, pHandle
  je  @F  ;如果找到匹配项
  mov  ebx, (LinkTable ptr [ebx]).NextLinkPtr
  jmp  NEXT
@@:
  ;拷贝完毕后立即结束
  invoke CopyContextToLinkTable, ebx, ptrContext
  xor  ebx, ebx
  jmp  NEXT
RecoveryDrReg endp

;清空Context的dr寄存器
ClearDrReg proc ptrContext
  pushad
  mov  ebx, ptrContext
  mov  ecx, 4
@@:
  mov  DWORD ptr [ebx + ecx], 0
  add  ecx, 4
  cmp  ecx, 18h
  jbe  @B
  pushad
  invoke DbgPrint, $CTA0("\n-------------ClearDrReg-------------\n")
  popad
  invoke ShowDrRegInfo, ptrContext
  popad
  ret
ClearDrReg endp

;NtGetContextThread钩子代码
NtGetContextThreadHookCode proc
  ;ebx存放CONTEXT指针
  mov  ebx, DWORD ptr [ebp + 10h]
  ;线程句柄
  mov  edx, DWORD ptr [ebp + 0ch]
  pushad  
  invoke  ShowDrRegInfo, ebx
  invoke  IsFilterProcess
  .if  eax  ;如果是DNF.exe
    invoke  AddLinkTable, edx, ebx
    invoke  ClearDrReg, ebx
  .else    ;如果不是DNF.exe
    invoke  RecoveryDrReg, ebx, edx
  .endif
  invoke  ShowDrRegInfo, ebx
  ;执行被覆盖的代码
  popad
  mov     eax, esi
  pop     esi
  leave
  ret
NtGetContextThreadHookCode endp

;NtGetContextThread加跳转
HookNtGetContextThread proc
  pushad
  ;头5字节跳转
  mov  eax, offset NtGetContextThreadHookCode
  sub  eax, NtGetContextThreadAddr;805c13e0h;805c13edh
  sub  eax, 5
  mov  ebx, NtGetContextThreadAddr;805c13e0h;805c13edh
  mov  cl, 0E9h
  mov  BYTE PTR [ebx], cl
  mov  DWORD PTR [ebx + 1], eax
  popad
  ret
HookNtGetContextThread endp

DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
  invoke DbgPrint, $CTA0("Begin")
  invoke PsGetCurrentProcess
  invoke GetNameOffset, eax
  mov  nameOffset, eax
  cmp  eax, -1
  je  @F
  mov  nameOffset, eax
  
  cli
        mov   eax, cr0
        and   eax, not 10000h
        mov   cr0, eax

  call  Hook
  call  HookThread
  call  Dbg
  call  HookNtGetContextThread

  mov  eax, pDriverObject
  assume   eax : ptr DRIVER_OBJECT
  mov   [eax].DriverUnload, offset DriverUnload
  assume   eax : nothing
  
  mov  eax, cr0
        or  eax, 10000h
        mov   cr0, eax
        sti
  invoke DbgPrint, $CTA0("End")
@@:
  mov  eax, STATUS_SUCCESS
     ret
DriverEntry endp
end DriverEntry
][/code]

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

kimberaly 发表于 2010-11-9 15:43
真是多步骤,呵呵
kingbaby 发表于 2010-11-9 14:40
lwbok 发表于 2010-11-9 14:04
cai595442533 发表于 2010-11-9 14:01
高手就是高手佩服
530687469 发表于 2010-11-9 15:57
我只看得懂一点    还要向楼主学习
HRBANG 发表于 2010-11-20 17:35
哈哈 ,这个猛 找了好久
bcf 发表于 2010-11-20 17:52
看不明白。。。
liu3062315 发表于 2010-11-20 22:37
看了一遍还是没有明白的干活
nevsayno 发表于 2010-11-21 03:11
学习一下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 18:35

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表