美文网首页
iOS打包教程

iOS打包教程

作者: 一直在路上66 | 来源:发表于2023-04-18 09:52 被阅读0次

iOS逆向知识掌握

  • 通过脱壳、运行时分析、静态分析、动态调试、Hook、注入等一系列技术手段,推导出目标文件的结构、流程、算法、代码等,称为“iOS应用逆向工程”(后续简称为“iOS逆向工程”)
  • 了解Objective-C、Swift的基本特性以及Xcode的使用方法,等熟练之后,还需要了解一些底层知识,例如Mach-O文件结构、Runtime机制等。
  • 推荐阅读 《iOS应用逆向工程》 《iOS应用逆向与安全之道》

越狱手机

  • 需要一台越狱手机 安装爱思助手

应用脱壳

  • iOS端App在上线之前会由苹果商店进行FairPlayDRM数字版权加密保护(称为“加壳”)otool可以看到二进制文件的信息里有一个cryptid字段,cryptid=1表示已加壳,cryptid=0表示未加壳。具体如下。
  • 使用 Frida-ios-dump工具脱壳 frida-ios-dump

工具之IDA

  • 下载安装ida ida地址
  • 加载文件并分析完成之后,用户便可以根据需求进行逆向分析。在进行逆向分析前有必要了解IDA界面的各种组件,IDA分析完成后的默认界面如下所示。 image.png
  • 主要分析每个类里面主要有哪些方法 例如PFSDManger集成brsdk的一些方法在hook时 hook这些方法就可以了 image.png

越狱开发工具之Theos

  • Theos是一个跨平台的越狱开发工具包,可以在Windows、Linux、macOS甚至iOS下工作。Theos无论是下载安装还是编译发布都比较简单,它为开发者准备好了一些代码模板、预置了一些基本的Makefile脚本,这样开发一个插件就会变得方便很多,其Logos语法也是相当优雅,让开发者可以更专注于功能开发。Theos相当于对Cydia Substrate的封装,因而能实现对Objective-C运行时的Hook,也能实现对C语言函数的Hook

Theos安装

  • 在Theos开发中,iOS文件的签名由ldid工具来完成,ldid取代了Xcode自带的codesign。使用brew安装即可
brew install ldid
  • 2.安装xz、lzma
    xz、lzma是两种压缩模块,为了后面“make package”能够顺利通过,需要安装它们。安装方法如下:
$ brew install xz
$ sudo cpan IO::Compress::Lzm
  • 3.添加$THEOS环境变量
    读者可以使用任何编辑工具打开.bash_profile文件,添加下面的环境变量:
export THEOS=/opt/theos
export PATH=$PATH:$THEOS/bin
  • 4.安装Theos
sudo git clone --recursive https://github.com/theos/theos.git $THEOS
  • 5.设置$THEOS的用户组权限
sudo chown -R $(id -u):$(id -g) $THEOS
  • 更多关于theos知识可以查询资料 掌握如何创建工程 如何书写Tweak.xm文件
  • %hook
    指定需要Hook的类名,接着就是需要Hook的函数,最后必须以%end结尾
  • (2)%log
    该命令在%hook内部使用,将类名、函数名、参数信息打印出来,非常实用。需要注意的是只在DEBUG模式下才会输出信息。
  • (3)%orig
  • (4)%new
    该命令在%hook内部使用,为现有类增加新的方法,功能与class_addMethod相同。示例如下:

工具之monkeydev

  • Theos使用Makefile基于命令行方式编译生成deb文件,习惯使用Xcode的开发者可能不太适应这种方式,于是有了后来的iOSOpenDev。它基于Xcode模板开发,在很长一段时间内都是越狱开发者的福音,但是该项目不再维护,因此在新的Xcode版本中不能很好地工作。国内安全研究员在此基础上进行了修改,推出了一个全新的集成框架,名为“MonkeyDev”,它不仅能完美支持新版Xcode和新版Theos,还增加了一些非常实用的功能
  • MonkeyDev安装
brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/
master/Library/Formula/sshpass.r
  • 选择xcode 版本
sudo xcode-select -s /Applications/Xcode9.
*新建项目选择Monkeyapp image.png
  • 选择Logos Tweak模板之后,会自动生成基础代码,由于Xcode无法识别*.xm文件,导致代码没有高亮效果,这时需要在Xcode界面右侧设置“Type”为“Objective-C++Source”,然后重新打开工程。完成后如图8-13所示。
  • 把IPA放到这里


    image.png
  • 在monkeyDemoDylib.xm 编写hook代码


    image.png

开始集成SDK

将sdk拖入到工程中

image.png image.png

添加依赖库

image.png

支付宝添加回调

#pragma mark - 支付回调,必接

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    [WCmsSDK application:application handleOpenURL:url];
    return %orig;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options {
    [WCmsSDK application:application openURL:url options:options];
    return  %orig;
}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    [WCmsSDK application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
    return %orig;
}

wansdk初始化代码

%hook AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // sdk初始化
    [WCmsSDK didFinishLaunching];
    return %orig;
}

接入登录

%hook   BRSDKApi

- (void)login{
    %log;
//    %orig;
    [self wanlogin];
}
%new
- (void)wanlogin{
    [WCmsSDK loadLoginViewResultSuccess:^(NSString *logintime, NSString *userName, NSString *sign, NSString *rzStatus) {
        NSLog(@"WCmsSDK____%@%@%@%@",logintime,userName,sign,rzStatus);
        NSString* openId = [NSString stringWithFormat:@"%@_%@", @"brsyp", userName];
        dispatch_async(dispatch_get_main_queue(), ^{
            [BoRanSDK thirdLoginWithOpenId:openId];
        });
    } failed:^(NSInteger code, NSString *message) {

    }];
}

%end

接入支付

-(void)pay_param:(NSDictionary *)param{
        %log;
        %orig;
    [BoRanSDK tradeOrderNum:param];
//    [self wanPay:param];
}
+(void)tradeOrderNum:(NSDictionary*)param{
    
    BRSDKOrderInfo* orderInfo = [[BRSDKOrderInfo alloc] init];
    orderInfo.productId = param[@"product_id"];
    orderInfo.productName = param[@"product_name"];
    orderInfo.productDesc = param[@"product_name"];
    NSString *amount =  param[@"amount"];
    orderInfo.productPrice = [NSString stringWithFormat:@"%ld",amount.integerValue*100];
    orderInfo.roleId = param[@"role_id"];
    orderInfo.roleName = param[@"role_name"];
    orderInfo.serverId = param[@"server_id"];
    orderInfo.serverName = param[@"server_name"];
    orderInfo.extInfo = param[@"extend"];
    NSMutableDictionary *resDict = [[NSMutableDictionary alloc]init];
    resDict[@"productId"] = orderInfo.productId;
    resDict[@"product"] = orderInfo.productName;
    resDict[@"orderMoneyFen"] = orderInfo.productPrice;
    resDict[@"roleId"] = orderInfo.roleId;
    resDict[@"roleName"] = orderInfo.roleName;
    resDict[@"serverId"] = orderInfo.serverId;
    resDict[@"serverName"] = orderInfo.serverName;
    resDict[@"extInfo"] = orderInfo.extInfo;
    [YouRequestManager requtForPouWayWithParams:resDict Block:^(NSDictionary *dic) {
        NSLog(@"requtForPouWayWithParams === %@",dic);
    } withFail:^(NSError *error) {
        
    }];
}

上传角色

-(void)upLoadRoleType:(NSString *)type Uid:(NSString *)user_id serverID:(NSString *)server_id serverName:(NSString *)server_name role_ID:(NSString *)role_id roleName:(NSString *)role_name level:(NSString *)level balanceID:(NSString *)balanceid balanceName:(NSString *)balancename balanceNum:(NSString *)balancenum vip:(NSString *)vip power:(NSString *)power gender:(NSString *)gender professionid:(NSString *)professionid profession:(NSString *)profession turn_level:(NSString *)turn_level partyId:(NSString *)partyid partyName:(NSString *)partyname{
    %orig;
    [WCmsSDK SetUserInfoDataWithRoleId:role_id
                              roleName:role_name
                             roleLevel:level
                                zoneId:server_id
                              zoneName:server_name
                                attach:@"无"
                                 block:^(NSInteger code) {
                                     if (code == 1) {
//                                         [YGMessage showMessage:@"上传成功"];
                                         NSLog(@"角色上传成功");
                                     };
                                 }];
    
    GameRoleInfo *roleInfo =  [[GameRoleInfo alloc]init];
    roleInfo.uploadType = UploadRoleInfoTypeCreateRole;
    roleInfo.serverId = server_id;
    roleInfo.serverName = server_name;
    roleInfo.roleId = role_id;
    roleInfo.roleName = role_name;
    roleInfo.roleLevel = level;
    roleInfo.partyName = @"无";
    roleInfo.roleCTime = [self gs_getCurrentTimeBySecond];
    roleInfo.balance = 20.0;
    roleInfo.fightingCapacity = @"10";
    roleInfo.reincarnation = @"0";
    roleInfo.roleVip = @"0";
    [BoRanSDK  sendGameRoleInfo:roleInfo];
}

#pragma mark - 角色上报

+ (void)sendGameRoleInfo:(GameRoleInfo *)roleInfo
{
    NSMutableDictionary* infoDict = [NSMutableDictionary dictionary];
    [infoDict setValue:@(roleInfo.uploadType) forKey:@"uploadType"];
    [infoDict setValue:roleInfo.serverId forKey:@"serverId"];
    [infoDict setValue:roleInfo.serverName forKey:@"serverName"];
    [infoDict setValue:roleInfo.roleId forKey:@"roleId"];
    [infoDict setValue:roleInfo.roleName forKey:@"roleName"];
    [infoDict setValue:roleInfo.roleLevel forKey:@"roleLevel"];
    [infoDict setValue:roleInfo.roleVip forKey:@"roleVip"];
    [infoDict setValue:@(roleInfo.balance) forKey:@"balance"];
    [infoDict setValue:roleInfo.partyName forKey:@"partyName"];
    [infoDict setValue:roleInfo.fightingCapacity forKey:@"fightingCapacity"];
    [infoDict setValue:roleInfo.reincarnation forKey:@"reincarnation"];
    [infoDict setValue:@(roleInfo.roleCTime) forKey:@"roleCTime"];
    
    //1.上报渠道角色信息
#if HAS_INCLUDE_CHANNEL
    if ([[sdkTools shareTool].loginMode intValue] != (int)LOGIN_MODE_BORAN) {
        
        int nType = 1;
        switch (roleInfo.uploadType) {
            case UploadRoleInfoTypeEnterGame:
                nType = 1;
                break;
            case UploadRoleInfoTypeCreateRole:
                nType = 2;
                break;
            case UploadRoleInfoTypeRoleLevelUp:
                nType = 3;
                break;
            case UploadRoleInfoTypeExitGame:
                nType = 4;
                break;
            default:
                break;
        }
        
        [infoDict setValue:@(nType) forKey:@"dataType"];
        [infoDict setValue:roleInfo.roleVip forKey:@"roleVipLevel"];
        [infoDict setValue:@(roleInfo.balance) forKey:@"roleBalence"];
        [infoDict setValue:@(roleInfo.roleCTime) forKey:@"rolelevelCtime"];
        [[BoranChannel sharedInstance] SendRoleInfo:infoDict];
    }
#endif
    
    //2.上报官方角色信息
    [YouRequestManager sendFforRole:infoDict WithBlock:^(NSDictionary *dic) {
        
        NSLog(@"send roleInfoDict = %@", infoDict);
        
        NSString *stuats = [[dic objectForKey:@"status"]stringValue];
        if ([stuats isEqualToString:@"1"]) {
            NSDictionary *succ = [[NSDictionary alloc]initWithObjectsAndKeys:@"401",@"code", nil];
            [[NSNotificationCenter defaultCenter]postNotificationName:kBRSDKSendRoleNotification object:nil userInfo:succ];
        }else{
            NSDictionary *succ = [[NSDictionary alloc]initWithObjectsAndKeys:@"402",@"code", nil];
            [[NSNotificationCenter defaultCenter]postNotificationName:kBRSDKSendRoleNotification object:nil userInfo:succ];
        }
    } withFail:^(NSError *error) {
        NSDictionary *succ = [[NSDictionary alloc]initWithObjectsAndKeys:@"403",@"code", nil];
        [[NSNotificationCenter defaultCenter]postNotificationName:kBRSDKSendRoleNotification object:nil userInfo:succ];
    }];
}

相关文章

  • ios APP最新打包上线超详细流程,保证一看就会的教程!

    ios APP最新打包上线超详细流程,保证一看就会的教程! ios APP最新打包上线超详细流程,保证一看就会的教程!

  • Mac平台Android自动化打包(Jenkins)

    本文作为iOS自动化打包实战(Jenkins)的姊妹篇,iOS自动化打包教程地址:http://www.jians...

  • Unity3D与iOS交互详解

    Unity iOS教程之Xcode打包framework在Unity调用 Unity3D与iOS交互详解

  • ios 企业级打包教程、企业签名

    参考链接: ios 企业级打包教程:https://www.cnblogs.com/jiangqi/p/52207...

  • iOS速记

    xiOS App上架流程(2016详细版)iOS-最全的App上架教程Windows环境下IOS APP打包上传A...

  • xcode打包iOS教程

    xcode打包分为5 步进行 1、导入证书到钥匙串 打开钥匙串助手,双击p12文件,默认钥匙串是(登录),注意这里...

  • HBuilder打包iOS教程

    HBuilder在线打包 1、打开HBuilder工具,选择完工的项目,点击发行,选择发行为原生安装包。 2、选择...

  • iOS 打包流程教程

    前言: 最近在学习flutter 开发,所以涉及到iOS的打包的 所以学习了一下 记录一下,希望对大家有用 准...

  • 文章收集

    关于视图的周期流程一篇文章揭秘 iOS 布局相关问题 封装SDK流程iOS 自己封装的SDK 打包与合并,新手教程...

  • React-Native 打包记录

    网上RN项目的离线打包教程如下: RN项目的离线打包(ios) - 简书 但是这样打出来的的api文件会有2个as...

网友评论

      本文标题:iOS打包教程

      本文链接:https://www.haomeiwen.com/subject/iyyhjdtx.html