一、准备
ios系统越狱环境
安装ssh
安装cycript
二、执行命令
找到进程注入:
chentekiiPhone:/var/containers/Bundle/Application root# ps aux | grep test
mobile 758 0.0 1.0 5031504 20176 ?? Ss 2:20PM 1:36.66 /var/containers/Bundle/Application/6E27936D-08FB-4F5B-A7BC-FC1A4D6AEB05/test.app/test
root 1182 0.0 0.2 4207888 4560 s000 S+ 2:29PM 0:00.01 grep test
chentekiiPhone:/var/containers/Bundle/Application root# cycript -p 758
cy#
注入之后执行hook指令
@import com.saurik.substrate.MS
var oldm = {};
var log = []
MS.hookMessage(objc_getClass("ViewController"),@selector(viewDidLoad), function(arg0) {
var d = [NSDate date]
log.push([d.toString()]);
return oldm->call(this, arg0);
}, oldm)
打印log
cy# log
[["2017-03-15 03:30:15 +0000"],["2017-03-15 03:30:15 +0000"],["2017-03-15 03:30:15 +0000"]]
choose命令,获取内存对象地址
cy# choose(ViewController)
[#"<ViewController: 0x101031b20>"]
操作符来获取这个对象
[#0x101031b20 show]
description函数能够把对象的内容表示成一个NSString,object_getClassName函数能够把对象
的类名表示成一个char*,两者可分别用%@和%s打印出来,这就为解析参数提供了足够参考。
cy# [#0x101031b20 description]
@"<ViewController: 0x101031b20>"
cy# object_getClassName(0x101031b20)
&"__NSCFNumber"
recursiveDescription - 打印UIView对象
cy# [[UIApp keyWindow] recursiveDescription].toString()
`<UIWindow: 0x10092f020; frame = (0 0; 375 667); gestureRecognizers = <NSArray: 0x281c38960>; layer = <UIWindowLayer: 0x28121b5a0>>
| <UITransitionView: 0x1009317e0; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x28121e620>>
| | <UIDropShadowView: 0x100934800; frame = (0 0; 375 667); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x28121e380>>
| | | <UIView: 0x100934290; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x28121e880>>
| | | | <_UILayoutGuide: 0x100934470; frame = (0 0; 0 20); hidden = YES; layer = <CALayer: 0x28121fc80>>
| | | | <_UILayoutGuide: 0x100934a00; frame = (0 667; 0 0); hidden = YES; layer = <CALayer: 0x28121e6e0>>
| <XLFloatBtn: 0x100935560; baseClass = UIButton; frame = (335 313.5; 40 40); opaque = NO; layer = <CALayer: 0x281215f20>>
| | <UIButtonLabel: 0x100940bc0; frame = (6.5 12; 27 16); text = '\u5b58\u6863'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x283103cf0>>
| | | <_UILabelContentLayer: 0x28122bf20> (layer)`
_printHierarchy - 直接打印所有UIViewController
cy# [[[UIWindow keyWindow] rootViewController] _printHierarchy].toString()
_autolayoutTrace – recursiveDescription的简化版,去掉了UIView的一些描述
cy# [[UIApp keyWindow] _autolayoutTrace].toString()
`
UIWindow:0x10092f020
| UITransitionView:0x1009317e0
| | UIDropShadowView:0x100934800
| | | \u2022UIView:0x100934290
| | | | *_UILayoutGuide:0x100934470
| | | | *_UILayoutGuide:0x100934a00
| XLFloatBtn:0x100935560'\u5b58\u6863'
| | UIButtonLabel:0x100940bc0'\u5b58\u6863'
Legend:
\t* - is laid out with auto layout
\t+ - is laid out manually, but is represented in the layout engine because translatesAutoresizingMaskIntoConstraints = YES
\t\u2022 - layout engine host`
_ivarDescription – 打印某个对象所有instance的名字和值
cy# [choose(SBApplication)[0] _ivarDescription].toString()
`<SBApplication: 0x1766cab0>:
in SBApplication:
\t_bundleIdentifier (NSString*): @"com.apple.social.remoteui.SocialUIService"
\t_displayIdentifier (NSString*): @"com.apple.social.remoteui.SocialUIService"
\t_path (NSString*): @"/Applications/SocialUIService.app"
\t_bundleVersion (NSString*): @"87"
\t_defaultImageNamesByScreenType (NSMutableDictionary*): <__NSDictionaryM: 0x17672a90>
\t_defaultImageNamesForOrientation (NSDictionary*): nil
...
in NSObject:
\tisa (Class): SBApplication`
_methodDescription – 打印某个对象的属性,实例和类方法
cy# [choose(SBApplicationController)[0] _methodDescription].toString()
`<SBApplicationController: 0x17642990>:
in SBApplicationController:
\tClass Methods:
\t\t+ (void) setClearSystemAppSnapshotsWhenLoaded:(BOOL)arg1; (0x1b2ad1)
...
\t\t+ (id) sharedInstanceIfExists; (0x1b2b6d)
\tInstance Methods:
\t\t- (id) setupApplication; (0x1b3e3d)
...
\t\t- (id) applicationWithDisplayIdentifier:(id)arg1; (0x1b3d0d)
in NSObject:
\tClass Methods:
\t\t+ (bool) cy\$hasImplicitProperties; (0xdb45d80)
...
\t\t+ (void) finalize; (0x39a49ad1)
\tProperties:
\t\t@property (nonatomic) BOOL isAccessibilityElement; (@dynamic isAccessibilityElement;)
...
\t\t@property (nonatomic) BOOL shouldGroupAccessibilityChildren; (@dynamic shouldGroupAccessibilityChildren;)
\tInstance Methods:
\t\t- (id) cy\$toCYON:(bool)arg1 inSet:(set<void *, std::less<void *>, std::allocator<void *> >*)arg2; (0xdb45b60)
...
\t\t- (void) finalize; (0x39a49ad5)`
找到目标App的Documents目录路径
cy# [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]
#"file:///var/mobile/Containers/Data/Application/5CA182CC-253F-4F55-814B-DDEB42FEDF19/Documents/"
获取bundle info
cy# [[NSBundle mainBundle] infoDictionary].toString()
`{
BuildMachineOSBuild = 19H2;
CFBundleDevelopmentRegion = en;
CFBundleExecutable = test;
CFBundleIdentifier = "cn.6us.test";
CFBundleInfoDictionaryVersion = "6.0";
CFBundleName = test;
CFBundleNumericVersion = 16809984;
CFBundlePackageType = APPL;
CFBundleShortVersionString = "1.0";
CFBundleSupportedPlatforms = (
iPhoneOS
);
CFBundleVersion = 1;
DTCompiler = "com.apple.compilers.llvm.clang.1_0";
DTPlatformBuild = 18A390;
DTPlatformName = iphoneos;
DTPlatformVersion = "14.0";
DTSDKBuild = 18A390;
DTSDKName = "iphoneos14.0";
DTXcode = 1201;
DTXcodeBuild = 12A7300;
LSRequiresIPhoneOS = 1;
MinimumOSVersion = "9.2";
UIApplicationSceneManifest = {
UIApplicationSupportsMultipleScenes = 0;
UISceneConfigurations = {
UIWindowSceneSessionRoleApplication = (
{
UISceneConfigurationName = "Default Configuration";
UISceneDelegateClassName = SceneDelegate;
UISceneStoryboardFile = Main;
}
);
};
};
UIApplicationSupportsIndirectInputEvents = 1;
UIDeviceFamily = (
1,
2
);
UILaunchStoryboardName = LaunchScreen;
UIMainStoryboardFile = Main;
UIRequiredDeviceCapabilities = (
arm64
);
UISupportedInterfaceOrientations = (
UIInterfaceOrientationPortrait,
UIInterfaceOrientationLandscapeLeft,
UIInterfaceOrientationLandscapeRight
);
}`