针对Mail的逆向分析过程中,思路及问题

大家好,我现在正在试图逆向系统自带 mobileMail.app 。
过程中遇到很多问题,希望得到大家的帮助。
也希望这篇帖子将来能为其他人提供参考。
在此感谢大家。欢迎大家多回帖纠正我思路上的错误与不足。

首先,dump出mail.app的头文件, → mailHeaders.zip (230 KB)
再结合Reveal,找到几个关键词: Compose、BarItem、Navigation等(欢迎大家多补充)
通过观察,决定重点分析以下几个头文件:(不确定我的方向是否是最优的,希望大家回帖提供更正确的思路)
1.MessageViewController.h
2.ComposeNavigationController.h
3.MailAppController.h
4.MailDetailViewController.h
5.MFMailComposeDeliveryController

MobileMail.app 可执行文件 → MobileMail.rar (675 KB)

通过对 MessageViewController.h 的分析+验证,确定这就是mail最主要ViewController,


我在MessageViewController.h中找到了页面里大多数控件的方法。

我已经找了很久,但还是找不到newMail的控件,请问如何定位newMail的方法?
我无法在MessageViewController.h 中通过send、edit、compose、new、等关键字搜索到该方法。

newMail有两种操作,按规律应该会有类似deletelongpressed的方法名。但是通过long、pressed关键字也无法找到
事实上我找到了newMail的控件:

LongPressableButtonItem *_composeButtonItem;

但还是无法通过关键字找到其对应操作的方法。我该如何去寻找?枚举所有MessageViewController.h里的方法?工作量有点大啊!除了这个还有别的办法或技巧吗?@snakeninny

LongPressableButtonItem 是什么?私有类?完全查不到资料。该如何处理?
有个LongPressableButtonItem.h:

#import "_AAAccountConfigChangedNotification.h"

@interface LongPressableButtonItem : _AAAccountConfigChangedNotification
{
    id _longPressTarget;
    SEL _longPressAction;
}

- (void)setLongPressTarget:(id)fp8 action:(SEL)fp12;
- (id)createViewForToolbar:(id)fp8;
- (void)longPressGestureRecognized:(id)fp8;

@end

但是无法找到 _AAAccountConfigChangedNotification.h
却有很多其他的头文件:


我用这段代码:

- (void)actionSheet:(id)fp8 clickedButtonAtIndex:(int)fp12
{
    NSLog(@"\n\n    ****    \n   ****    MessageViewController:  actionSheet: fp8: %@   fp12 :%d \n    ****    \n",fp8,fp12);
    %orig;
}

Log出来:
****
**** MessageViewController: actionSheet: fp8 <UIActionSheet: 0x178232a0; frame = (0 0; 272 132); opaque = NO; layer = <CALayer: 0x178233c0>> fp12 :1
****

请问我该如何利用者些信息跟踪到我想要分析的forward页面的ViewController?

预留位置

预留位置

预留位置

reveal不能捕获编写按钮的对象吗?

reveal能捕获按钮的对象,但是我从中只获得UInaNavigationRarItem的类名,不知如何利用这些信息

那就用Cycript打印出这个window的recursiveDescription,定位到这个UINavigationBarItem的类,然后通过subviews方法提取出其中的UIButton对象,假设它就叫button。因为UIButton继承自UIControl,所以可以通过UIControl的类方法

actionsForTarget:forControlEvent:

定位其action selector:

  1. 先用Cycript打印出[button allTargets],是一个数组;
  2. 遍历数组,得到每一个target,然后打印[button actionsForTarget:target forControlEvent:[button allControlEvents]],得到selector。
    这种思路会在书的第二版我写的例子中多次碰到,反复讲解,有一本书备着,这些问题应该不存在了

已经找到了UIActionSheet的delegate,就看看哪个类实现了actionSheet:clickedButtonAtIndex:这个方法,然后在IDA里看看那个方法的内部做了些什么

哪个类实现了actionSheet:clickedButtonAtIndex:这个方法?

这是MessageViewController.h里的方法,应该就是这个类没错吧

问题是除了replyButton,其他如flagButton等也通过这个actionSheet:clickedButtonAtIndex:实现选取caozuo。
并且,虽然replyButton、flagButton的id是固定的,点击他们出现的SelectedViewingContext的id也是固定的,
但是actionSheet:clickedButtonAtIndex:的第一个id型参数确是一直在变化的。

这是我的验证代码:

#import <UIKit/UIKit.h>
%hook MessageViewController//对邮件操作(比如选择标记、回复、转发)时调用
- (void)replyButtonClicked:(id)fp8
{
    NSLog(@"\n\n    ****    \n   ****    MessageViewController: replyButtonClicked (id)fp8: %@ \n    ****    \n",fp8);
    %orig;
}
- (void)markButtonClicked:(id)fp8
{
    NSLog(@"\n\n    ****    \n   ****    MessageViewController: markButtonClicked (id)fp8: %@ \n    ****    \n",fp8);
    %orig;
}
- (void)setSelectedViewingContext:(id)fp8
{
    NSLog(@"\n\n    ****    \n   ****    MessageViewController: setSelectedViewingContext (id)fp8: %@ \n    ****    \n",fp8);
    %orig;
}
- (id)selectedViewingContext
{
    NSLog(@"\n\n    ****    \n   ****    MessageViewController: selectedViewingContext:%@ \n    ****    \n",%orig);
    return(%orig);
}
- (void)actionSheet:(id)fp8 clickedButtonAtIndex:(int)fp12
{
    NSLog(@"\n\n    ****    \n   ****    MessageViewController:  actionSheet:%@    :%d \n    ****    \n",fp8,fp12);
    %orig;
}
%end

这是输出的Log : → actionSheetLog.zip (579 Bytes)

我通过什么能确定我的actionSheet是replyButton发送的呢?

你用LLDB在这个函数的开头下一个断点,然后点击编写按钮,看看能不能停下来。如果停下来了,就

po $r0

看看第一个参数是什么

我没有用Cycript,用了下面的代码:

%hook ComposeNavigationController

- (void)viewDidAppear:(BOOL)fp8
{
    NSLog(@"\n\n----    \n----    ComposeNavigationController: %@ \n----    viewDidAppear: fp8: %d\n----\n",self,fp8);
    NSLog(@"\n\n----    \n----    view : %@ \n----\n",[self view]);
    NSLog(@"\n\n----    \n----    recursiveDescription : %@ \n----\n",[self view ] recursiveDescription]);
    %orig;
}

[self view ] recursiveDescription] 会报警告:
getSendAction.xm:9:85: Instance method ‘-recursiveDescription’ not found (return type defaults to ‘id’)
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIView.h:113:40: Receiver is instance of class declared here

正常的吗?
得到了Log → recursiveDescription.zip (2.91 KB)
找到了我想要的:
| <UINavigationBar: 0x15f682b0; frame = (0 0; 768 44); opaque = NO; autoresize = W; gestureRecognizers = <NSArray: 0x15d22140>; layer = <CALayer: 0x15d104f0>>
| | <_UINavigationBarBackground: 0x15f6a110; frame = (0 0; 768 44); opaque = NO; autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x15f67100>>
| | | <_UIBackdropView: 0x15d07790; frame = (0 0; 768 44); opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <_UIBackdropViewLayer: 0x15fc8070>>
| | | | <_UIBackdropEffectView: 0x15fbc5c0; frame = (0 0; 768 44); clipsToBounds = YES; opaque = NO; autoresize = W+H; userInteractionEnabled = NO; animations = { filters.colorMatrix.inputColorMatrix=<CABasicAnimation: 0x17080200>; }; layer = <CABackdropLayer: 0x15fbba10>>
| | | | <UIView: 0x15f913e0; frame = (0 0; 768 44); hidden = YES; opaque = NO; autoresize = W+H; userInteractionEnabled = NO; animations = { backgroundColor= <CABasicAnimation: 0x170f1010>; }; layer = <CALayer: 0x15f88580>>
| | | <UIImageView: 0x15fbd300; frame = (0 44; 768 0.5); userInteractionEnabled = NO; layer = <CALayer: 0x15f5aae0>>
| | <UINavigationItemView: 0x15dfc000; frame = (328.5 8; 111.5 27); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x15f64ab0>>
| | | <UILabel: 0x15d00220; frame = (0 3; 111.5 22); text = ‘New Message’; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x15d1f510>>
| | <UINavigationButton: 0x1707b670; frame = (16 8; 54 30); opaque = NO; layer = <CALayer: 0x15e006a0>>
| | | <UIButtonLabel: 0x15e14760; frame = (0 4; 54 21); text = ‘Cancel’; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x15e08fe0>>
| | <UINavigationButton: 0x1707db40; frame = (697 8; 55 30); opaque = NO; layer = <CALayer: 0x17072140>>
| | | <UIButtonLabel: 0x15e14980; frame = (14 4; 41 21); text = ‘Send’; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x170ba560>>

我想问问Reavel是不是就用的这个原理?
你说的

actionsForTarget:forControlEvent:

方法(就是书上220页内容)我还不是很懂。回头试试再问

reveal是不是用的这个我不清楚,但我知道通过这种方式可以达到reveal的效果

newMail有两种操作,按规律应该会有类似deletelongpressed的方法名。但是通过long、pressed关键字也无法找到
事实上我找到了newMail的控件:

LongPressableButtonItem *_composeButtonItem;

但还是无法通过关键字找到其对应操作的方法。我该如何去寻找?枚举所有MessageViewController.h里的方法?工作量有点大啊!除了这个还有别的办法或技巧吗?@snakeninny

LongPressableButtonItem 是什么?私有类?完全查不到资料。该如何处理?
有个LongPressableButtonItem.h:

#import "_AAAccountConfigChangedNotification.h"

@interface LongPressableButtonItem : _AAAccountConfigChangedNotification
{
    id _longPressTarget;
    SEL _longPressAction;
}

- (void)setLongPressTarget:(id)fp8 action:(SEL)fp12;
- (id)createViewForToolbar:(id)fp8;
- (void)longPressGestureRecognized:(id)fp8;

@end

但是无法找到 _AAAccountConfigChangedNotification.h
却有很多其他的头文件:

该楼内容已经编辑进了2楼

我已经对MessageViewController.h的所有方法进行了穷尽hook。

部分代码如下

- (void)megaMallMessageCountChanged:(id)fp8
{
    NSLog(@"----    megaMallMessageCountChanged");
    %orig;
}
- (void)setMall:(id)fp8
{
    NSLog(@"----    setMall");
    %orig;
}
- (void)_animateView:(id)fp8 toCenterPoint:(struct CGPoint)fp12 size:(struct CGSize)fp20 otherAnimations:(id)fp completion:(id)fp28
{
    NSLog(@"----    _animateView");
    %orig;
}

我分别进行compose(就是前面的newmail)、reply、forward三种操作,
Log输出如下:
compose:

Nov 24 21:26:02 0987de-iPad MobileMail[596] <Warning>: ----    messageContentAreaLayer
Nov 24 21:26:03 0987de-iPad MobileMail[596] <Warning>: ----    _composeViewDidShow

reply:

Nov 24 21:28:14 0987de-iPad MobileMail[596] <Warning>: ----    actionSheet
Nov 24 21:28:14 0987de-iPad MobileMail[596] <Warning>: ----    selectedViewingContext
Nov 24 21:28:14 0987de-iPad MobileMail[596] <Warning>: ----    selectedViewingContext
Nov 24 21:28:14 0987de-iPad MobileMail[596] <Warning>: ----    _handleReplyWithContext
Nov 24 21:28:14 0987de-iPad MobileMail[596] <Warning>: ----    messageContentAreaLayer
Nov 24 21:28:14 0987de-iPad MobileMail[596] <Warning>: ----    selectedViewingContext
Nov 24 21:28:14 0987de-iPad MobileMail[596] <Warning>: ----    actionSheet
Nov 24 21:28:14 0987de-iPad MobileMail[596] <Warning>: ----    messageContentAreaLayer
Nov 24 21:28:15 0987de-iPad MobileMail[596] <Warning>: ----    _composeViewDidShow

forward:

Nov 24 21:29:57 0987de-iPad MobileMail[596] <Warning>: ----    actionSheet
Nov 24 21:29:57 0987de-iPad MobileMail[596] <Warning>: ----    selectedViewingContext
Nov 24 21:29:57 0987de-iPad MobileMail[596] <Warning>: ----    selectedViewingContext
Nov 24 21:29:57 0987de-iPad MobileMail[596] <Warning>: ----    _handleReplyWithContext
Nov 24 21:29:57 0987de-iPad MobileMail[596] <Warning>: ----    messageContentAreaLayer
Nov 24 21:29:57 0987de-iPad MobileMail[596] <Warning>: ----    selectedViewingContext
Nov 24 21:29:58 0987de-iPad MobileMail[596] <Warning>: ----    actionSheet
Nov 24 21:29:58 0987de-iPad MobileMail[596] <Warning>: ----    messageContentAreaLayer
Nov 24 21:29:58 0987de-iPad lockdownd[56] <Notice>: 00301000 _select_socket: receive secure message timeout!
Nov 24 21:29:58 0987de-iPad lockdownd[56] <Notice>: 00301000 _receive_message: walk away - non-SSL 1
Nov 24 21:29:58 0987de-iPad MobileMail[596] <Warning>: ----    _composeViewDidShow

已经可以确定是_composeViewDidShow负责调用邮件发送页面(草!这不是明摆的事吗!绕那么大的圈!!!)

楼主最终想达到一个什么效果呢?

你这个问题很典型,我把它作为案例加入到第二版第6章中去了,先公布一下答案,点击“编写邮件”按钮执行的代码是

[UIApplication sharedApplication] composeButtonClicked:[ComposeButtonItem composeButtonItem]]

至于来龙去脉,第二版里会有详细分析过程,到时候就知道了

为何我没有看到那个方法呢,是我找的头文件不对吗?这几天在忙其他事,mail的问题搁置了。回来再继续。
谢谢狗哥,越来越期待第二版了!!!

我希望能分析出mail.app的几个调用方法,实现后台转发等功能。