宝峰科技

 找回密码
 注册

QQ登录

只需一步,快速开始

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

[转贴] C++实现远程注入调用游戏CALL

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

    [LV.7]常住居民III

    admin 发表于 2010-5-18 01:20:28 | 显示全部楼层 |阅读模式

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

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

    x
    1.引申
         计算机发展历程从单道技术道多道技术,到后来的分时技术,为了解决资源的高效分配和CPU利用率的提高,引入进程的概念可以说是一个操作系统的一个里程碑。这里不多引申,主要是想说明,系统里各个进程的运行是相互独立的,每个进程独享自己的进程空间。在单CPU上,微观上各个进程串行运作,但是宏观上表现为各个进程是并行处理。进程只是 一个“容器”,它复杂向系统申请资源,真正的执行操作的是线程。这里仅仅是简单的说说...
         在进程加载的时候,代码被映射到进程的地址空间中,然后利用各种分页分段技术,在运行期将代码映射到具体的物理内存上,方可执行。Windows下进程的地址空间在逻辑上是相互独立的,而在物理上却是相互重叠的,所谓的重叠是指在一块内存区域可能被多个进程同时使用(共享内存便是这个原理)。
    2.注入的原理
         上面说了进程的地址空间是相互独立的,那么怎么使本进程的代码(比如一个CALL函数)在目标进程里运行呢,那就需要注入了。将代码利用一定的技术手段加载进目标进程空间,然后触发使之执行,这便是代码注入的雏形。当然,后来的技术做了很多“变种”,以至于这种技术被病毒技术得到了很好的利用。
          明白了上面的原理,就可以自己进行我们下面的这个实例了。
          我们调用完美游戏的CALL,必须要吧代码写进完美游戏进程地址空间,有关于这一系列的操作,Windows提供了相应的API,我也把它封装了成函数,中间过程的一些重要的细节等会解剖。
    3.远程注入
        这是一种比较普遍的做法,但是也有着明显的缺点,频繁的注入比较容易产生内碎片的大量累积。当然,有改进的做法,比如固定申请的地址,一次申请,多次利用,这里不在多说。
        这里仅作为技术探讨,列出主要的实现步骤。分二层实现,稍作了封装
        我们以带参数的选怪CALL为例:
    1. void  CallSelectMonster (long MonsterSn)
    2. {

    3. DWORD dwAddr = 0x59B8B0;
    4. _asm{
    5.   pushad
    6.   mov edi , MonsterSn
    7.   push edi
    8.   mov eax , dword ptr [0x950954]
    9.   mov eax , dword ptr [eax]
    10.   mov ecx , dword ptr [eax + 0x20]
    11.   add ecx , 0xec
    12.   call dwAddr
    13.   popad
    14. }
    15. }
    复制代码

          这里CALL存在问题,等会解决
       
        1>. 第一层调用:选怪函数,里面封装了调用注入函数的操作。
    1. void CSkill::SelectMonster(DWORD ProcessId, long MonsterSn)
    2. {
    3. long * m_pGuaiId = & MonsterSn ;

    4. //调用注入函数
    5. InjectRemoteFunc(ProcessId,CallSelectMonster,m_pGuaiId,sizeof(*m_pGuaiId));
    6. }
    复制代码

       
          2>.封装注入代码并调用执行的操作。

    1. //封装远程注入的函数
    2. //参数 1. 进程ID
    3. //参数 2. 被注入函数指针<函数名>
    4. //参数 3. 参数
    5. //参数 4. 参数长度

    6. BOOL InjectRemoteFunc(DWORD dwProcId,LPVOID mFunc, LPVOID pRemoteParam, DWORD ParamSize)
    7. {
    8. HANDLE hProcess;
    9. LPVOID ThreadAdd;
    10. LPVOID ParamAdd = NULL;
    11. HANDLE hThread  = NULL;
    12. DWORD lpNumberOfBytes;
    13. BOOL BO;
    14. ThreadAdd = mFunc;
    15. hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcId);//打开被注入的进程
    16. ThreadAdd = VirtualAllocEx(hProcess,NULL,4096,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
    17. BO = WriteProcessMemory(hProcess,ThreadAdd,mFunc,4096, &lpNumberOfBytes); //写入函数地址
    18. if(ParamSize!=0)
    19. {
    20.   ParamAdd = VirtualAllocEx(hProcess,NULL,ParamSize, MEM_COMMIT, PAGE_READWRITE);
    21.   BO = WriteProcessMemory(hProcess, ParamAdd, pRemoteParam, ParamSize, &lpNumberOfBytes); //写入参数地址
    22. }
    23. hThread = CreateRemoteThread(hProcess, NULL,0,(LPTHREAD_START_ROUTINE)ThreadAdd, ParamAdd, 0,&lpNumberOfBytes); //创建远程线程
    24. WaitForSingleObject(hThread, INFINITE);//等待线程结束
    25. VirtualFreeEx(hProcess, ThreadAdd, 4096, MEM_RELEASE);
    26. if(ParamSize!=0)
    27. {
    28.   VirtualFreeEx(hProcess, ParamAdd, ParamSize, MEM_RELEASE); //释放申请的地址
    29. }
    30. CloseHandle(hThread);
    31. CloseHandle(hProcess);
    32. return TRUE;
    33. }
    复制代码

    4.分析
        会C++的朋友可以马上要它运行起来,哪怕是控制台下,只要获得了窗口句柄,赋值一个比较合适的怪物ID,做个循环加,都可以实现选怪了。其他附加的代码我不贴出来了,前面说了,这是写给有一定基础的辅助编程的朋友学习讨论的。
        我在前面留了一个小的bug,这也是我主要写这篇教程的原因之一。在处理这个问题的时候,我也郁闷了好一阵,但最后还是解决了。如果现在能看出来bug的朋友,并知道为什么会有这样bug的朋友,可以不用看了,呵呵。
        1>为了说明这个问题,我想引入msdn里的一些说明:
        首先,创建远程线程的函数原型:
    1. HANDLE CreateRemoteThread(
    2.   HANDLE hProcess,                          // handle to process
    3.   LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
    4.   SIZE_T dwStackSize,                      // initial stack size
    5.   LPTHREAD_START_ROUTINE lpStartAddress,    // thread function
    6.   LPVOID lpParameter,                      // thread argument
    7.   DWORD dwCreationFlags,                    // creation option
    8.   LPDWORD lpThreadId                        // thread identifier
    9. );   
    复制代码

        看第四个参数,也就是回调函数(由用户编写,但调用权限由操作系统主宰的函数) ,当调用了这个创建远程线程的函数,只要这个倒数第二个参数设置为0,也就是dwCreationFlags=0,那么回调函数将会立即执行。
        现在看看回调函数的原型:
       
    1. DWORD WINAPI ThreadProc(
    2.     LPVOID lpParameter  // thread data
    3.     );
    复制代码

      发现该函数只接收一个LPVOID类型的参数,那么如果这个参数不是指针行不行呢,当然可行了,呵呵,现在明白了吧,前面的带参数CALL相当于这个“回调函数”,只是样子变了一下而已,这个思想很重要    那么现在改下CALL原型,变成这样就OK了
    1. void  CallSelectMonster (long * MonsterSn)
    2. {
    3. long sn = *MonsterSn;
    4. DWORD dwAddr = 0x59B8B0;
    5. _asm{
    6.   pushad
    7.   mov edi , sn
    8.   push edi
    9.   mov eax , dword ptr [0x950954]
    10.   mov eax , dword ptr [eax]
    11.   mov ecx , dword ptr [eax + 0x20]
    12.   add ecx , 0xec
    13.   call dwAddr
    14.   popad
    15. }
    16. }  
    复制代码

          到这里,都明白了吧,前面CALL的原型就是错误的,也就是不匹配,当调用创建远程线程时,参数传递就出现问题了。
          作为引申,观察另外一个函数的原型:
       
    1. HMODULE LoadLibrary(
    2.     LPCTSTR lpFileName  // file name of module
    3.     );
    复制代码


        比较一下

       
    1. DWORD WINAPI ThreadProc(
    2.     LPVOID lpParameter  // thread data
    3.     );
    复制代码

       
        原型一样,那么可以用LoadLibrary来作这个“回调函数”,又一个变形的回调函数,那么就可以轻松的将一个DLL注入的目标进程了,并且在DLL初始化的时候做很多事情。
    5.又一种注入DLL的方式,全局DLL注入
       说下实现的步骤和思想。这种方式可以用 hook + DLL来实现:
       1>.安装一个钩子,将钩子回调函数写在DLL里,在回调函数里new PerfectDialog() ,创建一个窗口,方便操作。
       2>.安装这个钩子,消息触发回调函数,那么指定的进程就会加载这个DLL了,这个进程当然就是你所要操作的进程。这个时候,DLL里代码操作的数据就和目标进程空间里的数据通用了。貌似很爽,调用CALL就好像调用自己进程空间的CALL一样,不用在进程注入了。但是,也会引发一些其他的问题,应该就是对于异常的考虑。比如,用指针读相关数据,指针+偏移,在读相关数据,这些操作都是要进行异常判断。这里不在用ReadProcessMemoryWriteProcessMemory函数,那么,这些操作你就是考虑自己封装,理论上就像是模拟一个自己进程空间的读写函数。呵呵,不是很难,但是也需要一些技巧。
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    免责声明

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

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

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

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