最近在学习ios逆向工程方面的知识,看了一些资料,自己也找个项目来实践下。
1、以支付宝v8.0为目标(谁叫人家是这方面的大牛^_^)。
2、工具:越狱手机一台,Cycript,class-dump-z等基本hook工具。
首先,获取到手势解锁页面,本来想按照前辈的教程,但是应该是经过改版后修改了代码逻辑,获取不到手势界面了
jian-de-iPhone:~ root# cycript -p Portal
cy# var app = UIApp.delegate
@"<DFClientDelegate: 0x28a4150>"
cy# app.keyWindow
cy# app.window
null
cy#
如上所示,获取不到keyWindow,也就获取不到window下的rootViewController。
在这种情况下看下 DFClientDelegate 的头文件:
@class UIWindow, DFBootLoader, DFContext;
@interface DFClientDelegate : XXUnknownSuperclass <UIApplicationDelegate, DFSplashScreenDelegate> {
@private
BOOL _isWalletBooted;
DFContext* _context;
UIWindow* _window;
int _spProcessPhase;
DFBootLoader* _bootLoader;
UIWindow* _splashScreenWindow;
}
@property(retain, nonatomic) DFBootLoader* bootLoader;
@property(retain, nonatomic) DFContext* context;
@property(assign, nonatomic) BOOL isWalletBooted;
@property(assign, nonatomic) int spProcessPhase;
@property(retain, nonatomic) UIWindow* splashScreenWindow;
@property(retain, nonatomic) UIWindow* window;
+(id)sharedDelegate;
-(void).cxx_destruct;
-(void)application:(id)application didFailToRegisterForRemoteNotificationsWithError:(id)error;
-(BOOL)application:(id)application didFinishLaunchingWithOptions:(id)options;
-(void)application:(id)application didReceiveLocalNotification:(id)notification;
-(void)application:(id)application didReceiveRemoteNotification:(id)notification;
-(void)application:(id)application didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken;
-(BOOL)application:(id)application handleOpenURL:(id)url;
-(BOOL)application:(id)application openURL:(id)url sourceApplication:(id)application3 annotation:(id)annotation;
-(void)applicationDidBecomeActive:(id)application;
-(void)applicationDidEnterBackground:(id)application;
-(void)applicationWillEnterForeground:(id)application;
-(void)applicationWillResignActive:(id)application;
-(void)applicationWillTerminate:(id)application;
-(void)bootUpWalletWithBootLoader:(id)bootLoader;
-(BOOL)handleOpenURL:(id)url;
-(BOOL)handleSafePayScheme:(id)scheme;
-(BOOL)isSafePayScheme:(id)scheme;
-(void)onSafePayFinished;
-(void)splashScreenDidDismiss;
-(BOOL)startBootLoader;
@end
在这里我扫了一下代码,最引起我兴趣的是 DFContext
在看下DFContext的头文件,看下是什么东西
@class UIWindow, DFMicroApplicationManager, DFServiceManager, DFNavigationBarDelegate, UINavigationController;
@interface DFContext : DTContext {
@private
UIWindow* _window;
UINavigationController* _navigationController;
DFMicroApplicationManager* _applicationManager;
DFServiceManager* _serviceManager;
DFNavigationBarDelegate* _navigationBarDelegate;
}
@property(retain, nonatomic) DFMicroApplicationManager* applicationManager;
@property(retain, nonatomic) DFNavigationBarDelegate* navigationBarDelegate;
@property(retain, nonatomic) UINavigationController* navigationController;
@property(retain, nonatomic) DFServiceManager* serviceManager;
@property(retain, nonatomic) UIWindow* window;
+(id)sharedContext;
-(void).cxx_destruct;
-(id)currentApplication;
-(id)findApplicationByName:(id)name;
-(id)findServiceByName:(id)name;
-(BOOL)registerService:(id)service forName:(id)name;
-(BOOL)startApplication:(id)application params:(id)params animated:(BOOL)animated;
-(BOOL)startApplication:(id)application params:(id)params launchMode:(int)mode;
-(void)unregisterServiceForName:(id)name;
@end
发现这里也有个window,再结合下前面的判断,在appdelegate下的keywindow和window都是空的,那界面是不是在这个类呈现的。
cy# var context = app.context
@"<DFContext: 0x28c0ec0>"
cy# context.window
@"<UIWindow: 0x28d36b0; frame = (0 0; 320 480); gestureRecognizers = <NSArray: 0x28d3990>; layer = <UIWindowLayer: 0x28d3790>>"
cy# context.window.rootViewController
@"<DFNavigationController: 0x28d3e30>"
cy#
发现界面是在这个类里实现的,但是 add 的是 DFNavigationController 类,这不是我要的。再看下头文件,-(id)currentApplication 引起了我的兴趣,看下是什么
cy# [context currentApplication]
@"DFMicroApplication: 20000001"
cy#
是个 DFMicroApplication 类,看看头文件
#import "DTMicroApplication.h"
@class NSMutableArray, DTMicroApplicationDescriptor;
@protocol DTMicroApplicationDelegate;
@interface DFMicroApplication : DTMicroApplication {
@private
DTMicroApplicationDescriptor* _descriptor;
id<DTMicroApplicationDelegate> _delegate;
NSMutableArray* _viewControllers;
}
@property(retain, nonatomic) NSMutableArray* viewControllers;
+(id)currentApplication;
-(id)init;
-(void).cxx_destruct;
-(void)dealloc;
-(id)delegate;
-(id)description;
-(id)descriptor;
-(void)exitAnimated:(BOOL)animated;
-(id)rootController;
-(void)setDelegate:(id)delegate;
-(void)setDescriptor:(id)descriptor;
@end
在这里,最有价值的 - (id)rootController 了,看下是什么东西,
cy# var cur = [context currentApplication]
@"DFMicroApplication: 20000001"
cy# [cur rootController]
@"<ALPLauncherController: 0x1ee6780>"
cy#
又出了一个新的类,继续看头文件
#import "DTLauncher.h"
#import "APCoverViewDelegate.h"
#import <XXUnknownSuperclass.h> // Unknown library
@class APCoverView, NSMutableArray, UIImageView, NSArray, ALPLauncherControllerKVOHandler, LauncherWidgetFactory;
@protocol DTAutoTestDelegate;
@interface ALPLauncherController : XXUnknownSuperclass <DTLauncher, APCoverViewDelegate> {
@private
BOOL isActive;
APCoverView* _waitingView;
NSArray* _widgets;
LauncherWidgetFactory* _widgetFactory;
NSMutableArray* _badgesList;
ALPLauncherControllerKVOHandler* _kvoHandler;
UIImageView* _leftImgView;
UIImageView* _rightImgView;
id<DTAutoTestDelegate> _autoTestDelegate;
}
@property(retain, nonatomic) id<DTAutoTestDelegate> autoTestDelegate;
@property(retain, nonatomic) NSMutableArray* badgesList;
@property(retain, nonatomic) ALPLauncherControllerKVOHandler* kvoHandler;
@property(retain, nonatomic) UIImageView* leftImgView;
@property(retain, nonatomic) UIImageView* rightImgView;
@property(retain, nonatomic) LauncherWidgetFactory* widgetFactory;
@property(retain, nonatomic) NSArray* widgets;
-(id)init;
-(id)initWithNibName:(id)nibName bundle:(id)bundle;
-(void).cxx_destruct;
-(id)_getSSAuthService;
-(id)_getUserInfo;
-(BOOL)_isLogin;
-(BOOL)addSkipBackupAttributeToDocumentDirectory;
-(void)appDidBecomeActive;
-(void)appWillResignActive;
-(void)backToHome;
-(void)dealloc;
-(void)doGesture;
-(id)findTabBarButtonByTitle:(id)title;
-(void)loginDidFinsh:(id)login;
-(id)selectedWidget;
-(int)selectedWindgetIndex;
-(void)setSelectedWidget:(id)widget;
-(void)setSelectedWidgetByIndex:(int)index;
-(void)setSmallBadgeHide:(BOOL)hide atWidgetIndex:(int)widgetIndex;
-(void)tabBarController:(id)controller didSelectViewController:(id)controller2;
-(void)tryToShowCoverView;
-(void)updateImageForTabItemAtIndex:(int)index selected:(BOOL)selected;
-(void)updateSmallBadge:(id)badge;
-(void)userExitLogin:(id)login;
-(void)viewDidAppear:(BOOL)view;
-(void)viewDidDisappear:(BOOL)view;
-(void)viewDidLoad;
-(void)viewWillAppear:(BOOL)view;
-(void)viewWillDisappear:(BOOL)view;
@end
看头文件,各位,兴奋的东西来了,看看这个是什么-(id)_getUserInfo; -(void)doGesture; 这个类是支付宝一个很重要的管理类。
-(id)_getUserInfo看字面就知道能获取到用户的信息,但是先放着。先看 -(void)doGesture,看字面应该是现实手势界面的调用方法。来试一下
首先在app 手势密码登录,再调用下这个方面
cy# var root = [cur rootController]
@"<ALPLauncherController: 0x1ee6780>"
cy# [root doGesture]
cy#
哈哈,手势界面真的出来了,这个类绝对是支付宝一个很重要的管理类。在来看下userInfo
cy# [root _getUserInfo]
@"<SAUserInfo: 0x1ec5620>"
cy#
一个用户信息类,期待啊。。
#import "NSCoding.h"
#import <XXUnknownSuperclass.h> // Unknown library
@class NSDictionary, NSString;
@interface SAUserInfo : XXUnknownSuperclass <NSCoding> {
@private
BOOL _autoLoginEnabled;
BOOL _isLoginState;
BOOL _isSkipGesture;
BOOL _isCertified;
BOOL _mobileBinded;
BOOL _setSecurityQA;
BOOL _openedUKey;
BOOL _openedDigitalCert;
BOOL _openedDynamicPwd;
BOOL _openedMobileOtp;
BOOL _isBindCard;
NSString* _loginId;
NSString* _taobaoLoginId;
NSString* _userId;
NSString* _iconUrl;
NSString* _loginServerTime;
NSString* _taobaoSid;
NSString* _barcodePayToken;
NSString* _extern_token;
NSString* _loginToken;
NSString* _sessionId;
NSString* _currentProductVersion;
NSString* _appId;
NSString* _existNewVersion;
NSString* _updateMemo;
NSString* _downloadURL;
NSString* _loginCheckCodeUrl;
NSString* _loginCheckCodeImg;
NSString* _tbCheckCodeId;
NSString* _tbCheckCodeUrl;
NSString* _loginContext;
NSString* _password;
unsigned _loginType;
NSString* _swPwdSwitch;
NSString* _gesturePassword;
int _gestureTryCount;
NSString* _userName;
NSString* _mobileNo;
NSString* _lastSecurityScore;
unsigned _accountType;
NSDictionary* _extResAttrs;
}
@property(assign, nonatomic) unsigned accountType;
@property(copy, nonatomic) NSString* appId;
@property(assign, nonatomic) BOOL autoLoginEnabled;
@property(copy, nonatomic) NSString* barcodePayToken;
@property(copy, nonatomic) NSString* currentProductVersion;
@property(copy, nonatomic) NSString* downloadURL;
@property(copy, nonatomic) NSString* existNewVersion;
@property(retain, nonatomic) NSDictionary* extResAttrs;
@property(copy, nonatomic) NSString* extern_token;
@property(copy, nonatomic) NSString* gesturePassword;
@property(assign, nonatomic) int gestureTryCount;
@property(copy, nonatomic) NSString* iconUrl;
@property(assign, nonatomic) BOOL isBindCard;
@property(assign, nonatomic) BOOL isCertified;
@property(assign, nonatomic) BOOL isLoginState;
@property(assign, nonatomic) BOOL isSkipGesture;
@property(copy, nonatomic) NSString* lastSecurityScore;
@property(copy, nonatomic) NSString* loginCheckCodeImg;
@property(copy, nonatomic) NSString* loginCheckCodeUrl;
@property(copy, nonatomic) NSString* loginContext;
@property(copy, nonatomic) NSString* loginId;
@property(copy, nonatomic) NSString* loginServerTime;
@property(copy, nonatomic) NSString* loginToken;
@property(assign, nonatomic) unsigned loginType;
@property(assign, nonatomic) BOOL mobileBinded;
@property(copy, nonatomic) NSString* mobileNo;
@property(assign, nonatomic) BOOL openedDigitalCert;
@property(assign, nonatomic) BOOL openedDynamicPwd;
@property(assign, nonatomic) BOOL openedMobileOtp;
@property(assign, nonatomic) BOOL openedUKey;
@property(copy, nonatomic) NSString* password;
@property(retain, nonatomic) NSString* sessionId;
@property(assign, nonatomic) BOOL setSecurityQA;
@property(copy, nonatomic) NSString* swPwdSwitch;
@property(copy, nonatomic) NSString* taobaoLoginId;
@property(copy, nonatomic) NSString* taobaoSid;
@property(copy, nonatomic) NSString* tbCheckCodeId;
@property(copy, nonatomic) NSString* tbCheckCodeUrl;
@property(copy, nonatomic) NSString* updateMemo;
@property(copy, nonatomic) NSString* userId;
@property(copy, nonatomic) NSString* userName;
-(id)init;
-(id)initWithCoder:(id)coder;
-(void).cxx_destruct;
-(id)decodeObjectAndDecryptWithCoder:(id)coder key:(id)key;
-(void)encodeWithCoder:(id)coder;
@end
看看属性列表,各位兴奋起来了没有啊,核心信息展示给我们了
获取手势密码试试
cy# [user valueForKey:@"gesturePassword"]
@"1256987"
cy#
哈哈,手势密码是 1256987 。至于其他信息,就看你自己的兴趣了。
PS:以上紧供学习
学习资料: 信息安全技术丛书·iOS应用逆向工程:分析与实战
念茜的博客 http://blog.csdn.net/column/details/hackingios.html
HackJBreaker的博客 http://blog.csdn.net/o_surface_o/article/category/1470847