dnf辅助外挂C++源代码
由于我的C用的比較少,所以大部分都用的匯編,部分地方用匯編寫不是很方便,所以我用的C,由于只是學習,所以內核地址我沒有計算都是硬編碼的。過DNF主要分為三步,也許我的思路不太正確,反正可以OD調試,下斷。
程序沒怎么修邊幅,因為只是測試,所以一般都沒有寫更改內核后的恢復,不過不妨礙使用。
?
第一步,這也是最起碼的,你必須要能夠打開游戲進程和線程,能夠開打進程和線程后不被檢測到
第二步,能夠讀寫進村內存
第三步,能夠用OD附加游戲進程
第四步,能夠下硬件斷點而不被檢測
?
跳過NtReadVirtualMemory,NtWriteVirtualMemory函數頭的鉤子
代碼:
?
#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
總結
以上是生活随笔為你收集整理的dnf辅助外挂C++源代码的全部內容,希望文章能夠幫你解決所遇到的問題。