看過"小黃書"的朋友們應(yīng)該都對函數(shù)OC函數(shù)下斷點(diǎn)步驟很清楚:
1次氨、LLDB連接到程序
2、調(diào)動命令 image -o -f查看app二進(jìn)制偏移
3艾凯、在hopper或者IDA查看需要下斷點(diǎn)的函數(shù)的文件偏移
4献幔、LLDB輸入br s -a 'app二進(jìn)制偏移+函數(shù)的文件偏移'
但是作為傳統(tǒng)的方式以上方法存在兩個問題
1、需要hopper或者IDA支持览芳,這兩個軟件對電腦配置的要求較高斜姥,而且反匯編速度較慢。
2沧竟、不能對“已經(jīng)通過運(yùn)行時替換函數(shù)實(shí)現(xiàn)地址的函數(shù)”進(jìn)行攔截
作為一個逆向開發(fā)新手铸敏,特分享一個以小技巧,可以免除對反匯編軟件的依賴悟泵,而且攔截成功率更高杈笔。
1、LLDB連接到程序
2糕非、找到需要下斷點(diǎn)的類蒙具,在LLDB命令行輸入po [MMServiceCenter _shortMethodDescription](以“微信”的[MMServiceCenter getService:]函數(shù)為例)效果如下:
3、然后在命令行輸入b 0x100bd04f0即可實(shí)現(xiàn)下斷操作朽肥,實(shí)踐效果如下:
最后再分享個打印數(shù)據(jù)模型內(nèi)容很有用的私有函數(shù)方法[模型對象 _ivarDescription]
recursiveDescription
I don't think it necessary to introduce this method again. It prints the hierarchy of an UIView object. Here's how we use it in Cycript:
cy# [[UIApp keyWindow] recursiveDescription].toString()
`<iConsoleWindow: 0x156b6410; baseClass = UIWindow; frame = (0 0; 320 480); autoresize = W+H; gestureRecognizers = <NSArray: 0x156b6bc0>; layer = <UIWindowLayer: 0x156b6720>>
| <UILayoutContainerView: 0x16258d80; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x16258e00>>
| | <UITransitionView: 0x16259610; frame = (0 0; 320 480); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x16259760>>
| | | <UIViewControllerWrapperView: 0x16243bb0; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x1625a670>>
| | | | <UILayoutContainerView: 0x1601dd70; frame = (0 0; 320 480); autoresize = W+H; gestureRecognizers = <NSArray: 0x16001650>; layer = <CALayer: 0x16073fe0>>
| | | | | <UINavigationTransitionView: 0x16004cc0; frame = (0 0; 320 480); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x16004e10>>
| | | | | | <UIViewControllerWrapperView: 0x1629d9a0; frame = (0 0; 320 480); layer = <CALayer: 0x1629da10>>
...
| | | <MMBadgeView: 0x160055a0; baseClass = UIImageView; frame = (203 1; 20 20); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x16005640>>
| | | | <MMUILabel: 0x16004ec0; baseClass = UILabel; frame = (0 0; 0 0); hidden = YES; userInteractionEnabled = NO; tag = 10032; layer = <CALayer: 0x16004f70>>
| | | <MMBadgeView: 0x16259810; baseClass = UIImageView; frame = (283 -4; 30 30); hidden = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x162598b0>>
| | | | <MMUILabel: 0x1625a180; baseClass = UILabel; frame = (0 0; 0 0); userInteractionEnabled = NO; tag = 10032; layer = <CALayer: 0x1625a230>>
_printHierarchy
Skip UIViews and nextResponders to get ViewControllers directly. Refer to this post78 for details.In short, it's:
[[[UIWindow keyWindow] rootViewController] _printHierarchy].toString()
_autolayoutTrace
Simplified recursiveDescription, cuts off lots of descriptions of UIViews. Here's how we use it in Cycript:
cy# [[UIApp keyWindow] _autolayoutTrace].toString()
*<iConsoleWindow:0x156b6410>
| *<UILayoutContainerView:0x16258d80>
| | *<UITransitionView:0x16259610>
| | | *<UIViewControllerWrapperView:0x16243bb0>
| | | | *<UILayoutContainerView:0x1601dd70>
| | | | | *<UINavigationTransitionView:0x16004cc0>
| | | | | | *<UIViewControllerWrapperView:0x1629d9a0>
...
| | | | <MMUILabel:0x1624b250>
| | | <MMBadgeView:0x160055a0>
| | | | <MMUILabel:0x16004ec0>
| | | <MMBadgeView:0x16259810>
| | | | <MMUILabel:0x1625a180>`
_ivarDescription
Prints all names and values of instance variables of a specified object. Here's how we use it in Cycript:
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
Prints all properties, instance methods and class methods of a specified object. Here's how we use it in Cycript:
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)`
這些實(shí)用的私有函數(shù)給逆向提供了大大的便利禁筏,不只是逆向開發(fā),正向開發(fā)中衡招,如果要分析競品的app篱昔,如果要去分析別人的某個功能則么實(shí)現(xiàn)的都很有用!
參考:
- http://swiftiostutorials.com/using-private-undocumented-ios-methods-debugging/45
- http://iosre.com/t/shortcut-to-find-the-viewcontrollers-class-name-on-the-keywindow/2834
- http://bbs.iosre.com/t/lldb-oc/6711
- http://iosre.com/t/powerful-private-methods-for-debugging-in-cycript-lldb/3414
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者