首页
社区
课程
招聘
[原创]iOS 游戏辅助之游戏加速浅析
发表于: 2017-9-19 19:23 41534

[原创]iOS 游戏辅助之游戏加速浅析

2017-9-19 19:23
41534
 

相对于Android APP,针对iOS APP的分析和破解要少得多,这也导致上线AppStore的绝大部分应用都是裸奔的。这篇文章将对iOS平台的一款游戏加速辅助进行分析,分享给大家。

一、基础知识

这款游戏加速器是以动态库方式注入到APP中加载运行的,其介绍说只能在越狱手机运行,因为动态库的注入依赖于框架:MobileSubstrate。但是在非越狱手机也可以实现注入的,一个方便的框架可以参考 MonkeyDev

 

动态库本质是一个Mach-O格式的文件,和WindowsDLL文件、Linuxso文件作用类似。其不能直接运行,而是通过系统链接加载器dyld完成加载和初始化。dyld是开源的,可在 Source Browser 查看。简单介绍下动态库dylib的加载过程:

  • 1、系统内核加载dyld,执行其中的__dyld_start()函数
  • 2、初始化运行环境,如setContext(mainExecutableMH, ...)
  • 3、加载共享缓存,这个是为了优化程序启动,即映射在内存的动态库只会加载一次
  • 4、加载DYLD_INSERT_LIBRARIES指定的动态库
  • 5、链接主程序,如link(sMainExecutable, ...)
  • 6、链接依赖的动态库
  • 7、弱符号绑定
  • 8、调用所有的初始化方法,包括动态库的构造器,load方法等
  • 9、查找主程序的入口点然后返回

二、加速器原理

2.1 构造器入口

本节主要使用 Hopper Disassembler 来进行分析。Hopper分析完成后如下图所示:

 

Alt pic

 

其中加速器的构造器函数为:__GLOBAL__sub_I_MFAccelerator.mm。反编译结果如下:

int __GLOBAL__sub_I_MFAccelerator.mm() {
    sp = sp - 0x1c;
    if (objc_getClass("UnityAppController") == 0x0) goto loc_510a;

loc_50d6:
    *0x87a0 = 0x1;
    MSHookMessageEx();
    goto loc_5150;

loc_5150:
    r0 = [[NSDistributedNotificationCenter defaultCenter] addObserver:[MFAcceleratorMgr sharedMgr] selector:@selector(handleDistributedNotification:) name:[NSString stringWithUTF8String:"com.cyjh.ifengwoo.port.accelerator"] object:0x0];
    return r0;

.l1:
    return r0;

loc_510a:
    r4 = objc_getClass("EAGLView");
    r0 = objc_getClass("CCEAGLView");
    r0 = r0 | r4;
    if (r0 == 0x0) goto .l1;

loc_512c:
    MSHookFunction();
    goto loc_5150;
}

其区分了游戏的类型:U3Dcocos2d。伪代码如下:

Class u3d = objc_getClass("UnityAppController");
if(u3d) {
    MSHookMessageEx(u3d, @selector(application:didFinishLaunchingWithOptions:), (IMP)fake_unity3d_finish_launching, &ori_unity3d_finish_launching)
} else {
    Class cocos2d_f1 = objc_getClass("EAGLView");
    Class cocos2d_f2 = objc_getClass("CCEAGLView");
    if(cocos2d_f1 || cocos2d_f2) {
        MSHookFunction((void *)gettimeofday, (void *)mygettimeofday, (void **)&orig_gettimeofday);
    }
}

可以看见,对于 cocos2d,其是通过内联HOOK gettimeofday函数完成的。而对U3D游戏相关时间函数的内联HOOK是在fake_unity3d_finish_launching中完成的,其的反编译代码很长,这儿只给出了关键的部分:

int __ZL29fake_unity3d_finish_launchingP10objc_classP13objc_selectormm(void * arg0, void * arg1, long arg2, long arg3) {
    ...
    r4 = dlsym(0x1 ^ 0xffffffff, "vm_region");
    r0 = 0x3972;
    asm{ vmov.i32   q4, #0x0 };
    r5 = sp + 0x38;
    r8 = 0x0;
    *(r0 + 0x4e1e) = r4;
    stack[2026] = _mach_task_self_;
    goto loc_4e54;
    ...
loc_4f48:
    MSHookFunction();
    goto loc_4f62;
    ...
loc_4f48:
    MSHookFunction();
    goto loc_4f62;
}

通过动态调试发现:U3D游戏的内联HOOK是通过内存搜索特征串得到的。大致流程如下:

  • 1、使用vm_region获取当前可执行文件的内存空间
  • 2、在此内存空间搜索两个特征串,如下:

    Alt pic

  • 3、只有在这两个特征串都存在的情况下,才会内联HOOK。至于这两个特征串的含义,笔者暂时不知。

  • 4、然后在距这两个特征串特定的位置进行内联HOOK,如下:

    Alt pic
    Alt pic

对于不同的U3D程序,特征串在的位置并不固定。

2.2 cocos2d 游戏加速

cocos2d的游戏加速实现主要在__ZL13$gettimeofdayP7timevalPv中,主要反编译逻辑如下:

int __ZL13$gettimeofdayP7timevalPv(void * arg0, void * arg1) {
    r4 = arg0;
    r2 = *0x87a8;
    r0 = (r2)(r4, arg1, r2);  // 这儿是调用gettimeofday并填充timeval结构
    if (r0 == 0x0) {
        r5 = *(r4 + 0x4);
        r6 = SAR(r5, 0x1f);
        r8 = 0x87b8;
        asm{ smlal      r5, r6, r0, r1 };
        r0 = *r8;
        r1 = *(r8 + 0x4);
        if (r2 != 0x0) { // 这儿是判断全局变量 saved_usecs 是否有值
                r0 = r5 - r0;
                r0 = __floatdisf();
                r0 << 0x10 | r0;
                s0 = *0x8700;
                r1 = 0x37ba;
                *(r8 + 0x4) = r6;
                asm{ vmul.f32   d0, d16, d0 };
                *r8 = r5;
                r10 = *(r1 + 0x5006);
                r11 = *(r1 + 0x500a);
                r5 = __fixsfdi() + r10;
                r6 = r11 + CARRY(FLAGS) + r1 + 0x5006;
                *r4 = __divdi3();
                *(r4 + 0x4) = __moddi3();
        }
        else { // 第一次调用才会到这
                    // 保存 timeval 到 saved_usecs
                *0x87bc = r6;
                *0x87b8 = r5;
        }
        // 保存上次获取的timeval值到saved_usecs_last
        *0x87c4 = r6;
        *0x87c0 = r5;
        r0 = 0x0;
    }
    return r0;
}

体现加速的代码主要在if (r2 != 0x0) {...}中,对应的汇编代码如下:

 

Alt pic

 

所以加速器伪代码大致为:

int ret = gettimeofday(&tv, NULL);
if(ret == 0) {
    if(saved_usecs->tv_sec && saved_usecs->tv_usec) {
        long A = tv->tv_usec/1000000000
                							

[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 2
支持
分享
最新回复 (21)
雪    币: 211
活跃值: (33)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
额,为什么显示不全?
2017-9-19 19:30
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
这个加速器确实不能在非越狱中运行,因为他依赖了MSHookFunction  这个函数只能在越狱环境下有效。当然也能在非越狱下实现类似inline  hook的操作,这就是后话了
2017-9-20 13:54
0
雪    币: 44229
活跃值: (19955)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
4






xerxers



额,为什么显示不全?

反馈收到,帖子你先不要编辑,我们查查原因。
2017-9-22 13:57
0
雪    币: 103
活跃值: (113)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
由一段伪代码引发的XXS盲打~~~
2017-9-23 17:48
0
雪    币: 40
活跃值: (627)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
gettimeofday怼不了U3D了  不知道你后面有没有处理unity的独立tick和gettimeofday的tick同步
2017-9-24 01:09
0
雪    币: 27
活跃值: (22)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
安卓端能用这个弄cocos2d的游戏么?我这边hook了下,再静态注入,好像没有起到作用,不知道大佬有没有安卓方面的demo或者实现
2018-8-24 10:32
0
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
非越狱注入的参考框架 MonkeyDev 访问403错误
2018-8-24 11:49
0
雪    币: 210
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
kanxue xerxers 额,为什么显示不全? 反馈收到,帖子你先不要编辑,我们查查原因。
请问一下消失掉的内容查到了吗
2019-2-14 14:00
0
雪    币: 210
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
kanxue xerxers 额,为什么显示不全? 反馈收到,帖子你先不要编辑,我们查查原因。
楼主,请教个问题,我hook gettimeofday在iOS9系统的手机上可以实现加速的效果,但是使用MonkeyDev或者tweak生成动态库注入Mach-O文件的方式在iOS11的非越狱机上没有效果,楼主知道这是为什么吗?谢谢了
2019-2-14 14:04
0
雪    币: 210
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
楼主,请教个问题,我hook gettimeofday在iOS9系统的手机上可以实现加速的效果,但是使用MonkeyDev或者tweak生成动态库注入Mach-O文件的方式在iOS11的非越狱机上没有效果,楼主知道这是为什么吗?谢谢了
最后于 2019-2-14 14:05 被PenguinAndy编辑 ,原因:
2019-2-14 14:05
0
雪    币: 210
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
ios大佬嘛 大佬
你也在学习这个吗?加个好友讨论一下可以吗?
2019-2-14 14:06
1
雪    币: 229
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
17
始终没弄明白,IOS下如何第三方调用APP本身的函数。
2019-10-5 15:33
0
雪    币: 34577
活跃值: (7135)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
18
懂原理是编程是很重要的学习方法。
2019-10-5 16:39
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
你好,想委托你做个dylib动态库,可以的话回复我的邮件,x1014522256m@163.com,详聊
2019-11-8 01:16
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
22
大佬可以来我公司。高薪应聘。坐标迪拜。过来公司报销所有费用
2020-4-7 18:55
0
游客
登录 | 注册 方可回帖
返回
//