美文网首页iOS 逆向
不用反汇编!lldb对oc函数下断点的黑科技

不用反汇编!lldb对oc函数下断点的黑科技

作者: 飘金 | 来源:发表于2017-08-23 13:39 被阅读509次

    原文出处

    看过"小黄书"的朋友们应该都对函数OC函数下断点步骤很清楚:

    1、LLDB连接到程序

    2、调动命令 image -o -f查看app二进制偏移

    3、在hopper或者IDA查看需要下断点的函数的文件偏移

    4、LLDB输入br s -a 'app二进制偏移+函数的文件偏移'

    但是作为传统的方式以上方法存在两个问题

    1、需要hopper或者IDA支持,这两个软件对电脑配置的要求较高,而且反汇编速度较慢。

    2、不能对“已经通过运行时替换函数实现地址的函数”进行拦截

    作为一个逆向开发新手,特分享一个以小技巧,可以免除对反汇编软件的依赖,而且拦截成功率更高。

    1、LLDB连接到程序

    2、找到需要下断点的类,在LLDB命令行输入po [MMServiceCenter _shortMethodDescription](以“微信”的[MMServiceCenter getService:]函数为例)效果如下:

    3、然后在命令行输入b 0x100bd04f0即可实现下断操作,实践效果如下:

    最后再分享个打印数据模型内容很有用的私有函数方法[模型对象 _ivarDescription]

    在结合另外一篇文章的有用Sioux函数

    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)`
    

    这些实用的私有函数给逆向提供了大大的便利,不只是逆向开发,正向开发中,如果要分析竞品的app,如果要去分析别人的某个功能则么实现的都很有用!

    参考:

    1. http://swiftiostutorials.com/using-private-undocumented-ios-methods-debugging/45
    2. http://iosre.com/t/shortcut-to-find-the-viewcontrollers-class-name-on-the-keywindow/2834
    3. http://bbs.iosre.com/t/lldb-oc/6711
    4. http://iosre.com/t/powerful-private-methods-for-debugging-in-cycript-lldb/3414

    相关文章

      网友评论

        本文标题:不用反汇编!lldb对oc函数下断点的黑科技

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