ASLR
ASLR(Address Space Layout Randomization)喉前,地址空間布局隨機(jī)化庶橱。
是一種針對(duì)緩沖區(qū)溢出的安全保護(hù)技術(shù),通過對(duì)堆魔眨、棧、共享庫映射等線性區(qū)布局的隨機(jī)化酿雪,通過增加攻擊者預(yù)測目的地址的難度遏暴,防止攻擊者直接定位攻擊代碼位置,達(dá)到阻止溢出攻擊的目的的一種技術(shù)指黎。
iOS4.3
開始引入了ASLR技術(shù)朋凉。
在MachOView中查看LC_SEGMENT_64(_TEXT)
的VM_Address
是0x100000000
(__PAGEZERO VM Size),如果沒有ASLR技術(shù),MachO文件在內(nèi)存中的物理地址就是0x100000000
查看MachO文件的在內(nèi)存中的物理地址
0x00000001043bc000
(lldb) image list
[ 0] 802EFF39-2417-3E7E-97B8-E21AD7AFD27A 0x00000001043bc000 /Users/niujf/Library/Developer/Xcode/DerivedData/001--Demo-dantuskxyprjdbcmfkmwgrxzoxbt/Build/Products/Debug-iphoneos/001--Demo.app/001--Demo
[ 1] 571392A7-E1E6-369F-8805-C1A141F3C1C5 0x0000000104488000 /Users/niujf/Library/Developer/Xcode/iOS DeviceSupport/13.1.3 (17A878)/Symbols/usr/lib/dyld
...
可以看到ASLR隨機(jī)產(chǎn)生的Offset
,也就是MachO文件的偏移值是0x1043bc000-0x100000000=0x43bc000
如何給一個(gè)函數(shù)設(shè)置內(nèi)存斷點(diǎn)醋安?
隨便寫一個(gè)方法杂彭,在Hopper中查看方法在文件中的地址是00000001000065f0
,由于Hopper會(huì)自動(dòng)加上一個(gè)__PAGEZERO VM Size 0x100000000
,所以實(shí)際方法在文件中的偏移值是0x65f0
在MachOView中查看
__PAGEZERO
,可以看到在文件中的File offset
和File Size
都是0
Hopper吓揪、IDA都是未使用ASLR的VM Address
方法在內(nèi)存中的物理地址 = __PAGEZERO VM Size + File Offset + ASLR Offset = 0x100000000 + 0x65f0 + 0x43bc000
如下對(duì)方法的在內(nèi)存中的物理地址下斷點(diǎn)亲怠,可以看到下斷點(diǎn)成功了。
(lldb) b -a 00000001000065f0+0x43bc000
Breakpoint 1: where = 001--Demo`-[ViewController eatWithObjc:] at ViewController.m:17, address = 0x00000001043c25f0
(lldb) breakpoint list
Current breakpoints:
1: address = 001--Demo[0x00000001000065f0], locations = 1, resolved = 1, hit count = 0
1.1: where = 001--Demo`-[ViewController eatWithObjc:] at ViewController.m:17, address = 0x00000001043c25f0, resolved, hit count = 0
如何查看一個(gè)全局變量在MachO文件中的位置柠辞?
查看一個(gè)int
類型的全局變量a
在內(nèi)存的物理地址
int a = 10;
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
a = 20; //打上斷點(diǎn)
NSLog(@"%d",a);
}
(lldb) p a
(int) $0 = 10
(lldb) p &a
(int *) $1 = 0x0000000102ad4df0
可以看到全局變量a
在內(nèi)存中的物理地址是0x0000000102ad4df0
(lldb) image list
[ 0] 802EFF39-2417-3E7E-97B8-E21AD7AFD27A 0x0000000102acc000 /Users/niujf/Library/Developer/Xcode/DerivedData/001--Demo-dantuskxyprjdbcmfkmwgrxzoxbt/Build/Products/Debug-iphoneos/001--Demo.app/001--Demo
MachO文件在內(nèi)存中的物理地址是0x0000000102acc000
团秽,全局變量a
在文件中的偏移值就是0x0000000102ad4df0
- 0x0000000102acc000
= 0x8df0
在MachOView中查看0x8df0
位置對(duì)應(yīng)的數(shù)據(jù)是0xA0
,也就是十進(jìn)制10
.
chisel
chisel一個(gè)LLDB命令集合,用于幫助調(diào)試iOS應(yīng)用程序。
可以通過Homebrew安裝,具體的安裝命令在README里有
chisel在Xcode11上遇到的問題
error: module importing failed: Missing parentheses in call to 'print'. Did you mean print('Whoops! You are missing the <' + arg.argName + '> argument.')? (fblldb.py, line 98)
File "temp.py", line 1, in <module>
莫慌习勤,在issues里面已經(jīng)給出了解決方案,有兩種踪栋,lz
是在 /usr/local/Cellar/chisel/1.8.1
路徑下替換了修改了源碼兼容Python 3
的libexec
文件
chisel的Commands
如果對(duì)那個(gè)Commands不熟悉,可以通過(lldb) help Commands 查看,也可以看README
- pviews(打印當(dāng)前頁面的視圖層級(jí))
(lldb) pviews
<UIWindow: 0x135e0be70; frame = (0 0; 375 812); gestureRecognizers = <NSArray: 0x283f42310>; layer = <UIWindowLayer: 0x283142fa0>>
| <UITransitionView: 0x135e14430; frame = (0 0; 375 812); autoresize = W+H; layer = <CALayer: 0x2831688c0>>
| | <UIDropShadowView: 0x135e14be0; frame = (0 0; 375 812); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x283168980>>
| | | <UIView: 0x135e13cd0; frame = (0 0; 375 812); autoresize = W+H; layer = <CALayer: 0x283168620>>
| | | | <UIButton: 0x135e13320; frame = (100 200; 100 100); opaque = NO; layer = <CALayer: 0x283168780>>
| | | | | <UIButtonLabel: 0x135e23c50; frame = (31.6667 39; 37 22); text = ''; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x281268000>>
| | | | | | <_UILabelContentLayer: 0x283171be0> (layer)
(lldb) pviews self.view
<UIView: 0x135e13cd0; frame = (0 0; 375 812); autoresize = W+H; layer = <CALayer: 0x283168620>>
| <UIButton: 0x135e13320; frame = (100 200; 100 100); opaque = NO; layer = <CALayer: 0x283168780>>
| | <UIButtonLabel: 0x135e23c50; frame = (31.6667 39; 37 22); text = ''; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x281268000>>
| | | <_UILabelContentLayer: 0x283171be0> (layer)
- pvc(打印當(dāng)前頁面的控制器)
(lldb) pvc
<ViewController 0x135e0afc0>, state: appeared, view: <UIView 0x135e13cd0>
- presponder(打印響應(yīng)者鏈)
(lldb) presponder 0x149d05b60 //按鈕的在內(nèi)存中的真實(shí)地址
<UIButton: 0x149d05b60; frame = (100 200; 100 100); opaque = NO; layer = <CALayer: 0x280e3ab00>>
| <UIView: 0x149d039d0; frame = (0 0; 375 812); autoresize = W+H; layer = <CALayer: 0x280e3aa00>>
| | <ViewController: 0x149e07d80>
| | | <UIDropShadowView: 0x149d073a0; frame = (0 0; 375 812); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x280e3aae0>>
| | | | <UITransitionView: 0x149d06bf0; frame = (0 0; 375 812); autoresize = W+H; layer = <CALayer: 0x280e3aac0>>
| | | | | <UIWindow: 0x149e08c30; frame = (0 0; 375 812); gestureRecognizers = <NSArray: 0x280050420>; layer = <UIWindowLayer: 0x280e14f00>>
| | | | | | <UIWindowScene: 0x149e04330; scene = <FBSSceneImpl: 0x28202cc80; identifier: sceneID:com.ttt.jinxiao-default>; persistentIdentifier = 42D38740-A3B7-4D1F-BB16-34AA4FE0252A; activationState = UISceneActivationStateForegroundActive; settingsCanvas = <UIWindowScene: 0x149e04330>; windows = (
"<UIWindow: 0x149e08c30; frame = (0 0; 375 812); gestureRecognizers = <NSArray: 0x280050420>; layer = <UIWindowLayer: 0x280e14f00>>",
"<UITextEffectsWindow: 0x149d32600; frame = (0 0; 375 812); opaque = NO; autoresize = W+H; layer = <UIWindowLayer: 0x280e160a0>>"
)>
| | | | | | | <UIApplication: 0x149e02140>
| | | | | | | | <AppDelegate: 0x280e3a600>
- pactions(打印一個(gè)控件的響應(yīng)方法和調(diào)用者)
(lldb) pactions 0x149d05b60
<ViewController: 0x149e07d80>: btClicked
- pclass(打印class的繼承關(guān)系)
(lldb) pclass 0x149d05b60
UIButton
| UIControl
| | UIView
| | | UIResponder
| | | | NSObject
- fvc(根據(jù)ViewController的Class名字查找VC)
(lldb) fvc ViewController
0x105002580 ViewController
(lldb) fvc -v 0x105002580
Found the owning view controller.
<ViewController: 0x105002580>
- pmethods(打印一個(gè)類的類和實(shí)例方法)
(lldb) pmethods 0x105002580
Class Methods:
No methods were found
Instance Methods:
- (void)btClicked
- (void)setBtn:(id)arg0
- (void)testMethod:(id)arg0
- (void)setTestArray:(id)arg0
- (id)btn
- (void).cxx_destruct
- (void)touchesBegan:(id)arg0 withEvent:(id)arg1
- (void)viewDidLoad
- (id)test
- (id)testArray
- (void)setTest:(id)arg0
- pinternals(打印一個(gè)對(duì)象內(nèi)部的成員變量)
(lldb) pinternals 0x105002580
(ViewController) $16 = {
_test = nil
_testArray = nil
_btn = 0x0000000105107520
}
- taplog(我們需要先將程序暫停姻报,輸入taplog己英,程序會(huì)自己運(yùn)行,這時(shí)候點(diǎn)擊你需要查看的view吴旋,控制臺(tái)上就會(huì)顯示出你剛剛點(diǎn)擊的view相關(guān)信息损肛。)
(lldb) taplog
Process 669 resuming
<UIButton: 0x105107520; frame = (100 200; 100 100); opaque = NO; layer = <CALayer: 0x282a70f80>>
要查看的view必須能接收點(diǎn)擊事件,也就是他的userInteractionEnabled必須為YES才能被找到荣瑟,UILabel和UIImageView默認(rèn)userInteractionEnabled為NO治拿。
- flicker(將view閃爍一下,以便于查找view的位置)
flicker 0x105107520 //view的在內(nèi)存中的真實(shí)地址
- vs(在view層級(jí)中搜索view笆焰,并顯示出來)
(lldb) vs 0x105107520
Use the following and (q) to quit.
(w) move to superview
(s) move to first subview
(a) move to previous sibling
(d) move to next sibling
(p) print the hierarchy
<UIButton: 0x105107520; frame = (100 200; 100 100); opaque = NO; layer = <CALayer: 0x282a70f80>>
DerekSelander-LLDB
DerekSelander-LLDB是另一款比較好用的LLDB調(diào)試工具
README.md里面有安裝步驟劫谅,這里lz
是把lldb_commands
文件夾,放到了跟chisel同級(jí)目錄嚷掠,/usr/local/opt
,然后在~/.lldbinit
里面加上 command script import /usr/local/opt/lldb_commands/dslldb.py 就ok
了
常用命令
- search(在堆中搜索某個(gè)類的所有活動(dòng)實(shí)例,此類必須是動(dòng)態(tài)的(繼承NSObject / SwiftObject),目前不適用于NSString或NSNumber(標(biāo)記的指針對(duì)象))
(lldb) search UIView
<UIViewControllerWrapperView: 0x10b76dd00; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x283716880>>
<UIImageView: 0x10b587350; frame = (0 -0.333333; 414 0.333333); userInteractionEnabled = NO; layer = <CALayer: 0x28377cb40>>
<_UINavigationBarLargeTitleView: 0x10b54eb70; frame = (0 0; 0 0); clipsToBounds = YES; hidden = YES; layer = <CALayer: 0x2837aec60>>
...
- methods(打印所屬類別的所有方法和成員變量)
(lldb) methods 0x2814fceb0
<WCAccountLoginControlLogic: 0x2814fceb0>:
in WCAccountLoginControlLogic:
Properties:
@property (readonly) unsigned long hash;
@property (readonly) Class superclass;
@property (readonly, copy) NSString* description;
@property (readonly, copy) NSString* debugDescription;
Instance Methods:
- (void) startLogic; (0x10511d4e8)
- (void) stopLogic; (0x10511da50)
- (void) onOneClickLoginSwitchAccount; (0x10511e2e0)
- (void) onOneClickLoginProblem; (0x10511e314)
- (void) onOneClickLoginGoToSecurityCenter; (0x10511e34c)
- (void) onOneClickLoginGoToHelpCenter; (0x10511e384)
...
- sbt(恢復(fù)去符號(hào)的函數(shù)調(diào)用棧信息)
(lldb) b -a 0x10511dbcc //對(duì)一個(gè)函數(shù)方法下斷點(diǎn)
(lldb) c
Process 19583 resuming
(lldb) bt //查看函數(shù)堆棧調(diào)用信息捏检,frame #0是去符號(hào)的函數(shù)調(diào)用信息
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x000000010511dbcc WeChat`___lldb_unnamed_symbol142055$$WeChat
frame #1: 0x0000000193667a44 UIKitCore`-[UIApplication sendAction:to:from:forEvent:] + 96
(lldb) sbt //frame #0 恢復(fù)了去符號(hào)的函數(shù)調(diào)用信息
frame #0 : 0x10511dbcc WeChat`-[WCAccountLoginControlLogic onFirstViewLogin]
frame #1 : 0x193667a44 UIKitCore`-[UIApplication sendAction:to:from:forEvent:] + 96
README.md里面還有其他命令,可以自己去嘗試
Cycript
Cycript是由Cydia
創(chuàng)始人Saurik推出的一款腳本語言不皆,Cycript
混合了OC贯城、JavaScript
語法的解釋器,這意味著我們能夠在一個(gè)命令中使用OC
或者JavaScript
霹娄,甚至兩者并用能犯。它能夠掛鉤正在運(yùn)行的進(jìn)程,能夠在運(yùn)行時(shí)修改很多東西犬耻。
Cycript的安裝
1. 下載Cycript后踩晶,解壓后直接把 cycript_0文件夾放到 /opt 目錄下.
2. Terminal執(zhí)行如下命令
$ cd /opt/cycript_0
$ ./cycript
如果出現(xiàn)
dyld: Library not loaded: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/libruby.2.0.0.dylib
Referenced from: /opt/cycript_0/./Cycript.lib/cycript-apl
Reason: image not found
Abort trap: 6
這個(gè)錯(cuò)誤是因?yàn)殡娔X的ruby
版本太高導(dǎo)致
3. 查看電腦ruby版本
$ cd /System/Library/Frameworks/Ruby.framework/Versions/
$ ls
2.3 Current
4. 創(chuàng)建Ruby2.0版本文件,并將2.3版本文件拷貝到2.0中
sudo mkdir -p /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/
sudo ln -s /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/libruby.2.3.0.dylib /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/libruby.2.0.0.dylib
如果出現(xiàn)
mkdir: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/: Operation not permitted
5. 關(guān)閉系統(tǒng)的SIP
系統(tǒng)完整性保護(hù)(SIP)
- 通過重新啟動(dòng)計(jì)算機(jī)并在啟動(dòng)時(shí)按住Command+R鍵啟動(dòng)到恢復(fù)操作系統(tǒng)枕磁。
- 從 Utilities 菜單啟動(dòng) Terminal渡蜻。
- 輸入以下命令:csrutil disable
- 重新啟動(dòng)您的計(jì)算機(jī)
6. 重新執(zhí)行步驟4和步驟2,出現(xiàn)如下標(biāo)志计济,安裝成功茸苇!
cy#
control + D 退出 Cycript
Cycript配置環(huán)境變量
1. 編輯bash_profile文件
$ cd ~/
$ vim .bash_profile
2. 添加如下配置信息
#Cycript
export CY_PATH_ROOT=/opt/cycript_0
export PATH=$CY_PATH_ROOT:$PATH
3. 退出文件編輯并保存,執(zhí)行如下命令查看,cycript環(huán)境變量配置成功
$ cycript
cy#
Cycript的簡單使用
Cycript連接手機(jī)有兩種方式:
- 通過ssh登錄峭咒,需要越獄手機(jī)打開ssh端口
- 在非越獄手機(jī)上税弃,我們可以使用MonkeyDev(iOS逆向-反Hook防護(hù)(VI)里面有詳細(xì)介紹安裝和使用)。它里面有句代碼
CYListenServer(6666)
凑队,代表在當(dāng)前應(yīng)用給Cycript
的Server
端申請了一個(gè)端口號(hào)6666
则果,我們可以在終端通過這個(gè)端口號(hào)在運(yùn)行時(shí)給當(dāng)前應(yīng)用附加Cycript
(MonkeyDev已經(jīng)幫我們注入了libcycript.dylib
)
$ cycript -r 172.20.0.240:6666
cy#
172.20.0.240是手機(jī)網(wǎng)絡(luò)的ip
cy# UIWindow.keyWindow()
#"<iConsoleWindow: 0x10b139fc0; baseClass = UIWindow; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x283099110>; layer = <UIWindowLayer: 0x283e296e0>>"
cy# [UIApplication sharedApplication]
#"<UIApplication: 0x10b115b50>"
cy# UIApp
#"<UIApplication: 0x10b115b50>"
cy# var keyWindow = UIWindow.keyWindow()
#"<iConsoleWindow: 0x10b139fc0; baseClass = UIWindow; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x283099110>; layer = <UIWindowLayer: 0x283e296e0>>"
cy# keyWindow
#"<iConsoleWindow: 0x10b139fc0; baseClass = UIWindow; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x283099110>; layer = <UIWindowLayer: 0x283e296e0>>"
cy# keyWindow.rootViewController
#"<MMUINavigationController: 0x10b920a00>"
cy# #0x10b920a00 //根據(jù)地址獲取對(duì)象
#"<MMUINavigationController: 0x10b920a00>"
cy# *#0x10b920a00 //獲取對(duì)象的所有成員變量和值
{isa:MMUINavigationController,_responderFlags:@error,_overrideTransitioningDelegate:null,_view:#"<UILayoutContainerView: 0x10b13a2f0; frame = (0 0; 414 736); clipsToBounds = YES;
...
cy# [i for(i in *keyWindow)] //獲取對(duì)象的所有成員變量(key)
["isa","_responderFlags","_constraintsExceptingSubviewAutoresizingConstraints","_cachedTraitCollection","_animationInfo","_layer","_layerRetained","_gestureRecognizers","_window","_subvi....
cy# choose(UIButton) //獲取所有UIButton的對(duì)象
[#"<UIButton: 0x10b54ba10; frame = (269 20; 145 49); opaque = NO; autoresize = LM; layer = <CALayer: 0x283efd4e0>>",#"<FixTitleColorButton: 0x10b11d960; baseClass = UIButton; frame = (20 18; 177 47); clipsToBounds = YES; opaque = NO; autoresize = RM; layer = <CALayer: 0x283e20a20>>",#"<FixTitleColorButton: 0x10b1477b0; baseClass = UIButton; frame = (217 18; 177 47); clipsToBounds = YES; opaque = NO; autoresize = LM; layer = <CALayer: 0x283ef8020>>"]
cy# keyWindow.recursiveDescription().toString() //打印所有的視圖層級(jí)
`<iConsoleWindow: 0x10b139fc0; baseClass = UIWindow; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x283099110>; layer = <UIWindowLayer: 0x283e296e0>>
| <UILayoutContainerView: 0x10b13a2f0; frame = (0 0; 414 736); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x283099b30>; layer = <CALayer: 0x283e29ac0>>
...
Shell腳本連接
1. 創(chuàng)建一個(gè)Shell腳本文件cylogin.sh, 路徑如下
$ open ~/ 打開根目錄
2. 添加可執(zhí)行權(quán)限
$ chmod +x cylogin.sh
3. 配置環(huán)境變量
export NJSHELL=/Users/niujf/NJShell
export PATH=$CY_PATH_ROOT:$PATH:$NJSHELL
如果以前沒有配置環(huán)境變量就是
export PATH=$NJSHELL
4. 執(zhí)行Shell腳本文件cylogin.sh
$ sh cylogin.sh
Cycript的高級(jí)用法
cy# APPID
@"com.ttt.jinxiao"
cy# pviews
function (){return UIApp.keyWindow.recursiveDescription().toString()}
cy# pviews() //打印當(dāng)前頁面的view
`<iConsoleWindow: 0x11bd49860; baseClass = UIWindow; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x2831f62b0>; layer = <UIWindowLayer: 0x283f7e320>>
| <UILayoutContainerView: 0x11bd48310; frame = (0 0; 414 736); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x2831cb0f0>; layer = <CALayer: 0x283f7d380>>
| | <UINavigationTransitionView: 0x11be2c9b0; frame = (0 0; 414 736); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x283f65300>>
| | | <UIViewControllerWrapperView: 0x11bd601d0; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x283fa09e0>>
| | | | <UIView: 0x11bd24df0; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x283f749a0>>
| | | | | <UIView: 0x11bd37310; frame = (0 20; 414 801); autoresize = W; layer = <CALayer: 0x283f74bc0>>
| | | | | | <UIImageView: 0x11be11970; frame = (0 -20; 414 736); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x283f70ec0>>
| | | | | <UIView: 0x11be12b70; frame = (0 651; 414 65); autoresize = W+TM; layer = <CALayer: 0x283f70fc0>>
| | | | | | <FixTitleColorButton: 0x11be35910; baseClass = UIButton; frame = (20 18; 177 47); clipsToBounds = YES; opaque = NO; autoresize = RM; layer = <CALayer: 0x283f71040>>
| | | | | | | <UIButtonLabel: 0x11bd0dfe0; frame = (70 12.6667; 37 22); text = '\u767b\u5165'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x281c4e760>>
| | | | | | | | <_UILabelContentLayer: 0x283fa0ee0> (layer)
| | | | | | <FixTitleColorButton: 0x11be40660; baseClass = UIButton; frame = (217 18; 177 47); clipsToBounds = YES; opaque = NO; autoresize = LM; layer = <CALayer: 0x283faba40>>
| | | | | | | <UIButtonLabel: 0x11be40a70; frame = (70 12.6667; 37 22); text = '\u8a3b\u518a'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x281c45cc0>>
| | | | | | | | <_UILabelContentLayer: 0x283fa0da0> (layer)
| | | | | <UIButton: 0x11bd37fc0; frame = (269 20; 145 49); opaque = NO; autoresize = LM; layer = <CALayer: 0x283f52600>>
| | | | | | <UIButtonLabel: 0x11be427b0; frame = (15 16; 115 17); text = '\u7e41\u9ad4\u4e2d\u6587\uff08\u81fa\u7063\uff09'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x281c45950>>
| | | | | | | <_UILabelContentLayer: 0x283fa0d20> (layer)`
cy# pvcs() //打印當(dāng)前頁面的控制器
"<MMUINavigationController 0x11c0f3e00>, state: appeared, view: <UILayoutContainerView 0x11bd48310>\n | <WCAccountLoginFirstViewController 0x11c87ae00>, state: appeared, view: <UIView 0x11bd24df0>"
cy# pactions(#0x11be35910) //獲取對(duì)象的action
"<WCAccountLoginControlLogic: 0x281c4a8a0> onFirstViewLogin"
cy# rp(#0x11be35910) //獲取對(duì)象的響應(yīng)者
`<FixTitleColorButton: 0x11be35910; baseClass = UIButton; frame = (20 18; 177 47); clipsToBounds = YES; opaque = NO; autoresize = RM; layer = <CALayer: 0x283f71040>>
<UIView: 0x11be12b70; frame = (0 651; 414 65); autoresize = W+TM; layer = <CALayer: 0x283f70fc0>>
<UIView: 0x11bd24df0; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x283f749a0>>
<WCAccountLoginFirstViewController: 0x11c87ae00>
<UIViewControllerWrapperView: 0x11bd601d0; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x283fa09e0>>
<UINavigationTransitionView: 0x11be2c9b0; frame = (0 0; 414 736); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x283f65300>>
<UILayoutContainerView: 0x11bd48310; frame = (0 0; 414 736); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x2831cb0f0>; layer = <CALayer: 0x283f7d380>>
<MMUINavigationController: 0x11c0f3e00>
<iConsoleWindow: 0x11bd49860; baseClass = UIWindow; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x2831f62b0>; layer = <UIWindowLayer: 0x283f7e320>>
<UIWindowScene: 0x11be11c40; scene = <FBSSceneImpl: 0x28113c500; identifier: sceneID:com.ttt.jinxiao-default>; persistentIdentifier = 62B17F00-49F3-4938-80BC-83289F774DF4; activationState = UISceneActivationStateForegroundActive; settingsCanvas = <UIWindowScene: 0x11be11c40>; windows = (
"<iConsoleWindow: 0x11bd1a530; baseClass = UIWindow; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x2831a7600>; layer = <UIWindowLayer: 0x283f1dee0>>",
"<iConsoleWindow: 0x11bd49860; baseClass = UIWindow; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x2831f62b0>; layer = <UIWindowLayer: 0x283f7e320>>",
"<UITextEffectsWindow: 0x11be3cc90; frame = (0 0; 414 736); opaque = NO; autoresize = W+H; layer = <UIWindowLayer: 0x283fb3f00>>"
)>
<UIApplication: 0x11bd16880>
<MicroMessengerAppDelegate: 0x28032ef00>`
在MonkeyDev的MDConfig.plist
文件中幔翰,里面有鏈接,打開可以看到上面的命令其實(shí)都是已經(jīng)封裝好的
cy文件的封裝
1. 在MonkeyDev中新建一個(gè)空的文件西壮,命名test.cy
2. 在Build Phases->Copy Files中添加test.cy文件
3. 將test.cy文件類型改為 javaScript Source類型遗增,擼代碼,可以參考mjcript
4. 運(yùn)行項(xiàng)目款青,終端調(diào)用
$ sh cylogin.sh
cy# @import test
{}
cy# MJAppId
@"com.ttt.jinxiao"
...
里面封裝了很多命令就不一一演示了