ios手柄研究

1.验证MFI没有苹果认证的硬件芯片,蓝牙无法连接。 BLE4.0除外MFi是苹果的一个开发者计划,针对硬件的。硬件和app配合使用。所以审核app肯定也很严格。因为MFi的硬件和app都要审核,app里用到蓝牙的

   在操作moga手柄时玩appstore下的原包,通过连接手柄弹出UI,抓到这个UI函数,然后动态调试传输字符串,发现其是一DES加密的验证码,破解难度较大,而且其验证码每次开启游戏时不同,是MFI芯片随机生成类似UUID服务码。

   新游手柄N1是蓝牙4.0,但是他们的手柄向下兼容,也支持2.0以上手机,越狱不越狱都不限制,MFI只支持非越狱,icade模式只支持少量游戏,故新游手柄并无破解MFI,只是个独立协议,通过在安装包导入dylib链接库

2.分析新游协议:首先sdk应该是用swift写的,因为用classdump不出结果,听新游人员说而且键值均自定义,并没参照xbox或者ps手柄协议,由于ios设备侧键值还不清楚方法所以未验证,新游sdk的frameworks中封装了大量swizzling接口,他们是<objc/runtime.h>以下方法,method_exchangeImplementations 来交换2个方法中的IMP,method_setImplementation 来直接设置某个方法的IMP,在分析反汇编时发现大量swizzle操作  

反编译代码:

r0 = objc_getClass("GCController");

*0x10724 = r0;

*0x10728 = object_getClass(r0);

r0 = class_getSuperclass(r0);

*0x1072c = r0;

r5 = class_getInstanceMethod(*0x10728, @selector(controllers));

    if (r5 != 0x0) {

            r0 = method_getImplementation(r5);

            *(__MergedGlobals + 0x10) = r0;

            method_setImplementation(r5, 0x24e1);

该方法替换了GCcontroller官方手柄api,替换了方法是[GCController controllers],替换的方法是void *__fastcall $GCController_controllers_method(),该方法调用了controllersWithMFIControllers:,该方法判断&OBJC_CLASS___NGDSDevice是不是"connected",而NGDSDevice定义了回调方法,调用自定义摁键键值类,判断摁键和蓝牙 回调调用了setValueChangedHandler方法,

 void * +[NGGameController controllersWithMFIControllers:](void * self, void * _cmd, void * arg2) {

    sp = sp - 0x4;

    r4 = @selector(sharedInstance);

    r0 = [NGDSDevice sharedInstance];

    if (([r0 connected] & 0xff) != 0x0) {

            r0 = [NGGameController sharedInstance];

            var_0 = r0;

            r0 = [NSArray arrayWithObjects:sp count:0x1];

    }

    else {

            r0 = 0x0;

    }

    return r0;

}

一.NGDSDevice类中调用了NGgamepad的sharedgamepad方法 该方法负责回调

二.调用了NGGamecontroller的extendgamepad和gamepad方法,extendgamepad的init调了NGExtendedgamepad的init其中也调用了ngextendedgamepad和NGcgamepad的SETngcontroller方法

NGEXtendedGamepad主要是调用了NGControllerButtonInput的类负责摁键

 

三.同时NGDSDevice中有Hardwarekeyboardstatuschanged-updategamepad connectionstate  负责更新状态

四.在每个回调函数 都有block 比如(NGDSDevice_init_block_invoke)他们其实调用了NGControllerDirectionpad的上层Buttoninput

一个Buttoninput对象负责接收摁键

 

 

一个GCController对象表示连接的物理游戏控制器。

一个GCControllerDirectionPad对象表示二维控制,如方向键或摇杆。

一个GCExtendedGamepad对象实现了一组游戏手柄控制逻辑轮廓。

 

  

 

替换的第二个方法是startWirelessControllerDiscoveryWithCompletionHandler,替换的方法是startWirelessControllerDiscoveryWithCompletionHandler,以及block,__74__NGGameController_startWirelessControllerDiscoveryWithCompletionHandler___block_invoke,其目的是游戏控制器的Connet和Disconnet状态进行事件注册

r5 = class_getInstanceMethod(*(__MergedGlobals + 0x18), @selector(startWirelessControllerDiscoveryWithCompletionHandler:));

    if (r5 != 0x0) {

            r0 = method_getImplementation(r5);

            *(__MergedGlobals + 0xc) = r0;

            method_setImplementation(r5, 0x24a5);

至于UUID当时分析的不对,应该就是在游戏中定下的私有服务创建的唯一标示符。

曾经尝试 暴力nop掉swizzle,发现手柄以及无法操作了。

3. 新游sdk分析:NGGamepadDemo

按键 NGGamepadButton 成员变量pressed表⽰按键是否按下
摇杆 NGGamepadThumbStick 摇杆向量坐标, x,y轴取值为-1.0~1.0
⼗字键 NGGamepadDirectionPad 同时提供向量坐标和4个⽅向按键对象

响应手柄的方式是注册回调函数和读取手柄当前状态更新游戏。

NGGamepad* gamepad = [NGGamepad sharedGamepad];
gamepad.buttonA.valueChangedHandler = ^(NGGamepadButton* button, BOOL
pressed, float value) {
if (pressed) {//A键按下
[self fireLasers];
}};

由于iOS系统的限制,前SDK⽆法判断⼿柄是否连接。游戏可以通过设置NGGamepad的valueChangedHandler,如果收到事件则说明⼿柄连接上。

并且新游手柄的api均是私有api

 

 

Log分析:主要调用了NGGameController类 该类就是自定义摁键类

Apr 28 19:51:30 zangxuetongde-iPad routined[2140] <Warning>: BTM: attempting to connect to service 0x00000020 on device "NewGamepad N1" 00:15:83:AC:47:40

 

Apr 28 19:51:32 zangxuetongde-iPad SpringBoard[42] <Warning>: BTM: connection to service 0x00000020 on device "NewGamepad N1" 00:15:83:AC:47:40 succeeded

 

Apr 29 11:06:20 zangxuetongde-iPad gamecontrollerd[4000] <Notice>: MS:Notice: Injecting: (null) [gamecontrollerd] (1141.16)

 

Apr 28 19:18:00 zangxuetongde-iPad TheKingOfFighters97[3079] <Warning>: Finished finding controllers

 

Apr 28 19:18:00 zangxuetongde-iPad TheKingOfFighters97[3079] <Warning>: Assigning ExtendedGamepad to player 0

 

Apr 28 19:52:01 zangxuetongde-iPad TheKingOfFighters97[3254] <Warning>: authentification error : The requested operation could not be completed because this application is not recognized by Game Center.(不能联网)

 

 

 

 

补充之前调试方法:

动态调试方法:

先在ipad安装openssh,再安装gdb

.PC 端运行 SSH 客户端一般是putty,连接到设备,输入用户名:
root,默认密码: alpine,

1.动态调试,主要工具gdb

首先,ps -ax|grep "要破解的程序名",得到其进程id,如1234
接着,使用gdb,用attach “进程id
然后,bt查看函数调用栈,找到可疑函数后,使用up 
继续,用si等命令单步跟踪,set等命令改变参数的值
再来,使用disassemble命令,查看确认要修改的二进制字符串
最后,用十六进制编辑器查找并修改二进制字符串    

 2. 动静结合,主要工具otool + gdb
 a. otool -tV "目标程序" > dis.asm
 b. 文本编辑器打开 dis.asm,查找可疑的函数
 c. 使用gdb打开目标程序,并在可疑的函数中设置断点,如 b *0x00001234
 d. run 运行程序,断点处,si 等跟踪, set 设置关键参数值
 e. 用计算器计算需要修改的序列偏移,或disassemble命令
 f. 用十六进制编辑器查找并修改二进制字符串

常用的命令

attach 1234; b *0x1234;clear *0x1234;bt;disassemble;si;finish;set $eax
gcc test.c -o test;otool -tV target > dis.asm

 

另一种方法是,加壳源程序在运行时候会自动解密,运行应用时动态调试 dump出关键代码 再用IDA分析。

IDA左边 Functions window 看出来,函数是以“ sub_”开头的说明已经加密

root# gdb -e ./iRead

(gdb) dump memory dec.bin 0x3000 0x837000

 

 

做了hack,伪装成MFI手柄

在响应手柄事件的地方调用原先触屏事件处理的逻辑。

不改原来的逻辑,是添加控制处理。

每个人物动作控制逻辑应该会对应一个接口,在手柄处理这边调用对应的接口。

u3d需要把手柄事件传递到u3d里面, cocos2dx可以直接调用objective-C的代码响应手柄事件。

触屏上,人物移动是靠虚拟摇杆的方向,手柄摇杆事件响应的可以得到摇杆的方向。

 

 

gamepad.leftThumbStick.valueChangedHandler = ^(NGGamepadThumbStick* stick, float xAxis, float yAxis) {

[self moveWithVector:CGPointMake(xAxis, yAxis)];

};

每个摇杆对象都有当前的摇杆坐标值的

实现回调

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值