dnf辅助外挂C++源代码仅供学习参考.docx
- 文档编号:10286954
- 上传时间:2023-02-09
- 格式:DOCX
- 页数:28
- 大小:20.25KB
dnf辅助外挂C++源代码仅供学习参考.docx
《dnf辅助外挂C++源代码仅供学习参考.docx》由会员分享,可在线阅读,更多相关《dnf辅助外挂C++源代码仅供学习参考.docx(28页珍藏版)》请在冰豆网上搜索。
dnf辅助外挂C++源代码仅供学习参考
独钓寒江雪
由于我的C用的比较少,所以大部分都用的汇编,部分地方用汇编写不是很方便,所以我用的C,由于只是学习,所以内核地址我没有计算都是硬编码的。
过DNF主要分为三步,也许我的思路不太正确,反正可以OD调试,下断。
程序没怎么修边幅,因为只是测试,所以一般都没有写更改内核后的恢复,不过不妨碍使用。
第一步,这也是最起码的,你必须要能够打开游戏进程和线程,能够开打进程和线程后不被检测到
第二步,能够读写进村内存
第三步,能够用OD附加游戏进程
第四步,能够下硬件断点而不被检测
跳过NtReadVirtualMemory,NtWriteVirtualMemory函数头的钩子
代码:
#include
typedefstruct_SERVICE_DESCRIPTOR_TABLE
{
PVOIDServiceTableBase;
PULONGServiceCounterTableBase;
ULONGNumberOfService;
ULONGParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;//由于KeServiceDescriptorTable只有一项,这里就简单点了
externPSERVICE_DESCRIPTOR_TABLEKeServiceDescriptorTable;//KeServiceDescriptorTable为导出函数
/////////////////////////////////////
VOIDHook();
VOIDUnhook();
VOIDOnUnload(INPDRIVER_OBJECTDriverObject);
//////////////////////////////////////
ULONGJmpAddress;//跳转到NtOpenProcess里的地址
ULONGJmpAddress1;//跳转到NtOpenProcess里的地址
ULONGOldServiceAddress;//原来NtOpenProcess的服务地址
ULONGOldServiceAddress1;//原来NtOpenProcess的服务地址
//////////////////////////////////////
__declspec(naked)NTSTATUS__stdcallMyNtReadVirtualMemory(HANDLEProcessHandle,
PVOIDBaseAddress,
PVOIDBuffer,
ULONGNumberOfBytesToRead,
PULONGNumberOfBytesReaded)
{
//跳过去
__asm
{
push0x1c
push804eb560h//共十个字节
jmp[JmpAddress]
}
}
__declspec(naked)NTSTATUS__stdcallMyNtWriteVirtualMemory(HANDLEProcessHandle,
PVOIDBaseAddress,
PVOIDBuffer,
ULONGNumberOfBytesToWrite,
PULONGNumberOfBytesReaded)
{
//跳过去
__asm
{
push0x1c
push804eb560h//共十个字节
jmp[JmpAddress1]
}
}
///////////////////////////////////////////////////
NTSTATUSDriverEntry(INPDRIVER_OBJECTDriverObject,PUNICODE_STRINGRegistryPath)
{
DriverObject->DriverUnload=OnUnload;
DbgPrint("Unhookerload");
Hook();
returnSTATUS_SUCCESS;
}
/////////////////////////////////////////////////////
VOIDOnUnload(INPDRIVER_OBJECTDriverObject)
{
DbgPrint("Unhookerunload!
");
Unhook();
}
/////////////////////////////////////////////////////
VOIDHook()
{
ULONGAddress,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
moveax,cr0
andeax,not10000h
movcr0,eax
}
*((ULONG*)Address)=(ULONG)MyNtReadVirtualMemory;//HOOKSSDT
*((ULONG*)Address1)=(ULONG)MyNtWriteVirtualMemory;
__asm
{//恢复内存保护
moveax,cr0
oreax,10000h
movcr0,eax
sti
}
}
//////////////////////////////////////////////////////
VOIDUnhook()
{
ULONGAddress,Address1;
Address=(ULONG)KeServiceDescriptorTable->ServiceTableBase+0xBA*4;//查找SSDT
Address1=(ULONG)KeServiceDescriptorTable->ServiceTableBase+0x115*4;
__asm{
cli
moveax,cr0
andeax,not10000h
movcr0,eax
}
*((ULONG*)Address)=(ULONG)OldServiceAddress;//还原SSDT
*((ULONG*)Address1)=(ULONG)OldServiceAddress1;//还原SSDT
__asm{
moveax,cr0
oreax,10000h
movcr0,eax
sti
}
DbgPrint("Unhook");
}
由于它不断对DebugPort清零,所以要修改调试相关函数,使得所有的访问DebugPort的地方全部访问EPROCESS中的ExitTime字节,这样它怎么清零都无效了,也检测不到
代码:
.386
.modelflat,stdcall
optioncasemap:
none
includednf_hook.inc
.const
Dspdo_1equ80643db6h
Dmpp_1equ80642d5eh
Dmpp_2equ80642d64h
Dct_1equ806445d3h
Dqm_1equ80643089h
Kde_1equ804ff5fdh
Dfe_1equ80644340h
Pcp_1equ805d1a0dh
Mcp_1equ805b0c06h
Mcp_2equ805b0d7fh
Dmvos_1equ8064497fh
Dumvos_1equ80644a45h
Pet_1equ805d32f8h
Det_1equ8064486ch
Dep_1equ806448e6h
.code
;还原自己的Hook
DriverUnloadprocpDriverObject:
PDRIVER_OBJECT
ret
DriverUnloadendp
ModifyFuncAboutDbgprocaddrOdFunc,cmd_1,cmd_2
pushad
movebx,addrOdFunc
moveax,cmd_1
movDWORDptr[ebx],eax
moveax,cmd_2
movDWORDptr[ebx+4],eax
popad
ret
ModifyFuncAboutDbgendp
DriverEntryprocpDriverObject:
PDRIVER_OBJECT,pusRegistryPath:
PUNICODE_STRING
cli
moveax,cr0
andeax,not10000h
movcr0,eax
invokeModifyFuncAboutDbg,Dspdo_1,90784789h,0fde89090h
invokeModifyFuncAboutDbg,Dmpp_1,90787e39h,950f9090h
invokeModifyFuncAboutDbg,Dct_1,90785e39h,840f9090h
invokeModifyFuncAboutDbg,Dqm_1,9078408bh,45899090h
invokeModifyFuncAboutDbg,Kde_1,90787839h,13749090h
invokeModifyFuncAboutDbg,Dfe_1,9078418bh,0d2329090h
invokeModifyFuncAboutDbg,Pcp_1,90784389h,45f69090h
invokeModifyFuncAboutDbg,Mcp_1,90785e39h,950f9090h
invokeModifyFuncAboutDbg,Mcp_2,90784a89h,5e399090h
invokeModifyFuncAboutDbg,Dmvos_1,9078498bh,0cb3b9090h
invokeModifyFuncAboutDbg,Dumvos_1,00787983h,74909090h
invokeModifyFuncAboutDbg,Pet_1,00787f83h,74909090h
invokeModifyFuncAboutDbg,Det_1,9078498bh,0c9859090h
invokeModifyFuncAboutDbg,Dep_1,9078498bh,0c9859090h
;invokeModifyFuncAboutDbg,Dmpp_2,8bc0950fh,8b90c032h
moveax,pDriverObject
assumeeax:
ptrDRIVER_OBJECT
mov[eax].DriverUnload,offsetDriverUnload
assumeeax:
nothing
moveax,cr0
oreax,10000h
movcr0,eax
sti
moveax,STATUS_SUCCESS
ret
DriverEntryendp
endDriverEntry
绕过NtOpenProcess,NtOpenThread,KiAttachProcess
以及最重要的,不能让它检测到有硬件断点,所以要对CONTEXT做一些伪装,把真实的DR0~DR7的数据存放到别的地方,OD访问的时候返回正确的数据,如果是DNF要获取上下文,就稍微做下手脚
代码:
.386
.modelflat,stdcall
optioncasemap:
none
includednf_hook.inc
.const
NtOpenProcessHookAddrequ805cc626h
NtOpenProcessRetAddrequ805cc631h
NtOpenProcessNoChangeequ805cc62ch
NtOpenThreadHookAddrequ805cc8a8h
NtOpenThreadRetAddrequ805cc8b3h
NtOpenThreadNoChangeequ805cc8aeh
KiAttachProcessAddrequ804f9a08h
KiAttachProcessRetAddrequ804f9a0fh
ObOpenObjectByPointerAddrequ805bcc78h
NtGetContextThreadAddrequ805d2551h;805c76a3h
NtGetContextThreadRetAddrequ805c76a7h;805d2555h
.data
nameOffsetdd?
threadCxtLinkdd0
tmpLinkdd?
.code
GetProcessNameproc
invokePsGetCurrentProcess
movebx,eax
addebx,nameOffset
invokeDbgPrint,$CTA0("\n")
pushebx
invokeDbgPrint,ebx
popebx
invokestrncmp,$CTA0("DNF.exe"),ebx,6
pusheax
invokeDbgPrint,$CTA0("\n")
popeax
ret
GetProcessNameendp
HookCodeproc
;执行被覆盖的代码
pushdwordptr[ebp-38h]
pushdwordptr[ebp-24h]
;判断是否dnf的进程
invokeGetProcessName
.if!
eax;如果是DNF自己的进程,那么跳转回去执行它的Hook代码
pushad
invokeDbgPrint,$CTA0("\nNotUnHook\n")
popad
moveax,NtOpenProcessNoChange;805c13e6h
jmpeax
.else;如果不是DNF自己的进程,那么直接调用ObOpenObjectByPointer,再返回到后面
pushad
invokeDbgPrint,$CTA0("\nUnHook\n")
popad
moveax,ObOpenObjectByPointerAddr;805b13f0h
calleax
movebx,NtOpenProcessRetAddr;805c13ebh
jmpebx
.endif
HookCodeendp
;获取系统名称偏移
GetNameOffsetprocepe
localtmpOffset
pushad
movebx,epe
invokestrlen,$CTA0("System")
xorecx,ecx
@@:
pusheax
pushecx
invokestrncmp,$CTA0("System"),ebx,eax
popecx
.if!
eax
popeax
movtmpOffset,ecx
popad
moveax,tmpOffset
ret
.elseif
popeax
incebx
incecx
cmpecx,4096
je@F
jmp@B
.endif
@@:
popad
moveax,-1
ret
GetNameOffsetendp
Hookproc
pushad
;头5字节跳转
moveax,offsetHookCode
subeax,NtOpenProcessHookAddr;805c13e0h;805c13edh
subeax,5
movebx,NtOpenProcessHookAddr;805c13e0h;805c13edh
movcl,0E9h
movBYTEPTR[ebx],cl
movDWORDPTR[ebx+1],eax
popad
ret
Hookendp
HookThreadCodeproc
;执行被覆盖的代码
pushdwordptr[ebp-34h]
pushdwordptr[ebp-20h]
;判断是否dnf的进程
invokeGetProcessName
.if!
eax;如果是DNF自己的进程,那么跳转回去执行它的Hook代码
pushad
invokeDbgPrint,$CTA0("\nNotUnHook\n")
popad
moveax,NtOpenThreadNoChange;805c13e6h
jmpeax
.else;如果不是DNF自己的进程,那么直接调用ObOpenObjectByPointer,再返回到后面
pushad
invokeDbgPrint,$CTA0("\nUnHook\n")
popad
moveax,ObOpenObjectByPointerAddr;805b13f0h
calleax
movebx,NtOpenThreadRetAddr;805c13ebh
jmpebx
.endif
HookThreadCodeendp
HookThreadproc
pushad
;头5字节跳转
moveax,offsetHookThreadCode
subeax,NtOpenThreadHookAddr;805c13e0h;805c13edh
subeax,5
movebx,NtOpenThreadHookAddr;805c13e0h;805c13edh
movcl,0E9h
movBYTEPTR[ebx],cl
movDWORDPTR[ebx+1],eax
popad
ret
HookThreadendp
HookDbgproc
movedi,edi
pushebp
movebp,esp
pushebx
pushesi
movesi,KiAttachProcessRetAddr
jmpesi
HookDbgendp
Dbgproc
pushad
;头5字节跳转
moveax,offsetHookDbg
subeax,KiAttachProcessAddr;805c13e0h;805c13edh
subeax,5
movebx,KiAttachProcessAddr;805c13e0h;805c13edh
movcl,0E9h
movBYTEPTR[ebx],cl
movDWORDPTR[ebx+1],eax
popad
ret
Dbgendp
;还原自己的Hook
DriverUnloadprocpDriverObject:
PDRIVER_OBJECT
cli
moveax,cr0
andeax,not10000h
movcr0,eax
;还原进程处理
moveax,0ffc875ffh
movebx,805cc656h
movDWORDptr[ebx],eax
moveax,43e8dc75h
movDWORDptr[ebx+4],eax
;还原线程处理
moveax,0ffcc75ffh
movebx,805cc8d8h
movDWORDptr[ebx],eax
moveax,0c1e8e075h
movDWORDptr[ebx+4],eax
;还原调试处理
moveax,08b55ff8bh
movebx,804f9a08h
movDWORDptr[ebx],eax
moveax,08b5653ech
movDWORDptr[ebx+4],eax
moveax,cr0
oreax,10000h
movcr0,eax
sti
ret
DriverUnloadendp
;显示LinkTable的信息
ShowLinkTableInfoprocptrLT
pushad
invokeDbgPrint,$CTA0("\nTheLinkTableInfo:
\n")
movebx,ptrLT
moveax,(LinkTableptr[ebx]).ThreadHandle
invo
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- dnf 辅助 外挂 C+ 源代码 学习 参考