驱动过 NP保护原理(驱动过保护)学习各种高级外挂制作技术,马上去百度搜索(魔鬼作坊) ,点击第一个站进入,快速成为做挂达人NP=nProtect GameGuard(如果你不知道这是什么,请不要往下看)一、NP 用户层监视原理NP 启动后通过 WriteProcessMemory 跟 CreateRemoteThread 向所有进程注入代码(除了系统进程 smss.exe) ,代码通过 np 自己的 LoadLibrary 向目标进程加载 npggNT.desnpggNT.des 一旦加载就马上开始干“坏事”,挂钩 (HOOK)系统关键函数如 OpenProcess,ReadProcessMemory,WriteProcessMemory,PostMessage等等挂钩方法是通过改写系统函数头,在函数开始 JMP 到 npggNT.des 中的替换函数用户调用相应的系统函数时, 会首先进入到 npggNT.des模块等待 NP 的检查,如果发现是想对其保护的游戏进行不轨操作的话,就进行拦截,否则就调用原来的系统函数,让用户继续通过对比我们可以发现,NP 把 PostMessageA 函数头原来的 8BFF558BEC 五个字节改为了 E9A69AB8CD,即将 MOV EDI,EDI PUSH EBPMOV EBP,ESP 三条指令改为了 JMP npggNT.458A6630。
所以用户一旦调用 PostMessageA 的话,就会跳转到 npggNT.des 中的 458A6630 中去二、用户层反 NP 监视方法 1,把被 NP 修改了的函数头改回去 上面知道 NP 是通过在关键系统函数头写了一个 JMP 来进行挂钩的,因此,在理论上我们可以通过把函数头写回 去来进行调用 在实际操作的时候, 这种方法并不理想 因为 npggNT.des也挂钩了把函数头改写回去的所有函数, 还有它的监视线程也会进行检校判断它挂钩了的函数是不是被修改回去 因此实现起来很困难, 随时都会死程序2,构建自己的系统函数(感谢 JTR提供) 这种方法适用于代码比较简单的系统函数下面我们看看 keybd_event 的函数源码由上面我们看到 keybd_event 进行了一些参数的处理最后还是调用了 user32.dll 中的 SendInput 函数而下面是 SendInput 的源代码 B8 F6110000 MOV EAX,11F6BA0003FE7F MOV EDX,7FFE0300 FF12 CALL DWORD PTR DS:[EDX] ; ntdll.KiFastSystemCall C2 0C00 RETN 0CSendInput 代码比较简单吧?我们发现 SendInput最终是调用了ntdll.dll中的 KiFastSystemCall函数, 我们再跟下去, KiFastSystemCall 就是这个样子了 8BD4 MOV EDX,ESP 0F34 SYSENTER 最终就是进入了 SYSENTER。
通过上面的代码我们发现一个 keybd_event 函数构建并不复杂因此我们完全可以把上面的代码 COPY 到自己的程 序,用来替代原来的 keybd_eventNP 启动后依然会拦截原来的那个,但已经没关系啦,因为我们不需要用原来 那个 keybd_event 了这种方法适用于源代码比较简单的系统函数,复杂的话实现起来就比较麻烦了我是没有信心去重新构建一 个 PostMessageA,因为其中涉及到 N 个 jmp 和 Call,看起来头都大还有在 VC6 里嵌入汇编经常死 VC(这种事太烦人了),我想不会是我用了盗版的原因吧?3,进入 ring0(感谢风景的驱动鼠标键盘模拟工具)由上面可以看到,NP 用户层的监视不过是修改了一下系统的函数头,进行挂钩监视因此,要反 NP 用户层监视 的话,进入 ring0 的话很多问题就可以解决了比如 WinIO 在驱动层进行键盘模拟,npggNT.des是拦截不到的 但是由于 NP 用了特征码技术,再加上 WinIO 名气太大了,所以 WinIO 在 NP 版本 8××以后都不能用了但是如 果熟悉驱动开发的话,自己写一个也不是很困难的事说了那么多看起来很“高深”的东西,现在说一些象我这样的菜鸟都能明白的东西,呵呵,因为这是菜鸟想出来的 菜办法。
4,断线程 我们知道 NP 是通过 CreateRemoteThread 在目标进程创建远程线程的,还有一点,很重要的一点就是:NP 向目标 进程调用了 CreateRemoteThread 后就什么都不管了,也就是说,凭本事可以对除游戏外的所有进程 npggNT.des 模块进行任何“处置”这样我们可以用一个很简单的方法就是检查自己的线程,发现多余的话(没特别的事情就 是 NP 远程创建的)就马上结束了它,这样 NP 就无法注入了但是由于 windows系统是多任务系统,而 CreateRemoteThread 的执行时间又极短,要在这么短的时间内发现并结 束它的话是一件很困难的事一旦 CreateRemoteThread 执行完毕而我们的监视线程还没有起作用的话,后果就惨 重了,npggNT.des 马上把程序“搞死”因为我们一直试图关闭它的线程, 而 npggNT.des 又拦截了 TerminateThread, 所以我们就只能不断地“重复重复再重复”去试图关闭 npggNT.des 的监视线程如果我们很幸运地在其执行注入代码时就能断了它地线程地话,npggNT.des 就无法注入了。
这种方法在 NP 早期 版本大概有百分之五十的成功率,现在能有百分之一的成功率都不错了5,断线程之线程陷阱 我知道“线程陷阱”这个词肯定不是我首创, 但用“陷阱”这种方法来对付 NP 之前在网上是找不到的 为什么要叫“线 程陷阱”?因为这确确实实是一个陷阱,在 npggNT.des 肯定要经过的地方设置一个“陷阱”,等它来到之后,掉进 去自动就死掉了而搭建陷阱的方法简单得令你难以相信上面我们从 npggNT.des的监视原理可以看到,npggNT.des 要来挂钩(HOOK)我们的系统函数,这种的方法我们也 会,是不是?哪想想,这种挂钩方法需要用到哪些系统函数呢?打开进程 OpenProcess 或 GetCurrentProcess(因为 npggNT.des 已经进入了目标进程,所以没有必要再调用 OpenProcess,肯定是用后者)、找模块地址 GetModelHandle、找函数地址 GetProcAddress、改写函数头的内存属 性 VirtualQuery//得到当前线程 ID if(!IsMyThread(dwThreadId)){//不是我们要保护的线程 ExitThread(0);//断了它吧 } UnhookGetCurrentProcess(); //是我们要保护的线程调用就恢复函数头 HANDLE hProcess=GetCurrentProcess();//让它调用 RehookGetCurrentProcess();//重新挂钩 return hProcess; //返回调用结果 } 这种方法去掉 npggNT.des的监视是完全能够实现的,但是这个函数 IsMyThread(dwThreadId)非常关键,要考虑周 全,不然断错线程的话,就“自杀”了。
6,更简单的陷阱原理跟上面一样,但是我们将替换函数写成这个样子 HANDLE WINAPI MyGetCurrentProcess(VOID)//替换掉原来的 GetCurrentProcess { HMODLE hMod=GetModelHandle(“npggNT.des“); if(hMod!=NULL){ FreeLibrary(hMod); //直接 Free掉它 } UnhookGetCurrentProcess(); //是我们要保护的线程调用就恢复函数头 HANDLE hProcess=GetCurrentProcess();//让它调用 RehookGetCurrentProcess();//重新挂钩 return hProcess; //返回调用结果 } 这种方法就万无一失了,不用担心会“自杀”三、总结由上面可以看到在用户层上反 NP 监视是不是很简单的事?最简单有效的就是第六种方法,短短的几行代码就可 以搞定了但是不要指望去掉了 npggNT.des 就可以为所欲为了,还有 NP 还在驱动层做了很多手脚,比如 WriteProcessMemory 在用户层用没问题,但是过不了 NP 的驱动检查,对游戏完全没效果。
要在 NP 下读写游戏内 存,说起来又另一篇文章了《如何在 NP 下读写游戏内存》 ,请继续关注学习各种高级外挂制作技术,马上去百度搜索(魔鬼作坊) ,点击第一个站进入,快速成为做挂达 人。