非越狱手机植入动态库

Posted by GH on December 12, 2018

目标

  1. 修改爱奇艺App
  2. 将这个修改过的App重签名
  3. 安装在未越狱手机上

准备:

  1. 越狱手机和一台未越狱手机
  2. Mac电脑

1. 修改爱奇艺App

  • 步骤1. 在越狱手机AppStore上下载爱奇艺App.
  • 步骤2. 在越狱手机上找到爱奇艺的AppID, 这里可以通过MJAppTools, 快速查询(这里也可以通过Cycript来找到),代码如下:
1
2
3
4
5
6
7
8
// 终端
MJAppTools -l

// 显示
爱奇艺 <com.qiyi.iphone>
/private/var/mobile/Containers/Bundle/Application/C8575DD1-889E-4E70-AF66-4E4CC920F6AC/iQiYiPhoneVideo.app
/private/var/mobile/Containers/Data/Application/CD9280DD-C4C3-4CF2-84E0-5F484596E211
  arm_64 加壳
  • 步骤3. 创建一个名叫libReveal.plist的文件,将刚才的AppIDcopy进plist中,如下:
1
2
3
4
5
6
7
{
	Filter = {
		Bundles = (
			"com.qiyi.iphone"
		);
	};
}
  • 步骤4. 打开Reveal
1
2
3
4
//1. 找到
Helpe -> Show Reveal Library in Finder -> iOS Library
//2. 重命名
RevealServer -> libReveal
  • 步骤5. 将libReveal.plist 和 libReveal.dylib 同时上传到越狱机器以下路径(可以通过iFunBox):
1
Device/Library/MobileSubStrate/DynamicLibraries
  • 步骤6. 此时打开Reveal和越狱机器上的爱奇艺App,结合Cycript或者mjcript, 可以找到你想要修改的东西所属的类,这里如果我们需要修改播放的广告。

  • 步骤7. 通过Reveal可以找到启动页面相关的广告View是QYStartADView, 它所属的类是QYStartADViewController

  • 步骤8. 通过Clutchdumpdecrypted脱壳,得到脱壳后的新App。我用的是Clutch,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 罗列手机上可以脱壳的App
Clutch -i
// 脱壳指定App
Clutch -d x(爱奇异的前面的数字)
// 返回
com.qiyi.iphone contains watchOS 2 compatible application. It's not possible to dump watchOS 2 apps with Clutch 2.0.4 at this moment.
Zipping iQiYiPhoneVideo.app
ASLR slide: 0x100004000
Dumping <QiYiUserNotification> (arm64)
Patched cryptid (64bit segment)
ASLR slide: 0x1000dc000
Dumping <QYToday> (arm64)
Patched cryptid (64bit segment)
ASLR slide: 0x1000bc000
Dumping <QYSiriShortCuts> (arm64)
Patched cryptid (64bit segment)
Writing new checksum
Writing new checksum
Writing new checksum
objc[4015]: Class ZipArchive is implemented in both /var/tmp/clutch/1C8BA028-6FC4-4975-B4E9-644D2935FB55/clutch and /private/var/mobile/Containers/Bundle/Application/C8575DD1-889E-4E70-AF66-4E4CC920F6AC/iQiYiPhoneVideo.app/Frameworks/QYUniversalFramework.framework/QYUniversalFramework. One of the two will be used. Which one is undefined.
Dumping <QYUniversalFramework> arm64
ASLR slide: 0x100054000
Dumping <iQiYiPhoneVideo> (arm64)
Patched cryptid (64bit segment)
Successfully dumped framework QYUniversalFramework!
Child exited with status 0
Zipping QYUniversalFramework.framework
Zipping QYSiriShortCuts.appex
Zipping QYToday.appex
Zipping QiYiUserNotification.appex
Writing new checksum
DONE: /private/var/mobile/Documents/Dumped/com.qiyi.iphone-iOS9.0-(Clutch-2.0.4).ipa
Finished dumping com.qiyi.iphone in 38.5 seconds
  • 步骤9. copy出来已经脱壳了的App,然后找到包中的Mach-O文件,最后运用class-dump, 执行以下的命令得到相应的头文件:
    1
    
    class-dump -H -o iqiHeaders iQiYiPhoneVideo.app
    
  • 步骤10. 通过查看类QYStartADView的相关头文件,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//
//     Generated by class-dump 3.5 (64 bit).
//
//     class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.
//

#import "UIView.h"

#import "QYStartADViewControllerDelegate.h"
#import "QYStartAdPlayerControllerDelegate.h"

@class AdsClient, CupidAd, NSString, NSTimer, QYStartADViewController, QYStartAdPlayerController, QYWebContainer, UILabel, UIWindow;

@interface QYStartADView : UIView <QYStartAdPlayerControllerDelegate, QYStartADViewControllerDelegate>
{
    UIWindow *_window;
    NSTimer *_adTimer;
    float _iAdTime;
    _Bool _shouldRun;
    long long _addedTime;
    float _adShowTime;
    _Bool _isFullScreenAd;
    int _type;
    id <QYPhoneStartADViewDelegate> _delegate;
    UILabel *_secords;
    long long _duration;
    double _logoBackHeight;
    double _needToCut;
    UIView *_adImageView;
    QYWebContainer *_webView;
    AdsClient *_adClient;
    CupidAd *_adCupid;
    QYStartAdPlayerController *_player;
    QYStartADViewController *_startAdViewController;
}

@property(retain, nonatomic) QYStartADViewController *startAdViewController; // @synthesize startAdViewController=_startAdViewController;
@property(retain, nonatomic) QYStartAdPlayerController *player; // @synthesize player=_player;
@property(nonatomic) int type; // @synthesize type=_type;
@property(retain, nonatomic) CupidAd *adCupid; // @synthesize adCupid=_adCupid;
@property(retain, nonatomic) AdsClient *adClient; // @synthesize adClient=_adClient;
@property(retain, nonatomic) QYWebContainer *webView; // @synthesize webView=_webView;
@property(retain, nonatomic) UIView *adImageView; // @synthesize adImageView=_adImageView;
@property(nonatomic) double needToCut; // @synthesize needToCut=_needToCut;
@property(nonatomic) double logoBackHeight; // @synthesize logoBackHeight=_logoBackHeight;
@property(nonatomic) long long duration; // @synthesize duration=_duration;
@property(retain, nonatomic) UILabel *secords; // @synthesize secords=_secords;
@property(nonatomic) _Bool isFullScreenAd; // @synthesize isFullScreenAd=_isFullScreenAd;
@property(nonatomic) __weak id <QYPhoneStartADViewDelegate> delegate; // @synthesize delegate=_delegate;
- (void).cxx_destruct;
- (id)imageFromImage:(id)arg1 inRect:(struct CGRect)arg2;
- (void)playToEnd;
- (void)playError;
- (void)h5WillJumpToPage;
- (void)userInteractWithHtml;
- (void)sendH5AdClickPingback;
- (void)finishDisplayHtml;
- (void)keyboardDidHide;
- (id)labelWithFrame:(struct CGRect)arg1 backgroundColor:(id)arg2 textColor:(id)arg3 font:(id)arg4 text:(id)arg5 textAlignment:(long long)arg6;
- (id)imageViewWithFrame:(struct CGRect)arg1 image:(id)arg2;
- (void)delegateCallStartADViewDidEnd;
- (void)showEnds;
- (void)updateTime;
- (void)updateUI:(id)arg1;
- (void)finishAdShowForHtml;
- (void)prepareForEndAd;
- (void)secondChange;
- (void)timerStart;
- (void)showAdDetail;
- (void)skipAd;
- (id)createTouchScreenPromptView;
- (id)createViewWithType:(int)arg1 withURL:(id)arg2;
- (void)addBottomView;
- (void)addTimeBg;
- (id)initWithType:(int)arg1 withURL:(id)arg2 withDur:(long long)arg3 withAdData:(id)arg4 withADCupid:(id)arg5;
- (void)dealloc;

// Remaining properties
@property(readonly, copy) NSString *debugDescription;
@property(readonly, copy) NSString *description;
@property(readonly) unsigned long long hash;
@property(readonly) Class superclass;

@end

这里的代码量不是很多,我们看到这个- (id)initWithType:(int)arg1 withURL:(id)arg2 withDur:(long long)arg3 withAdData:(id)arg4 withADCupid:(id)arg5;有可能就是一个实例化方法,我们可以覆写这个方法来达到取消启动广告的效果(这里只是一个猜测!)

  • 步骤11. 下面通过编写theos, 来覆写这个实例化方法,假设你已经按照github上的教程安装好了,此时就可以按照下面的流程开始:
  • xxx.xm的相关语法的编写可以参考语法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/*------1-------*/
// 在合适的位置执行,下面的命令
nic.pl

/*------2-------*/
// 终端的显示
NIC 2.0 - New Instance Creator
------------------------------
  [1.] iphone/activator_event
  [2.] iphone/application_modern
  [3.] iphone/application_swift
  [4.] iphone/cydget
  [5.] iphone/flipswitch_switch
  [6.] iphone/framework
  [7.] iphone/ios7_notification_center_widget
  [8.] iphone/library
  [9.] iphone/notification_center_widget
  [10.] iphone/preference_bundle_modern
  [11.] iphone/tool
  [12.] iphone/tool_swift
  [13.] iphone/tweak
  [14.] iphone/xpc_service
Choose a Template (required):

/*------3-------*/
// 这里我们选择13,然后回车, 这里唯一需要注意的就是这个AppID,必须要填写爱奇艺的AppID, 其他的可以随便填写、或者直接回车
Choose a Template (required): 13
Project Name (required): ghiqyTest
Package Name [com.yourcompany.ghiqytest]: com.ghcoder.ghiqyTest
Author/Maintainer Name [龚欢]:
[iphone/tweak] MobileSubstrate Bundle filter [com.apple.springboard]: com.qiyi.iphone
[iphone/tweak] List of applications to terminate upon installation (space-separated, '-' for none) [SpringBoard]:
Instantiating iphone/tweak in ghiqytest/...
Done.

/*------4-------*/
// 创建完成之后,会发现自动创建了一个名叫ghiqytest的文件夹,里面存在四个文件,依次是:control(相关的配置信息)、ghiqyTest.plist(你需要修改的应用的AppID)、Makefile(配置文件)、Tweak.xm(需要修改的相关类)
// 下面是我对Tweak.xm修改的内容如下:

%hook QYStartADView

- (id)initWithType:(int)arg1 withURL:(id)arg2 withDur:(long long)arg3 withAdData:(id)arg4 withADCupid:(id)arg5 {
	return nil;
}

%end

/*------5-------*/
// ssh到越狱手机,并且要在Makefile的开头加上下面两行配置
export THEOS_DEVICE_IP=127.0.0.1
export THEOS_DEVICE_PORT=10010

/*------6-------*/
// 如果一切正常的话,执行完成之后,越狱机器就会自动重启了
make clean &&  make package && make install

2. 将这个修改过的App重签名

  • 步骤1. 要完成这个重签名,我们需要有如下几个文件
    1. 我们刚才编写的xxx.xm文件,其实刚才在我们重启之后,它就生成一个动态库文件,这个文件存放在越狱机的如下路径中:(Device->Library->MobileSubstrate->DynamicLibraries->ghiqyTest.dylib).
    2. 在越狱机器中加载这个动态库的Framework(CydiaSubstrate) [路径如下Device->Library->Frameworks->CydiaSubstrate.framework->CydiaSubstrate]
    3. 已经脱壳了的App
    4. xxx.mobileprovision文件,这个是需要一年99美金才可以,可以通过创建一个空的Xcode项目,编译之后在Target的App中找到这个xxx.mobileprovision文件(或者可以去apple.developer.com后台去下载)
  • 步骤2. 然后将上面提到三个文件ghiqyTest.dylib、CydiaSubstrate、xxx.mobileprovision一起拷贝到已经脱壳了的App中。

  • 步骤3. 在脱壳了的App中找到info.plist文件,把里面的UISupportedDevices这一栏统一删除掉。

  • 步骤4. 此时我们需要查看一些动态库,以及我们的Mach-O文件依赖的库是否配置正确:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*------1-------*/
// 查看爱奇艺Mach-O依赖的动态库
otool -L iQiYiPhoneVideo

// 终端显示
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4)
	/usr/lib/libresolv.9.dylib (compatibility version 1.0.0, current version 1.0.0)
	/usr/lib/libsqlite3.dylib (compatibility version 9.0.0, current version 274.20.0)
	/usr/lib/libxml2.2.dylib (compatibility version 10.0.0, current version 10.9.0)
	/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
	/System/Library/Frameworks/AVFoundation.framework/AVFoundation (compatibility version 1.0.0, current version 2.0.0)
	/System/Library/Frameworks/Accelerate.framework/Accelerate (compatibility version 1.0.0, current version 4.0.0)
	/System/Library/Frameworks/AdSupport.framework/AdSupport (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/AssetsLibrary.framework/AssetsLibrary (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/CFNetwork.framework/CFNetwork (compatibility version 1.0.0, current version 974.2.1)
	/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (compatibility version 150.0.0, current version 1556.0.0)
	/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics (compatibility version 64.0.0, current version 1245.8.0)
	/System/Library/Frameworks/CoreLocation.framework/CoreLocation (compatibility version 1.0.0, current version 2245.4.104)
	/System/Library/Frameworks/CoreMotion.framework/CoreMotion (compatibility version 1.0.0, current version 2245.4.104)
	/System/Library/Frameworks/CoreTelephony.framework/CoreTelephony (compatibility version 1.0.0, current version 0.0.0)
	/System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 1556.0.0)
	/System/Library/Frameworks/ImageIO.framework/ImageIO (compatibility version 1.0.0, current version 0.0.0)
	/System/Library/Frameworks/MapKit.framework/MapKit (compatibility version 1.0.0, current version 14.0.0)
	/System/Library/Frameworks/MobileCoreServices.framework/MobileCoreServices (compatibility version 1.0.0, current version 932.2.0)
	/System/Library/Frameworks/OpenAL.framework/OpenAL (compatibility version 1.0.0, current version 1.0.0)
	@rpath/QYUniversalFramework.framework/QYUniversalFramework (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/QuartzCore.framework/QuartzCore (compatibility version 1.2.0, current version 1.11.0)
	/System/Library/Frameworks/SceneKit.framework/SceneKit (compatibility version 1.0.0, current version 470.0.0)
	/System/Library/Frameworks/Security.framework/Security (compatibility version 1.0.0, current version 58286.202.3)
	/System/Library/Frameworks/StoreKit.framework/StoreKit (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration (compatibility version 1.0.0, current version 963.200.27)
	/System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 61000.0.0)
	/System/Library/Frameworks/WebKit.framework/WebKit (compatibility version 1.0.0, current version 606.1.36)
	/System/Library/Frameworks/Intents.framework/Intents (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/IntentsUI.framework/IntentsUI (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/ReplayKit.framework/ReplayKit (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/UserNotifications.framework/UserNotifications (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/Speech.framework/Speech (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/CoreData.framework/CoreData (compatibility version 1.0.0, current version 865.0.0)
	/System/Library/Frameworks/EventKit.framework/EventKit (compatibility version 1.0.0, current version 100.0.0)
	/System/Library/Frameworks/WatchConnectivity.framework/WatchConnectivity (compatibility version 1.0.0, current version 175.0.0)
	/System/Library/Frameworks/PassKit.framework/PassKit (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/GLKit.framework/GLKit (compatibility version 1.0.0, current version 103.2.0)
	/System/Library/Frameworks/Photos.framework/Photos (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/CoreSpotlight.framework/CoreSpotlight (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/LocalAuthentication.framework/LocalAuthentication (compatibility version 1.0.0, current version 425.202.1)
	/System/Library/Frameworks/VideoToolbox.framework/VideoToolbox (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/AVKit.framework/AVKit (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/MessageUI.framework/MessageUI (compatibility version 1.0.0, current version 3445.100.35)
	/usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)
	/System/Library/Frameworks/CoreText.framework/CoreText (compatibility version 1.0.0, current version 1.0.0)
	/usr/lib/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.5)
	/System/Library/Frameworks/CoreMedia.framework/CoreMedia (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/MediaPlayer.framework/MediaPlayer (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/AudioToolbox.framework/AudioToolbox (compatibility version 1.0.0, current version 492.0.0)
	/usr/lib/libicucore.A.dylib (compatibility version 1.0.0, current version 62.1.0)
	/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)
	/System/Library/Frameworks/CoreImage.framework/CoreImage (compatibility version 1.0.0, current version 5.0.0)
	/System/Library/Frameworks/CoreML.framework/CoreML (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/CoreVideo.framework/CoreVideo (compatibility version 1.2.0, current version 1.5.0)
	/System/Library/Frameworks/JavaScriptCore.framework/JavaScriptCore (compatibility version 1.0.0, current version 606.1.36)
	/System/Library/Frameworks/OpenGLES.framework/OpenGLES (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/Frameworks/SpriteKit.framework/SpriteKit (compatibility version 1.0.0, current version 2.0.0)
	
/*------2-------*/
// 需要把我们刚才创建的动态库链接进来,执行如下的命令
insert_dylib @executable_path/ghiqyTest.dylib iQiYiPhoneVideo iQiYiPhoneVideo --all-yes

/*------3-------*/
// 再次执行第一步的命令,会发现最下多了一行,就代表链接成功
@executable_path/ghiqyTest.dylib (compatibility version 0.0.0, current version 0.0.0)

/*------4-------*/
// 此时我们再看一下ghiqyTest.dylib, 这个动态库有没有依赖的其他动态库
otool -L ghiqyTest.dylib

// 终端显示
ghiqyTest.dylib (architecture arm64):
	/Library/MobileSubstrate/DynamicLibraries/ghiqyTest.dylib (compatibility version 0.0.0, current version 0.0.0)
	/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
	/System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 1560.10.0)
	/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (compatibility version 150.0.0, current version 1560.10.0)
	/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate (compatibility version 0.0.0, current version 0.0.0)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)
	
/*------5-------*/
// 这里需要修改/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate路径,执行下面的命令就可以修改了
install_name_tool -change /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate @loader_path/CydiaSubstrate ghiqyTest.dylib

// 再次执行第四部:就会发现之前路径修改了
ghiqyTest.dylib (architecture arm64):
	/Library/MobileSubstrate/DynamicLibraries/ghiqyTest.dylib (compatibility version 0.0.0, current version 0.0.0)
	/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
	/System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 1560.10.0)
	/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (compatibility version 150.0.0, current version 1560.10.0)
	@loader_path/CydiaSubstrate (compatibility version 0.0.0, current version 0.0.0)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)
  • 步骤5. 我们要先找到我们签名证书的Identity,通过如下的命令可以找到
1
2
3
4
5
6
security find-identity -v -p codesigning

// 终端显示
1) E797391C5ABBC9FB40EE04252C5679A6FEC1B351 "iPhone Developer: ******"
2) EF3725BCB7AB3C3F12AFC9C3A82C16B84A2925EC "iPhone Developer: *******" (CSSMERR_TP_CERT_REVOKED)
     2 valid identities found
  • 步骤6. 开始签名:
1
2
3
4
  iQiYiPhoneVideo.app codesign -fs E797391C5ABBC9FB40EE04252C5679A6FEC1B351 ghiqyTest.dylib
ghiqyTest.dylib: replacing existing signature
  iQiYiPhoneVideo.app codesign -fs E797391C5ABBC9FB40EE04252C5679A6FEC1B351 CydiaSubstrate
CydiaSubstrate: replacing existing signature
  • 步骤7. 最后我们对App整体签名,这里可以使用一个方便工具iOSAppSinger 步骤7.1 也可以通过codesign,来完成对App的整体签名:
1
2
3
4
5
6
7
8
9
10
11
/*------1-------*/
// 先从xxx.mobileprovision导出xxx.entitlements
security cms -D -i embedded.mobileprovision > temp.plist
/usr/libexec/PlistBuddy -x -c 'Print:Entitlements' temp.plist > entitlements.plist

/*------2-------*/
// 生成完成之后的entitlements.plist,配合codeSign进行重签名
codesign -fs E797391C5ABBC9FB40EE04252C5679A6FEC1B351 --entitlements entitlements.plist xxx.app

/*------3-------*/
// 生成之后的xxx.app,放到Payload的文件夹中,然后进行压缩,然后再修改后缀名为.ipa

3. 安装在未越狱手机上

直接通过iFunbox安装在非越狱机器上。