宝峰科技

 找回密码
 注册

QQ登录

只需一步,快速开始

智能终端设备维修查询系统注册会员邮箱认证须知!
查看: 2161|回复: 0

[推荐] 如何在NP下读写游戏内存及如何进入NP进程

[复制链接]
  • TA的每日心情
    开心
    2024-12-9 18:45
  • 签到天数: 124 天

    [LV.7]常住居民III

    admin 发表于 2010-6-14 12:54:51 | 显示全部楼层 |阅读模式

    欢迎您注册加入!这里有您将更精采!

    您需要 登录 才可以下载或查看,没有账号?注册

    x
    在一篇文章《反NP监视原理》中说到要去掉NP的注入是很容易的事,但是去掉npggNT.des并不是说我们想对游戏怎么样都可以了,NP还挂钩了很多内核函数,所以很多关键系统函数就算我们在用户层能用也对游戏没有什么效果。如果想在不破解NP前提下读写游戏内存该怎么办呢,办法至少有两个:
    一、用驱动
    在驱动下读写游戏内存是没问题,但是由于我不懂驱动,所以也没什么可说。
    二、进入游戏进程
    在用户层,如果我们想在不破解NP的前提下读写游戏内存的话,大概就只能进入游戏进程了。因为很简单,我们的程序无法对游戏使用OpenProcess、ReadProcessMemoery及WriteProcessMemory这些函数(就算是去掉了NP监视模块npggNT.des),而NP又不可能限制游戏自身使用这些函数,所以只要我们能够进入游戏进程就能够读写游戏的内存。


    怎么进入游戏呢?下面介绍两种方法:
    1,最简单的办法
    —全局消息钩子(WH_GETMESSAGE)
    看似很复杂的东西原来很简单就可以实现,大道至易啊。使用消息钩子进入游戏进程无疑是最简单的一种方法,具体编程大概象这样:一个消息钩子的DLL,里面包含一个消息回调函数(什么都不用做),读写内存过程,跟主程序通讯过程或操作界面过程,当然在DLL_PROCESS_ATTACH要判断当前的进程是不是游戏的,是的话就做相应的处理;一个安装全局消息钩子的主程序。大概这样就可以了。使用全局消息钩子的好处是简单易用,但是不足之处是要在游戏完全启动(NP当然也启动啦)后才能进入,如果想在NP启动前做一些什么事的话是不可能的。
    另外也简单介绍一下防全局钩子的办法,Windows是通过调用LoadLibraryExW来向目标进程注入钩子DLL的,所以只要我们在钩子安装前挂钩了这个函数,全局钩子就干扰不了了。
    2,更麻烦的办法

    远程注入
    知道远程注入方法和原理的人可能会说“有没有搞错,OpenProcess、WriteProcessMemory这些必备函数都不能用,怎么注入?”,当然啦,NP启动后是不能干这些事情,所以我们要在NP启动前完成。这样一来,时机就很重要了。
    游戏启动的流程大概是这样:游戏Main->GameGuard.des->GameMon.des(NP进程)。这里的做法是这样:游戏Main->GameGuard.des(暂停)->注入DLL->GameGuard.des(继续)->GameMon.des。关键点就是让GameGuard.des暂停,有什么办法?想到一个是全局消息钩子(还是少不了它啊)。要实现大概需要做下面的工作:一个全局消息钩子DLL,里面只要一个消息回调函数(什么都不用做),DLL_PROCESS_ATTACH下进行当前进程判断找GameGuard.des,找到的话就向主程序SendMessage;主程序,负责安装钩子,接收钩子DLL发来的消息,接收到消息就开始查找游戏进程,向游戏进程注入内存操作DLL,返回给SendMessage让GameGuard.des继续,卸载钩子(免得它继续钩来钩去);内存操作DLL,负责对游戏内存进行操作。
    具体编写如下(有省略):
    1. ////////////////////////////////////////////////GameHook.cpp//////////////////////////////////////////////////////////////////
    2. BOOL IsGameGuard();
    3. //////////////////////////////////
    4. LRESULT CALLBACK GetMsgProc(int nCode,WPARAM wParam,LPARAM lParam)
    5. {
    6. return (CallNextHookEx(m_hHook,nCode,wParam,lParam));//什么都不需要做
    7. }
    8. ///////////////////////////////////////
    9. BOOL WINAPI DllMain(HINSTANCE hInst,DWORD dwReason,LPVOID lp)
    10. {
    11. switch(dwReason){
    12. case DLL_PROCESS_ATTACH:
    13. if(IsGameGuard())//判断当前进程是不是GameGuard.des
    14. SendMessage(m_hwndRecv,WM_HOOK_IN_GAMEGUARD,NULL,NULL);//向主窗体发送消息,SendMessage是等待接受窗体处理完毕才返回的,
    15. break; //所以进程就暂停在这里,我们有足够的时间去做事情
    16. case DLL_PROCESS_DETACH:
    17. break;
    18. }
    19. return TRUE;
    20. }
    21. ///////////////////////////////////
    22. GAMEHOOKAPI BOOL SetGameHook(BOOL fInstall,HWND hwnd)
    23. {
    24. ...
    25. }
    26. ////////////////////////////////////////
    27. BOOL IsGameGuard()
    28. {
    29. TCHAR szFileName[256];
    30. GetModuleFileName(NULL,szFileName,256);
    31. if(strstr(szFileName,"GameGuard.des")!=NULL){//这样的判断严格来说是有问题的,但实际操作也够用了。当然也可以进行更严格的判断,不过麻烦点
    32. return TRUE;
    33. }
    34. return FALSE;
    35. }
    36. //////////////////////////////////////////////////////Main////////////////////////////////////////////////////////////////////////
    37. void OnGameGuard(WPARAM wParam,LPARAM lParam)//处理消息钩子DLL发来的消息就是上面SendMessage的那个
    38. {
    39. DWORD dwProcessId=FindGameProcess(m_strGameName);//开始查找游戏进程
    40. if(dwProcessId==0){
    41. MessageBox(m_hWnd,"没有找到游戏进程","查找游戏进程",MB_OK);
    42. return;
    43. }

    44. if(!InjectDll(dwProcessId)){//查找到就开始注入
    45. MessageBox(m_hWnd,"向游戏进程注入失败",注入",MB_OK);
    46. return;
    47. }
    48. }
    49. /////////////////////////////////////////////////
    50. DWORD FindGameProcess(LPCSTR szGameName)//负责查找游戏进程
    51. {
    52. HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    53. if(hSnapshot==INVALID_HANDLE_VALUE)
    54. return 0;
    55. PROCESSENTRY32 pe={sizeof(pe)};
    56. DWORD dwProcessID=0;
    57. for(BOOL fOK=Process32First(hSnapshot,&pe);fOK;fOK=Process32Next(hSnapshot,&pe)){
    58. if(lstrcmpi(szGameName,pe.szExeFile)==0){
    59. dwProcessID=pe.th32ProcessID;
    60. break;
    61. }
    62. }
    63. CloseHandle(hSnapshot);
    64. return dwProcessID;
    65. }
    66. /////////////////////////////////////////////////
    67. BOOL InjectDll(DWORD dwProcessId)//负责注入,参考自Jeffrey Richter《windows核心编程》
    68. {
    69. CString strText;
    70. char* szLibFileRemote=NULL;

    71. HANDLE hProcess=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE,FALSE,dwProcessId);
    72. if(hProcess==NULL){
    73. // SetRecord("Open game process failed!");
    74. return FALSE;
    75. }
    76. int cch=lstrlen(szDll)+1;
    77. int cb=cch*sizeof(char);
    78. szLibFileRemote=(char*)VirtualAllocEx(hProcess,NULL,cb,MEM_COMMIT,PAGE_READWRITE);
    79. if(szLibFileRemote==NULL){
    80. // SetRecord("Alloc memory to game process failed!");
    81. CloseHandle(hProcess);
    82. return FALSE;
    83. }

    84. if(!WriteProcessMemory(hProcess,(LPVOID)szLibFileRemote,(LPVOID)szDll,cb,NULL)){
    85. // SetRecord("Write game process memory failed!");
    86. CloseHandle(hProcess);
    87. return FALSE;
    88. }

    89. PTHREAD_START_ROUTINE pfnThreadRtn=(PTHREAD_START_ROUTINE)
    90. GetProcAddress(GetModuleHandle(TEXT("kernel32")),"LoadLibraryA");
    91. if(pfnThreadRtn==NULL){
    92. // SetRecord("Alloc memory to game process failed!");
    93. CloseHandle(hProcess);
    94. return FALSE;
    95. }

    96. HANDLE hThread=CreateRemoteThread(hProcess,NULL,0,pfnThreadRtn, szLibFileRemote,0,NULL);
    97. if(!hThread)
    98. {
    99. // SetRecord("Create remote thread failed!");
    100. CloseHandle(hProcess);
    101. return FALSE;
    102. }
    103. if(hThread!=NULL)
    104. CloseHandle(hThread);
    105. CloseHandle(hProcess);
    106. return TRUE;

    107. }
    复制代码



    这种方法比一个全局消息钩子麻烦一点,但是优点是显然易见的:可以在NP启动前做事情,比如HOOK游戏函数或做游戏内存补丁。下面进入NP进程还要用到这种方法。

    三、进入NP进程
    如果我们对NP有足够的了解,想对它内存补丁一下,来做一些事情,哪又怎样才可以进入NP的进程呢?嗯,我们知道游戏启动流程是这样的游戏Main->GameGuard.des->GameMon.des(NP进程),其中GameGuard.des跟GameMon.des进程是游戏Main通过调用函数CreateProcessA来创建的,上面我们说到有办法在NP进程(GameMon.des)启动前将我们的DLL注入到游戏进程里,因此我们可以在GameMon.des启动前挂钩(HOOK)CreateProcessA,游戏创建NP进程时让NP暂停,但是游戏本来创建NP进程时就是让它先暂停的,这步我们可以省了。下面是游戏启动NP(版本900)时传递的参数:
    ApplicationName:C:\惊天动地Cabal Online\GameGuard\GameMon.des
    CommandLine:\x01\x58\x6d\xae\x99\x55\x57\x5d\x49\xbe\xe4\xe1\x9b\x14\xe6\x88\x57\x68\x6d\x11\xb9\x36\x73\x38\x71\x1e\x88\x46\xa9\x97\xd4\x3a\x20\x90\x62\xae\x15\xcd\x4b\xcd\x72\x82\xbd\x75\x0a\x54\xf0\xcc\x01\xad
    CreationFlags:4
    Directory:
    其中的CommandLine好长啊,它要传递的参数是:一个被保护进程的pid,两个Event的Handle,以及当前timeGetTime的毫秒数 (感谢JTR分享)。
    CreationFlags:4 查查winbase.h头文件,发现#define CREATE_SUSPENDED 0x00000004,所以NP进程创建时就是暂停的

    在我们替换的CreateProcessA中,先让游戏创建NP进程(由于游戏创建时NP进程本来就是暂停的,所以不用担心NP的问题),让游戏进程暂停(SendMessage就可以了),然后再向NP进程注入DLL,最后让游戏进程继续。这样我们的DLL就进入NP进程了。实现起来大概是这样子
    1. BOOL
    2. WINAPI
    3. MyCreateProcessA(//替换原来的CreateProcessA
    4. LPCSTR lpApplicationName,
    5. LPSTR lpCommandLine,
    6. LPSECURITY_ATTRIBUTES lpProcessAttributes,
    7. LPSECURITY_ATTRIBUTES lpThreadAttributes,
    8. BOOL bInheritHandles,
    9. DWORD dwCreationFlags,
    10. LPVOID lpEnvironment,
    11. LPCSTR lpCurrentDirectory,
    12. LPSTARTUPINFOA lpStartupInfo,
    13. LPPROCESS_INFORMATION lpProcessInformation
    14. )
    15. {
    16. UnhookCreateProcessA();
    17. BOOL fRet=CreateProcessA(lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,
    18. lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation);
    19. RehookCreateProcessA();
    20. SendMessage(hwndRecv,//负责注入的窗体句柄
    21. WM_HOOK_NP_CREATE,//自定义消息
    22. (WPARAM)lpProcessInformation->dwProcessId,//把NP进程ID传给负责注入的主窗体
    23. NULL);
    24. return fRet;
    25. }
    复制代码

    四、注意问题
    由于我们是在不破解NP的前提下对游戏内存进行操作,所以一不小心的话,很容易就死游戏。NP保护了游戏进程的代码段,所以在NP启动后就不要再对其代码段进行修改,要补丁或HOOK系统函数这些都要在NP启动前完成。当然读写游戏的数据段是没问题的,因为游戏本身也不断进行这样的操作。
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    免责声明

    本站中所有被研究的素材与信息全部来源于互联网,版权争议与本站无关。本站所发布的任何软件编程开发或软件的逆向分析文章、逆向分析视频、补丁、注册机和注册信息,仅限用于学习和研究软件安全的目的。全体用户必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。学习编程开发技术或逆向分析技术是为了更好的完善软件可能存在的不安全因素,提升软件安全意识。所以您如果喜欢某程序,请购买注册正版软件,获得正版优质服务!不得将上述内容私自传播、销售或者用于商业用途!否则,一切后果请用户自负!

    QQ|Archiver|手机版|小黑屋|联系我们|宝峰科技 ( 滇公网安备 53050202000040号 | 滇ICP备09007156号-2 )

    Copyright © 2001-2023 Discuz! Team. GMT+8, 2025-5-8 13:55 , File On Powered by Discuz! X3.49

    快速回复 返回顶部 返回列表