利用ios的hook机制实现adobe air ios ane下appdelegate的动态替换

开发背景

利用adobe air开发完游戏后,需要针对ios或者android平台进行支付、推送的sdk接入,本文可以用来彻底解决ios平台下delegate生命周期几个回调函数的调用,实现原生的推送、支付功能的接入

hook知识背景

(objc里的Method Swizzling,本节内容转自http://blog.csdn.net/yiyaaixuexi)

在Objective-C中调用一个方法,其实是向一个对象发送消息,查找消息的唯一依据是selector的名字。利用Objective-C的动态特性,可以实现在运行时偷换selector对应的方法实现,达到给方法挂钩的目的。

每个类都有一个方法列表,存放着selector的名字和方法实现的映射关系。IMP有点类似函数指针,指向具体的Method实现。

我们可以利用 method_exchangeImplementations 来交换2个方法中的IMP,

我们可以利用 class_replaceMethod 来修改类,

我们可以利用 method_setImplementation 来直接设置某个方法的IMP,

……

归根结底,都是偷换了selector的IMP,如下图所示:

实现思路

1、在MDChangeDelegateHelper类加载阶段就对adboe air的appdelegate类进行方法hook,确保在adobe air的appdelegate在创建前替换成我们新实现的类

2、需要3个SEL,

一个AppDelegate原SEL:oldSEL,

一个MDChangeDelegateHelper的默认SEL:defaultSEL,用于为原appdelegate添加默认的原oldSEL

一个MDChangeDelegateHelper的目标SEL:newSEL

方法替换思路:

3、替换后对应的sel关系为

oldSEL   -- newMethod

newSEL -- oldMethod

所以当对应的appdelegate方法被调用时,

oldSEL找到了newMethod的实现,newMethod的实现在MDChangeDelegateHelper.m内的hookedxxx方法

在newMethold中调用了newSEL,newSEL指向oldMethod,实现了原流程的兼容

代码实现

//
//  MDChangeDelegateHelper.m
//  ChangeDelegateDemo
//
//  Created by ashqal on 14-10-31.
//  Copyright (c) 2014年 moredoo. All rights reserved.
//

#import "MDChangeDelegateHelper.h"
#import <UIKit/UIKit.h>

#import <objc/runtime.h>

void hookMethod(SEL oldSEL,SEL defaultSEL, SEL newSEL)
{
    //CTAppController
    Class aClass = objc_getClass("CTAppController");
    if ( aClass == 0 )
    {
        NSLog(@"!!!!!!!!!!!!!did not find adobe class!");
        return;
    }
    Class bClass = [MDChangeDelegateHelper class];
    //把方法加给aClass
    class_addMethod(aClass, newSEL, class_getMethodImplementation(bClass, newSEL),nil);
    class_addMethod(aClass, oldSEL, class_getMethodImplementation(bClass, defaultSEL),nil);

    Method oldMethod = class_getInstanceMethod(aClass, oldSEL);
    assert(oldMethod);
    Method newMethod = class_getInstanceMethod(aClass, newSEL);
    assert(newMethod);
    method_exchangeImplementations(oldMethod, newMethod);

}

@implementation MDChangeDelegateHelper

+ (void)load
{
    NSLog(@"MDChangeDelegateHelper load");
    //[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(createStarterNotificationChecker:)
                                                 //name:@"UIApplicationWillFinishLaunchingNotification" object:nil];
    //[self changeDelegate];

    hookMethod( @selector(application:didFinishLaunchingWithOptions:)
               ,@selector(defaultApplication:didFinishLaunchingWithOptions:)
               ,@selector(hookedApplication:didFinishLaunchingWithOptions:)
               );
    hookMethod( @selector(application:handleOpenURL:)
               , @selector(defaultApplication:handleOpenURL:)
               , @selector(hookedApplication:handleOpenURL:)
               );
    hookMethod(@selector(application:openURL:sourceApplication:annotation:)
               , @selector(defaultApplication:openURL:sourceApplication:annotation:)
               , @selector(hookedApplication:openURL:sourceApplication:annotation:));

    hookMethod(@selector(application:supportedInterfaceOrientationsForWindow:)
               , @selector(defaultApplication:supportedInterfaceOrientationsForWindow:)
               , @selector(hookedApplication:supportedInterfaceOrientationsForWindow:)
               );
    hookMethod(@selector(applicationDidBecomeActive:)
               , @selector(defaultApplicationDidBecomeActive:)
               , @selector(hookedApplicationDidBecomeActive:)
               );

    hookMethod(@selector(init)
               , @selector(init)
               , @selector(hookedInit)
               );
}

-(BOOL)hookedApplication:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)dic
{

    NSLog(@"hooked didFinishLaunchingWithOptions");
    [self hookedApplication:application didFinishLaunchingWithOptions:dic];
    return YES;
}

-(id)hookedInit
{
    NSLog(@"hooked init!!!");
    return [self hookedInit];
}

- (BOOL)hookedApplication:(UIApplication *)application handleOpenURL:(NSURL *)url {

    NSLog(@"hooked handleOpenURL");
    [self hookedApplication:application handleOpenURL:url];
    return YES;
}

- (BOOL)hookedApplication:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    NSLog(@"hooked openURL sourceApplication annotation");
    [self hookedApplication:application openURL:url sourceApplication:sourceApplication annotation:annotation];
    return YES;
}

- (NSUInteger) hookedApplication:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    NSLog(@"hooked supportedInterfaceOrientationsForWindow");
    [self hookedApplication:application supportedInterfaceOrientationsForWindow:window ];
    return 0;
}

- (void)hookedApplicationDidBecomeActive:(UIApplication *)application
{
    [self hookedApplicationDidBecomeActive:application];
    NSLog(@"hooked applicationDidBecomeActive");
}

- (BOOL)defaultApplication:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)dic{ return YES;}
- (BOOL)defaultApplication:(UIApplication *)application handleOpenURL:(NSURL *)url{return YES;}
- (BOOL)defaultApplication:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{return YES;}
- (NSUInteger) defaultApplication:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{return 0;}
- (void)defaultApplicationDidBecomeActive:(UIApplication *)application{}
- (id)init
{
    self = [super init];
    if (self) {

    }
    return self;
}

@end

注意点

a) 在运行时nslog出adobe air的appdelegate名字为CTAppController,所以将此类作为替换对象

b) 在对init函数进行替换时发现CTAppController没有实现init函数,所以将默认的init函数做了基础实现,不然无法创建实例了

时间: 2024-08-08 00:38:16

利用ios的hook机制实现adobe air ios ane下appdelegate的动态替换的相关文章

iOS的绘图机制

iOS的视图机制,提到了iOS的视图框框可以通过drawRect自己绘图,每个view的layer(CALayer)就像一个视图的投影,其实我们也可以来操作它定制一个视图,例如半透明圆角背景的视图. 要完成自己在视图上绘图,大家一定要了解一下iOS的绘图机制了.今天我试图也通俗地说一下iOS的绘图. 在iOS中绘图可以有两种方式: 1,采用iOS的核心图形库. 2,采用OpenGL ES. 这两个库的不同我简单介绍一下: 前者主要是通过核心图形库和UIKit进行封装,其更加贴近我们经常操作的视图

开发Adobe AIR移动应用程序的考虑事项

http://www.adobe.com/cn/devnet/air/articles/considerations-air-apps-mobile.html Adobe AIR 经过发展演进,已经超越了最初作为桌面应用程序平台的目标.如今,它支持跨移动.桌面和数字家用设备的独立应用程序开发.AIR 是一种极富吸引力的开发平台,部分原因在于其广泛的覆盖面.与此同时,这些环境中的每一种环境都给移动应用程序开发与设计带来的独特的要求. 举例来说,移动应用程序常常是短期运行的.它们需要一种可在较小的屏

【repost】JS中的hook机制

hook机制也就是钩子机制,由表驱动实现,常用来处理多种特殊情况的处理.我们预定义了一些钩子,在常用的代码逻辑中去适配一些特殊的事件,这样可以让我们少些很多if else语句.举个高考加分的例子,比如获得过全国一等奖加20分,二等奖加10分,三等奖加5分.使用if else的话: function student(name,score,praise){ return { name:name, score:score, praise:praise } } function praiseAdd(st

黄聪:WordPress 的 Hook 机制与原理(add_action、add_filter)

稍有接触过 WordPress 主题或插件制作修改的朋友,对 WordPress 的Hook机制应该不陌生,但通常刚接触WordPress Hook 的新手,对其运作原理可能会有点混乱或模糊.本文针对 WordPress Hook 运作大致做个简单的说明,而预设读者是理解基本的 PHP function 语法及运作,但对 WordPress Hook 机制不是很明白. Hook机制里登场的角色 先从“登场角色”的个别说明开始: WordPress核心 指的是 WordPress 内建的程式码架构

ios的安全机制

ios的安全机制 iOS是由苹果公司为iPhone开发的操作系统.它主要是给iPhone.iPod touch以及iPad使用.就像其基于的Mac OS X操作系统一样,它也是以Darwin为基础的.原本这个系统名为iPhone OS,直到2010年6月7日WWDC大会上宣布改名为iOS.iOS的系统架构分为四个层次:核心操作系统层(the Core OS layer),核心服务层(the Core Services layer),媒体层(the Media layer),可轻触层(the Co

Hook机制里登场的角色

稍有接触过 WordPress 主题或插件制作修改的朋友,对 WordPress 的Hook机制应该不陌生,但通常刚接触WordPress Hook 的新手,对其运作原理可能会有点混乱或模糊.本文针对 WordPress Hook 运作大致做个简单的说明,而预设读者是理解基本的 PHP function 语法及运作,但对 WordPress Hook 机制不是很明白. Hook机制里登场的角色 先从“登场角色”的个别说明开始: WordPress核心 指的是 WordPress 内建的程式码架构

WordPress开发第二篇即hook机制

我们可以把wp_head()以及wp_footer()看成是"钩子",我们可以用别的hook  function来钩住它.首先wp_head只有一行代码,那就是do_action('wp_head'),而wp_footer也只有do_action('wp_footer')而已,因此我们可以使用do_action来表现的更加简洁一些.</span> 当我们执行到输出header.php时,就会执行到wp_head(),就如同执行do_action('wp_head'),此时w

Adobe AIR中使用Flex连接Sqlite数据库(1)(创建数据库和表,以及同步和异步执行模式)

系列文章导航 Adobe AIR中使用Flex连接Sqlite数据库(1)(创建数据库和表) Adobe AIR中使用Flex连接Sqlite数据库(2)(添加,删除,修改以及语句参数) Adobe AIR中使用Flex连接Sqlite数据库(3)(查询) Adobe AIR中使用Flex连接Sqlite数据库(4)(事务) Flex,Fms3相关文章索引 Fms3和Flex打造在线多人视频会议和视频聊天(附原代码) 免费美女视频聊天,多人视频会议功能加强版本(Fms3和Flex开发(附源码))

IOS 阶段学习第25天笔记(IOS沙盒机制介绍)

IOS学习(OC语言)知识点整理 一.IOS沙盒机制介绍 1)概念:每个ios应用都有自己的应用沙盒,应用沙盒就是文件系统目录,与其他应用放入文件 系统隔离,ios系统不允许访问 其他应用的应用沙盒,但在ios8中已经开放访问(extension) 2)extension是ios8新开放的一种对几个固定系统区域的拓展机制,它可以在一定程度上弥补ios的沙盒机制对应用间的通信限制 3)应用沙盒一般包括以下几个文件目录: 1.应用程序包:包含所有资源文件和可执行文件 2.Documents:保存应用