dnf辅助外挂C 源代码_第1页
dnf辅助外挂C 源代码_第2页
dnf辅助外挂C 源代码_第3页
dnf辅助外挂C 源代码_第4页
dnf辅助外挂C 源代码_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

独钓寒江雪由于我的C用的比较少,所以大部分都用的汇编,部分地方用汇编写不是很方便.所以我用的C,由于只是学习,所以内核地址我没有计算都是硬编码的。过DNF主要分为三步,也许我的思路不太正确,反正可以0D调试,下断。程序没怎么修边幅,因为只是测试,所以一般都没有写更改内核后的恢复,不过不妨碍使用。第一步,这也是最起码的,你必须要能够打开游戏进程和线程,能够开打进程和线程后不被检测到第二步,能够读写进村内存第三步,能够用0D附加游戏进程第四步,能够下硬件断点而不被检测跳过NtReadViinialMemoiy,NtWiiteV11tualMemoiy函数头的钩子代码:#includetvpedefstnictSERVICEDESCRIPTORTABLE{PVOIDSeiviceTableBase;PULONGSeiviceCounteiTableBase;ULONGNumbeiOfSeivice;ULONGPaiamTableBase;)SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;〃由于KeSeiviceDescnptoiTable只有一项,这里就简单点了externPSERVICE_DESCRIPTOR_TABLEKeServiceDescriptoiTable;//KeSeiviceDescriptorTable为导出函数VOIDHook(;VOIDUnhook(;VOIDOnUnload(INPDRIVER_OBJECTDnveiObject;ULONGJmpAddress;//跳转到NtOpeiiPiocess里的地址ULONGJmpAddressl;//跳转到NtOpeiiPiocess里的地址ULONGOldSeiviceAddiess;//原来NtOpeiiPiocess的服务地址ULONGOldSeiviceAddiess1;//原来NtOpeiiPiocess的服务地址//〃///〃///〃〃//〃〃/〃〃//〃〃/〃〃—declspec(nakedNTSTATUS_stdcallMyNtReadVutualMemoiy(HANDLEProcessHandle,PVOIDBaseAddress,PVOIDBuffer,ULONGNumbeiOfBytesToRead,PULONGNumbeiOfBvtesReadedJ{〃跳过去—asm{pushOxlcpush804eb560h〃共十个字节jmp[JmpAddiess]}}——declspealakedNTSTATUS——sacallMyN【wli_evlitualMemoly(HANDLEplocessHapdpPVOIDBaseAddless"PVOIDBufE。ULONGNumbelofBytesTOWs-kPULONGNumbeiOfBytesReaded■{——asm{pushOxlcpush804eb560h、/»+->#斗jmp【JmpAddlesslJ三三三三二三三三三三三三三三三三三_NTSTATUSDllvelEmly(INPDRIVERIOBJECTDllvelobJecLPUNICODEISTRINGRegsrypalh{DrlvelobJec_—VDlivelUnloadHonulload;DbgplB'一c-unhookelload---HookGretrnnSTATUSISUCCESS;三三三一三三三三三三三三三三二三三三--VOIDonunload(INPDRIVERIOBJECTDmelobjec-DbgPiint(flUnhookerunload!*1;Uiiliook(;}//〃///〃///〃〃//〃〃/〃〃//〃〃//〃〃/〃〃//〃〃/〃VOIDHook({ULONGAddress,Address1;Address=(ULONGKeSeiviceDescnptoiTable->SeiviceTableBase十OxBA*4;//0x7A为NtOpeiiPiocess服务IDAddress1=(ULONGKeSeiviceDescnptoiTable->SeiviceTableBase+0x115*4;//0x7A为NtOpeiiPiocess服务IDDbgPnnt("Address:0x%08X,',Address;OldSendeeAddress=*(ULONG*Addiess;〃保存原来NtOpeiiPiocess的地址OldSendeeAddress1=*(ULONG*Address1;//保存原来NtOpeiiPiocess的地址DbgPiint(nOldSeiviceAddiess:0x%08X,t,OldSexviceAddiess;DbgPiint(n01dSexviceAddressl:0x%08Xu,OldSeiviceAddressl;DbgPnnt(,,MyNtOpeiiProcess:0x%08Xf\MyNtReadViitualMemory;DbgPnnt(,,MyNtOpeiiProcess:0x%08Xt\MyNtWnteViinialMemoiy;JmpAddiess=(ULONG0x805b528a十7;〃跳转到NtOpeiiPiocess函数头+10的地方’这样在其前面写的JMP都失效了JmpAddiess1=(ULONG0x805b5394十7;DbgPiint(HJmpAddress:0x%08X,,,JmpAddress;DbgPiint(HJmpAddressl:0x%08XHJmpAddiess1;—asm{〃去掉内存保护ellmoveax,ciOandeaxjiotlOOOOhmovciO,eax}*((ULONG*Address=(ULONGMyNtReadViinialMemoiy;//HOOKSSDT*((ULONG*Address1=(ULONGMyNtWiiteV11tualMemoiy;—asm{〃恢复内存保护moveax,ciOoreaxJOOOOhmovciO,eaxStl}}//〃///〃///〃〃//〃〃/〃〃//〃〃//〃〃/〃〃//〃〃〃〃VOIDUiiliook({ULONGAddress,Address1;Address=(ULONGKeSeiviceDescnptoiTable->SeiviceTableBase十OxBA*4;//查找SSDTAddress1=(ULONGKeSeiviceDescnptoiTable->SeiviceTableBase十0x115*4;—asm(climoveax,ciOandeaxaiot10000bmovciO,eax}*((ULONG*Address=(ULONGOldSeiviceAddiess;//还原SSDT*((ULONG*Address1=(ULONGOldSemceAddiessl;//还原SSDT—asm(moveax,ciOoreaxJOOOOhmovciO,eaxStl}DbgPniit(nUiiliooku;}由于它不断对DebugPoit清零,所以要修改调试相关函数,使得所有的访问DebugPort的地方全部访问EPROCESS中的ExitTmie字节,这样它怎么清零都无效了,也检测不到代码:.386.modelflat,stdcalloptioncasemap:nonemcludednf_hook.inc.constDspdo_lequ80643db6hDmpp_lequ80642d5ehDmpp_2equ80642d641iDct_lequ806445d3hDqm_lequ8064308911Kde_lequ804ff5fdhDfe_lequ8064434011Pcp_lequ805dla0dhMcp_lequ805b0c06hMcp_2equ805b0d7fliDmvos_lequ8064497fhDumvos.lequ80644a45hPet_lequ805d32f8hDet_lequ8064486chDep_lequ806448e6h.code;还原自己的HookDnveiUnloadpiocpDiiveiObject:PDRIVER_OBJECTretDnveiUnloadendpModifyFuncAboutDbgpiocaddrOdFunc,cnid_l,cmd_2pushadmovebx,addrOdFuncmoveax,cmd_lmovDWORDpti[ebx],eaxmoveax,cnid_2movDWORDpti[ebx+4],eaxpopadretModifyFuncAboutDbgendpDnveiEntiypiocpDnveiObject:PDRIVER_OBJECT,pusRegistiyPath:PUNICODE_STRINGellmoveax,ciOandeax,notlOOOOhmovciO,eaxmvokeModifyFuncAboutDbg.Dspdo_l,9078478911,0fde89090hmvokeModifyFuncAboutDbg.Dnipp_l,90787e39h,950f9090hmvokeModifyFuncAboutDbg.Dct_l,90785e39h,840f9090hmvokeModifyFuncAboutDbg.Dqm_l,9078408bh,4589909011uivokeModifyFuncAboutDbg,Kde_l,9078783911,1374909011mvokeModifyFuncAboutDbg,Dfe_l,9078418bh,0d2329090hmvokeModifyFuncAboutDbg,Pcp_l,9078438911,45f69090huivokeModifyFuncAboutDbg.Mcp_l,90785e39h,950f9090huivokeModifyFuncAboutDbg.Mcp_2,90784a89h,5e399090huivokeModifyFuncAboutDbg.Dmvos_l,9078498bh,0cb3b9090huivokeModifyFuncAboutDbg.Dumvos_l,0078798311,7490909011uivokeModifyFuncAboutDbg,Pet_l,00787fB3h,7490909011uivokeModifyFuncAboutDbg.Det_L9078498bh,0c9859090huivokeModifyFuncAboutDbg.Dep_l,9078498bh,0c9859090h;invokeModifyFuncAboutDbg,Dmpp_2,8bc0950fh,8b90c032hmoveax,pDiiveiObjectassumeeax:ptrDRIVER_OBJECTmov[eax].DnveiUnload,offsetDnveiUnloadassumeeax:nothingmoveax,ciO01eax,lOOOOhmovciO,eaxStlmoveax,STATUS_SUCCESSletDnveiEntiyendpendDiiveiEntiy绕过NtOpeiiProcess,NtOpenThiead.KiAttachProcess以及最重要的,不能让它检测到有硬件断点.所以要对CONTEXT做一些伪装,把真实的DR0~DR7的数据存放到别的地方0D访问的时候返回正确的数据.如果是DNF要获取上下文,就稍微做下手脚代码:.386.modelflat,stdcalloptioncasemap:nonemchidednf_hook.inc.constNtOpeiiProcessHookAddiequ805cc626hNtOpeiiProcessRetAddrequ805cc631hNtOpeiiProcessNoChangeequ805cc62chNtOpenThieadHookAddiequ805cc8a8hNtOpenThieadRetAddfequ805cc8b3hNtOpenThieadNoChangeequ805cc8aehKiAttacliPiocessAddiequ804f9a08hKiAttacliPiocessRetAddiequ804f9a0fliObOpenObjectByPointeiAddiequ805bcc78hNtGetContextThieadAddiequ805d255lh;805c76a3hNtGetContextThieadRetAddiequ805c76a71i;805d2555h.datanameOffsetdd?thieadCxtLnikdd0tmpLiiikdd?.codeGetPiocessNameprocmvokePsGetCunentProcessmovebx,eaxaddebx,nameOffsetmvokeDbgPrmt,$CTA0(”\n”pushebxmvokeDbgPnnt,ebxpopebxmvokestincmp,$CTAO(”DNF.exe",ebx,6pusheaxmvokeDbgPrmt,$CTA0(”\n”popeaxretGetPiocessNameendpHookCodeproc;执行被覆盖的代码pushdwoidpti[ebp-38h]pushdwoidpti[ebp-24h];判断是否dnf的进程mvokeGetPiocessName■if!eax;如果是DNF自己的进程,那么跳转回去执行它的Hook代码pushaduivokeDbgPrmt,$CTAO(n\iiNotUiiHook\ii"popadmoveax,NtOpeiiPiocessNoCliange;805c13e6hjmpeax.else;如果不是DNF自己的进程,那么直接调用ObOpenObjectByPointei,再返回到后面pushadinvokeDbgPrmt,$CTAO(n\iiUiiHook\ii"popadmoveax,ObOpenObjectByPointerAddr;805bl3fOhcalleaxmovebx,NtOpenPiocessRetAddr;805cl3ebhjmpebx.endifHookCodeendp;获取系统名称偏移GetNameOffsetpiocepelocaltmpOffsetpushadmovebx,epemvokestilen,$CTAO(f,Systemuxoiecx,ecx@@:pusheaxpushecxmvokestincmp,$CTAO(uSystem,\ebx,eaxpopecx.if!eaxpopeaxmovtmpOffset,ecxpopadmoveax,tmpOffsetret.elseifpopeaxmeebxmeecxempecx,4096je@Fjmp@B.endif@@:popadretGetNameOffsetendpHookpiocpushad;头5字节跳转moveax,offsetHookCodesubeax,NtOpeiiProcessHookAddi;805c13e0h;805c13edhsubeax,5movebx,NtOpeiiProcessHookAddi;805c13e0h;805c13edhmovcL0E9hmovBYTEPTR[ebx],clmovDWORDPTR[ebx+1],eaxpopadretHookendpHookTlueadCodepioc;执行被覆盖的代码pushdwoidpti[ebp-34h]pushdwoidpti[ebp-20h];判断是否dnf的进程mvokeGetPiocessName•if!eax;如果是DNF自己的进程,那么跳转回去执行它的Hook代码pushaduivokeDbgPrmt,$CTAO(n\iiNotUiiHook\ii"popadmoveax,NtOpenTlHeadNoChange;805cl3e6hjmpeax.else;如果不是DNF自己的进程,那么直接调用ObOpenObjectByPomtei,再返回到后面pushaduivokeDbgPrmt,$CTAO(n\iiUiiHook\ii"popadmoveax,ObOpenObjectByPointerAddr;805bl3fOhcalleaxmovebx,NtOpenTlueadRetAddi;805c13ebhjmpebx.endifHookTlueadCodeendpHookTlueadprocpushad;头5字节跳转moveax,offsetHookTlueadCodesubeax,NtOpenThieadHookAddi;805c13e0h;805c13edhsubeax,5movebx,NtOpenThreadHookAddr;805c13e0h;805c13edhmovcL0E9hmovBYTEPTR[ebx],clmovDWORDPTR[ebx+1],eaxpopadretHookTlueadendpHookDbgprocmovedi,edipushebpmovebp,esppushebxpushesimovesi,KiAttachProcessRetAddijmpesiHookDbgendpDbgprocpushad;头5字节跳转moveax,offsetHookDbgsubeax,KiAttacliPiocessAddi;805c13e0h;805c13edhsubeax,5movebx,KiAttacliPiocessAddi;805c13e0h;805c13edhmovcl,0E9hmovBYTEPTR[ebx],clmovDWORDPTR[ebx+1],eaxpopadretDbgendp;还原自己的HookDnveiUnloadpiocpDiiveiObject:PDRIVER_OBJECTellmoveax,crOandeax,notlOOOOhmovciO,eax;还原进程处理moveax,Offc875ffhmovebx,805cc656hmovDWORDpti[ebx],eaxmoveax,43e8dc75hmovDWORDpti[ebx+4],eax;还原线程处理moveax,Offcc75ffhmovebx,8O5cc8d8hmovDWORDpti[ebx],eaxmoveax,Ocle8eO75hmovDWORDpti[ebx+4],eax;还原调试处理moveax,O8b55ff8bhmovebx,804f9a08hmovDWORDpti[ebx],eaxmoveax,O8b5653echmovDWORDpti[ebx+4],eaxmoveax,crOoreax,lOOOOhmovciO,eaxStlretDnveiUnloadendp;显示LmkTable的信息ShowLuikTablelnfbprocptiLTpushaduivokeDbgPrmt,$CTA0("\nTheLmkTableInfo:\n"movebx,ptiLTmoveax,(LmkTableptr[ebx].TlueadHandleuivokeDbgPrmt,$CTAO(”ThieadHandle:%OX\n”,eaxmovebx,ptiLTmoveax,(LmkTableptr[ebx].DfOSeguivokeDbgPrmt,$CTAO("DiOSeg:%OX\nH,eaxmovebx,ptiLTmoveax,(LmkTableptr[ebx].DilSeguivokeDbgPrmt,$CTA0("Di1Seg:%0X\nH,eaxmovebx,ptiLTmoveax,(LmkTablepti[ebx].Di2SeguivokeDbgPrmt,$CTA0("Di2Seg:%0X\iiH,eaxmovebx,ptiLTmoveax,(LmkTableptr[ebx].Di3SeguivokeDbgPrmt,$CTA0("Di3Seg:%0X\nH,eaxmovebx,ptiLTmoveax,(LmkTableptr[ebx].Di6SeguivokeDbgPimt,$CTA0(”Dr6Seg:%0XW,eaxmovebx,ptiLTmoveax,(LiiikTableptr[ebx].Df7SeguivokeDbgPrmt,$CTA0("Di7Seg:%0X\iiH,eaxmovebx,ptiLTmoveax,(LiiikTableptr[ebx].LiiikPtruivokeDbgPrmt,$CTAO("LmkPtr:%OX\iiH,eaxmovebx,ptiLTmoveax,(LiiikTablepti[ebx].NextLnikPtruivokeDbgPrmt,$CTAO(HNextLiiikPti:%OX\ii",eaxpopadretShowLnikTablelnfbendp;判断该线程是否存在;如果不存在则返回o.存在则返回指向该链表的指针,1代表链表为空ExsitsLuikTableprocpHandlepushadmoveax,thieadCxtLuik.if!eax;链表为空pushaduivokeDbgPrmt,$CTAO(n\iiLuikTableIsNull.\ii"popadpopadmoveax,1ret.endif@@:movebx,(LinkTableptr[eax].ThieadHaiidlecmpebx,pHandle;如果匹配已经存在je@Fmoveax,(LinkTableptf[eax].NextLnikPtf.if!eax;已经到达末尾,没有找到匹配pushadmvokeDbgPnnt,$CTAO(H\pHandleIsNotFound.\iinpopadpopadxoieax,eaxret.endifjmp@B@@:pushadmvokeDbgPnnt,$CTAO(,r\iipHandleIsExsits.\iiHpopadmvokeShowLmkTableInfb,eax;返回链表指针movtmpLuik,eaxpopadmoveax,tmpLinkretExsitsLu±Tableendp;拷贝Context到LnikTable中CopyContextToLiiikTablepiocptiContext,ptiLTpushadmovebx,ptiContextmovedx,ptiLTmovecx,4@@:moveax,DWORDpti[ebx十ecx]movDWORDpti[edx+ecx],eaxaddecx,4cmpecx,18hjbe@BpopadretCopyContextToLiiikTableendp;添加LnikTable表AddLiiikTablepiocpHandle,ptiContextpushadmvokeExsitsLiiikTable,pHandle.ifeax>1;已经存在只需要更新dr寄存器即可mvokeCopyContextToLrnkTable,eax,ptiContext.elsepusheaxmvokeExAllocatePool,1,sizeLnikTable.ifeax;申请内存成功movebx,eaxpopeax:置地一个元素movecx,pHandlemov(LinkTablepti[ebx].ThieadHandle,ecx:拷贝dr寄存器的值mvokeCopyContextToLmkTable.ptiContext,ebx:置另外两个元素mov(LinkTablepti[ebx].LuikPti,ebxmov(LinkTablepti[ebx].NextLiiikPti;0mvokeShowLuikTablelnfb,ebx;把新的链表项添加到链表中.ifeax=1;如果链表为空,直接加在表头movtlueadCxtLnik.ebx.else;如果链表不为空则加到末尾moveax,thieadCxtLiiik@@:;指向下一个元素movecx,(LinkTableptf[eax].NextLnikPtftestecx,ecxje@Fmoveax,ecxjmp@B@@:mov(LinkTablepti[eax].NextLuikPti;ebx.endif.else;申请内存失败popeaxpushaduivokeDbgPrmt,$CTAO("\nAllocMemoiyFaild.\iiHpopadjmp@F.endif.endif@@:popadretAddLiiikTableendp;判断进程是否过虑进程;如果是需要过虑的进程返回值为L否则返回0IsFilteiPiocesspiocpushad;获取当前进程名mvokePsGetCunentProcessmovebx,eaxaddebx,nameOffsetmvokeDbgPnnt,$CTA0(,r\ii%s:CallNtGetContextThiead\n”,ebxuivokestincmp,$CTAO(”DNF.exe",ebx,7testeax,eaxjne@Fpopadmoveax,1ret@@:popadxoieax,eaxretIsFilteiPiocessendp;显示Context的调试寄存器ShowDiReglnfbprocptiContextpushadmvokeDbgPnnt,$CTA0(”\nTheContextIiifo:\nMmovebx,ptiContextmoveax,DWORDpti[ebx十4]uivokeDbgPrmt,$CTAO("DiO:%OX\iin,eaxmovebx,ptiContextmoveax,DWORDpti[ebx十8]uivokeDbgPrmt,$CTA0("Di1:%0X\ii",eaxmovebx,ptiContextmoveax,DWORDpti[ebx+Och]uivokeDbgPrmt,$CTA0(”Dr2:%0X\n",eaxmovebx,ptiContextmoveax,DWORDpti[ebx+lOh]uivokeDbgPrmt,$CTA0("Dr3:%0X\ii",eaxmovebx,ptiContextmoveax,DWORDpti[ebx+14h]uivokeDbgPrmt,$CTA0(”Di6:%0X\n",eaxmovebx,ptiContextmoveax,DWORDpti[ebx+18h]uivokeDbgPrmt,$CTA0(”Di7:%0X\n",eaxpopadretShowDiReglnfbendp;恢复被隐藏的di•寄存器RecoveiyDrRegprocptiContext,pHandlepushad;定位到LinkTablemovebx,tlueadCxtLmkNEXT:testebx,ebxjne@F;如果没有遍历完popadret@@:moveax,(LiiikTableptr[ebx].TlueadHandlecmpeax,pHandleje@F;如果找到匹配项movebx,(LiiikTableptr[ebx].NextLiiikPtrjmpNEXT;拷贝完毕后立即结束mvokeCopyContextToLinkTable,ebx,ptiContextxoiebx,ebxjmpNEXTRecoveiyDrRegendp;清空Context的di寄存器CleaiDiRegpiocptrContextpushadmovebx,ptiContextmovecx,4movDWORDpti[ebx+ecx],0ad

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论