dnf辅助外挂C++源代码

由于我的C用的比较少,所以大部分都用的汇编,部分地方用汇编写不是很方便,所以我用的C,由于只是学习,所以内核地址我没有计算都是硬编码的。过DNF主要分为三步,也许我的思路不太正确,反正可以OD调试,下断。

程序没怎么修边幅,因为只是测试,所以一般都没有写更改内核后的恢复,不过不妨碍使用。

 

第一步,这也是最起码的,你必须要能够打开游戏进程和线程,能够开打进程和线程后不被检测到

第二步,能够读写进村内存

第三步,能够用OD附加游戏进程

第四步,能够下硬件断点而不被检测

 

跳过NtReadVirtualMemoryNtWriteVirtualMemory函数头的钩子

代码:

 

#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;//0x7ANtOpenProcess服务ID

  Address1 = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x115 * 4;//0x7ANtOpenProcess服务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

 

绕过NtOpenProcessNtOpenThreadKiAttachProcess

以及最重要的,不能让它检测到有硬件断点,所以要对CONTEXT做一些伪装,把真实的DR0DR7的数据存放到别的地方,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

 

;拷贝ContextLinkTable

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

 

;清空Contextdr寄存器

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

阅读更多
上一篇外挂编写完全攻略
下一篇[四种]网络游戏外挂的制作方法
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭