易语言教程_易语言源码_易语言视频教程_易语言论坛

 找回密码
 点击注册

Vip新手入门区
新手学习指南  学员作品展示 Vip课程总纲  Vip绝密课程系列

Vip相关下载区
Vip模块下载   Vip模块绑定   Vip模块例子 魔鬼插件下载  魔鬼插件例子  教程工具下载

Vip论坛服务区
教程问题提问区   模块问题提问区 技术交流区   魔鬼插件建议   忘记密码找回

VIP会员办理QQ: 8643245   
【请先加好友,然后到好友列表双击联系客服,办理VIP会员。】
【基础篇】易语言辅助入门基础教程
VIP模块办理QQ: 7189694 办理正版魔鬼作坊VIP模块 【基础篇】OD与CE入门基础教程
办理【终身VIP会员】“秒杀价” 仅需 RMB278.00元… 【基础篇】零基础绝密汇编语言入门课程 (共26课已完成)…
办理VIP详情…猛击这里查看详情 【基础篇】VIP辅助入门基础教程-新手必学 已发布10课 ……
VIP教程免费试看章节…猛击下载 【第1款】制作“辅助挂”教程目录查看(共107+16_x64下更新课已完成)…
亲爱的VIP学员,请到此写下你学习的感受与发布作品截图… 【第2款】制作“任务挂”教程目录查看(共77+1_x64下更新课已完成)…
卍解吧!不用bp send类封包断点找CALL的各种通杀思路 【第3款】驱动过保护技术课程(共38课已完成)…
【绝密教程】VIP绝密教程系列---注意:随时会更新! 【第4款】VIP邪恶二叉树辅助课程 (共31+17_x64下更新课已完成)…
【精品第13款】3D射击游戏与页游透视 智辅课程 已完成17课… 【第5款】零基础易语言按键辅助教程 (30课已完成)…
【精品第14款】变态功能辅助是如何炼成的 已完成36课… 【第6款】从零开始学习封包辅助技术教程(20课已完成) …
【精品第15款】DNF商业变态辅助的修炼之路 已完成27课… 【第7款】大杀特杀分析来源与CALL吸血鬼课程 (56课已完成)
【精品第16款】中控台多线程多开自动化商业辅助课程 已完成66课… 【第8款】完全零基础网页辅助课程(40课已完成)
【全新精品第17款】检测原理与过游戏内存检测技术课程 已发布9课… 【第9款】自动登录与操控LUA技术课程 (共46+8_x64下更新课已完成)…
【全新精品第18款】手游全自动化任务脚本辅助课程 已发布25课…… 【第10款】网页辅助封包脱机进阶课程 已完成30课…
【全新精品第19款】D3D方框骨骼透视与自瞄辅助课程进阶篇 已发布34课…… 【第11款】VC++ Lua脚本辅助课程 已完成112课…
【全新精品第20款】 X64模拟器吃鸡游戏方框透视自瞄辅助课程 发布中... 【第12款】网游脱机封包智辅课程 已完成35课…
查看: 1315|回复: 0

代码注入和CALL游戏中的功能函数一点技巧

[复制链接]

8

主题

12

回帖

18

积分

编程入门

Rank: 1

魔鬼币
592
发表于 2017-5-30 08:13:06 | 显示全部楼层 |阅读模式

获得目标进程句柄就从略了。直接从注射开始:

HANDLE CRemoteCodeDlg::InjetionCode(HANDLE hProcess, LPVOID pCode, LPVOID pParam)
{
    HANDLE RemoteThand;
    LPVOID CodeAddress = NULL;
    LPVOID DataAddress = NULL;
    DWORD  RetByte,Tid,CodeSize,AllRemoteMemSize;

    if(! hProcess || INVALID_HANDLE_VALUE == hProcess)
    {
        return HANDLE(0);
    }
     
    CodeSize = DWORD(PCHAR(GETVCPROC_ADDRESS(GetVCProcAddress)) - PCHAR(GETVCPROC_ADDRESS(ISee)));
    AllRemoteMemSize = CodeSize +  MEMCODEPARAM_SIZE + sizeof(DWORD);

    CodeAddress = VirtualAllocEx(hProcess,NULL,AllRemoteMemSize,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
    if(! CodeAddress)
    {         
        return HANDLE(0);
    }
     
    if(! WriteProcessMemory(hProcess,CodeAddress,pCode,CodeSize,&RetByte))
    {         
        VirtualFreeEx(hProcess,CodeAddress,AllRemoteMemSize,MEM_DECOMMIT);
        CodeAddress = NULL;
        return HANDLE(0);
    }
    DataAddress = LPVOID(DWORD(CodeAddress) + sizeof(DWORD) & ~3);

    if(! WriteProcessMemory(hProcess,DataAddress,pParam,MEMCODEPARAM_SIZE,&RetByte))
    {         
        VirtualFreeEx(hProcess,CodeAddress,AllRemoteMemSize,MEM_DECOMMIT);
        CodeAddress = NULL;
        return HANDLE(0);
    }

    RemoteThand = CreateRemoteThread(hProcess,NULL,0,LPTHREAD_START_ROUTINE(CodeAddress),
        DataAddress,CREATE_SUSPENDED,&Tid);

    m_pRemoteAllocMem = CodeAddress;
    m_RemoteMemSize = AllRemoteMemSize;

    return RemoteThand;
}

        首先说说这个被注射代码的大小问题,这个问题我在很多论坛上看到过。但是回答的人都是用估计值作答。实际上这个难题也很好理解,因为你写得不是机器代码,自然无法计算最后生成的执行的机器代码字节数。(玩笑话,编译器知道,但他不会告诉你。呵呵)。

    汇编语言可以很轻松的获得这个值,原因同上。

    难道我们就无法确定了吗?NO,让编译器告诉我们,不要吃惊,方法如下:
int Func1(void)
{
    -------------------------------
  --------------------------------
}

void Func2(void)
{

}

    假设Func1是要注射的代码,要求的Func1编译后的代码大小:

  Func1Size = Func2 - Func2;
原理:
   
  实际上如果你对编译器比较熟悉的话,就会知道实际上函数名就是编译过程中的一个地址标号。因此用高地址标号减去低的就是我们想要得。有人要问:你怎末知道编译器一定会把Func2放在Func1之后哪?我的回答是:可能有反向的。但目前我见到的VC \ BC \ BCB \ SC(赛门铁克)都是这末做的。

我的码如下:

CodeSize = DWORD(PCHAR(GETVCPROC_ADDRESS(GetVCProcAddress)) - PCHAR(GETVCPROC_ADDRESS(ISee)));

这个GETVCPROC_ADDRESS是一个宏,定义如下:

#ifdef _DEBUG     
    #define GETVCPROC_ADDRESS(Fn)  GetVCProcAddress(Fn)
#else
    #define GETVCPROC_ADDRESS(Fn)  Fn
#endif

    为什莫定义这个?直接用Fn2 - Fn1不就好了吗?NO,这又引出了一个概念:VC的编译器有个特点从6.0到现在的9.0都是如此。在你选择Debug版本编译时,所有的函数调用都会被编译为一个间接的调转指令。就像调用系统API一样。在编译器内部型如:

JMP @IAT_Fn1@这个鬼样子。

而在Release版本时就变成了直接调用。所以为了调试方便就定义了此宏。Debug宏实现如下:

LPVOID GetVCProcAddress(LPVOID pFn)
{
    PCHAR pAddRess = (PCHAR)pFn;

    pAddRess ++;        //跳过@IAT的第一个指令jmp

    pAddRess +=  *(DWORD *)pAddRess;
    pAddRess += 4;        //修正指针类型偏移

    return pAddRess;
}

好了,再看看这个:

AllRemoteMemSize = CodeSize +  MEMCODEPARAM_SIZE + sizeof(DWORD);

        全部分配的内存大小为什用代码尺寸大小(CodeSize) + 参数块大小(MEMCODEPARAM_SIZE)还要再加一个sizeof(DWORD)哪?我只说是为了数据对齐,如何保证后拷贝的数据块能正好放在一个4字节对齐的开始地址哪?看看下面这行代码你就明白了。

DataAddress = LPVOID(DWORD(CodeAddress) + sizeof(DWORD) & ~3);

        至于经常有人说直接注射的代码无法调用API的问题,我觉得更加荒谬。他们的理由无非是,本地进程的API地址跟目标进程的API地址不一致。是的,这个我也承认。但是你可以用LoadLibRary和GetProcAddress来获取目标进程中的API地址。你不用跟我说这两个地址怎末来?实际上 Kernel32.dll在每个进程中的加载地址都一样。
您需要登录后才可以回帖 登录 | 点击注册

本版积分规则

魔鬼作坊|易语言教程|易语言源码|易语言论坛|易语言视频教程| 论坛导航|免责申明|手机版||网站地图
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表魔鬼作坊立场!
任何人不得以任何方式翻录、盗版或出售本站视频,一经发现我们将追究其相关责任!
我们一直在努力成为最好的编程论坛!
Copyright© 2010-2019 All Right Reserved.
快速回复 返回顶部 返回列表