20、Theos越狱调试Wallet

news/2024/4/24 3:21:06/文章来源:https://blog.csdn.net/SharkToping/article/details/130347544

前面的总结中使用砸壳重签后的App进行调试,本篇在越狱环境下不重签App进行调试,但是还是需要砸壳获取Headers.

一、Cycript

1.1 在越狱环境中使用Cycript

  • 在越狱环境上,安装Cycript插件.需要先安装adv-cmds插件,因为被Cycript插件所依赖、在Cydia中,安装Cycript
    • 在设备中找到WeChat,并找到它的进程
$ ssh root@192.168.124.12
Holothurian6P:~ root# ps -A | grep WeChat
34532 ??         0:00.00 /var/containers/Bundle/Application/0AE7CC54-E2BF-4CD0-A1F6-95EBB12285D0/WeChat.app/WeChat
34589 ttys002    0:00.00 grep WeChat
    • 针对WeChat进程,进入cy环境
Holothurian6P:~ root# cycript -p 34532
cy# 
    • 此时我们并没有污染WeChat,但可以使用Cycript命令进行调试了
# UIApp
#"<UIApplication: 0x139d07820>"
cy#

1.2 导入cy文件

  • 在越狱环境中,使用自定义cy文件

    • 找到之前使用的“获取当前控制器”的cy脚本,在越狱环境中,将脚本拷贝到设备上的Cycript指定目录下,即可使用
  • 从Mac端: 将current_vc.cy脚本,拷贝到 /usr/lib/cycript0.9目录下(FileZilla查看)

scp currentVC.cy root@192.168.124.12:/usr/lib/cycript0.9
current_vc.cy                                  100%  918    59.0KB/s   00:00
  • SSH登录手机查看文件存在位置
$ ssh root@192.168.124.12
Holothurian6P:~ root# cd /usr/lib/cycript0.9
Holothurian6P:/usr/lib/cycript0.9 root# ls
com/  current_vc.cy  org/
Holothurian6P:/usr/lib/cycript0.9 root#
  • 针对WeChat进程,进入cy环境,可以使用进程id或名称
cycript -p WeChat
  • 导入 currentVC脚本
@import current_vc
{}
  • 获取当前包路径
cy# APPPATH
@"/var/containers/Bundle/Application/0AE7CC54-E2BF-4CD0-A1F6-95EBB12285D0/WeChat.app"
  • 使用cy文件,必须拷贝到Cycript指定目录下,这样很可能造成文件冲突.所以Cycript引入了命名空间,可以将cy文件拷贝到不同子目录中,然后按照指定规则导入.
  • 在/usr/lib/cycript0.9目录下,已经默认存在一些子目录
  • 在com目录下,存在以作者名字命名的saurik目录,里面存储了官方的MS.cy脚本
  • 仿照官方的目录结构,在com目录下,创建自定义目录Holothurian
Holothurian6P:~ root# cd /usr/lib/cycript0.9
Holothurian6P:/usr/lib/cycript0.9 root# ls
com/  current_vc.cy  org/
Holothurian6P:/usr/lib/cycript0.9/ root# cd com
Holothurian6P:/usr/lib/cycript0.9/com root# mkdir Holothurian
Holothurian6P:/usr/lib/cycript0.9/com root# cd Holothurian
Holothurian6P:/usr/lib/cycript0.9/Holothurian root# mv .../current_vc.cy ../Holothurian
    • 进入WeChat进程的cy环境,导入current_vc脚本
$ ssh root@192.168.124.12
Holothurian6P:~ root# cycript -p WeChat
cy# @import com.Holothurian.current_vc
{}
cy#
    • 使用这种方式,保证了脚本的唯一性,有效避免文件冲突.并且按不同目录划分,更利于脚本的管理

二、Theos

  • theos是一个越狱开发工具包,使用它可以创建Tweak项目,动态Hook第三方程序,使用MonkeyDev框架,它提供的Logos语法,其实也依赖于theos

2.1 theos安装

sudo git clone --recursive https://github.com/theos/theos.git /opt/theos
    • theos有很多依赖库,子组件,使用 recursive参数,可以循环下载,将依赖库一并安装
    • opt目录,用来安装附加程序包.有时会出现系统权限问题,建议将theos安装自定义目录.或者安装到opt目录,然后在自定义目录中拷贝一份.

2.2 ldid

    • 安装ldid的过程中,可能会一同安装ldid
    • ldid是针对越狱插件的签名工具.如果未安装,需要手动安装
brew install ldid

2.3 theos插件

目的: 使用theos插件,“窃取”AlipayWallet(10.3.66)的登录密码

2.3.1 静态分析

需要取出AlipayWallet的头文件

  • 1、frida-iOS-dump尝试:失败
  • 2、通过手机上的Clutch 尝试
Clutch -i  查看当前安装的所有包
Clutch -d //数字/包名/
    • 如果砸壳成功并且压缩成功、那么将会出现在如下目录下
/private/var/mobile/Documents/Dumped/
    • 如果砸壳中途退出、那么将会出现在缓存中
/private/var/tmp/clutch/
    • 将砸壳后的内容移动到Mac电脑上
scp -r root@192.168.124.12:/private/var/tmp/clutch/649B21FD-53F7-49BE-86F8-8DA5898A7343/ /Users/Chenxi/Desktop/
    • 查看可执行文件破解与否 cryptid表示加密状态、1加密、0解密
otool -l AlipayWallet | grep cry
    • 加密: 砸壳失败
  • 3、dumpdecrypted.dylib砸壳尝试:

$ ssh root@192.168.124.12
Holothurian6P:~ root# ps -e
...
37102 ??         0:00.00 /var/containers/Bundle/Application/9D61BA0D-4C7D-4BEA-99A0-0928B3BE40FA/AlipayWallet.app/Alip
...
Holothurian6P:~ root# cycript -p AlipayWallet
cy# @import com.Holothurian.current_vc
cy# APPPATH
@"/var/containers/Bundle/Application/9D61BA0D-4C7D-4BEA-99A0-0928B3BE40FA/AlipayWallet.app"
cy# [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]
#"file:///var/mobile/Containers/Data/Application/7F4E0FEA-217C-4DD0-8BEB-820BA9C5FCFC/Documents/"
cy# exit(0)
Holothurian6P: cd /var/mobile/Containers/Data/Application/7F4E0FEA-217C-4DD0-8BEB-820BA9C5FCFC/Documents/
Holothurian6P:/var/mobile/Containers/Data/Application/7F4E0FEA-217C-4DD0-8BEB-820BA9C5FCFC/Documents root# cp /private/var/root/dumpdecrypted.dylib /var/mobile/Containers/Data/Application/7F4E0FEA-217C-4DD0-8BEB-820BA9C5FCFC/Documents/
Holothurian6P:/var/mobile/Containers/Data/Application/7F4E0FEA-217C-4DD0-8BEB-820BA9C5FCFC/Documents root# DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/containers/Bundle/Application/9D61BA0D-4C7D-4BEA-99A0-0928B3BE40FA/AlipayWallet.app/AlipayWallet
......
Holothurian6P:/var/mobile/Containers/Data/Application/7F4E0FEA-217C-4DD0-8BEB-820BA9C5FCFC/Documents root# ls | grep Ali
AlipayWallet.fid*
GenieForAlipay.fid*
Holothurian6P:/var/mobile/Containers/Data/Application/7F4E0FEA-217C-4DD0-8BEB-820BA9C5FCFC/Documents root# exit
logout
Connection to 192.168.124.12 closed.
scp -r root@192.168.124.12:/var/mobile/Containers/Data/Application/7F4E0FEA-217C-4DD0-8BEB-820BA9C5FCFC/Documents/AlipayWallet.fid ~/Desktop
    • 最终得到AlipayWallet.fid文件、删掉后缀即为可执行文件.
  • 将AlipayWallet的头文件按照名称排列class-dump到指定目录
class-dump -S -s -H AlipayWallet -o ./Headers

2.3.2 动态分析

  • 在设备中打开ZFB,来到登录界面,并找到它的进程
ssh root@192.168.124.12
Holothurian6P:~ root# ps -A | grep AlipayWallet
37231 ??         0:00.00 /var/containers/Bundle/Application/9D61BA0D-4C7D-4BEA-99A0-0928B3BE40FA/AlipayWallet.app/AlipayWallet
37269 ttys000    0:00.00 grep AlipayWallet
    • 进入AlipayWallet进程的cy环境
Holothurian6P:~ root# cycript -p 37231
    • 导入current_vc脚本 && 获取当前控制器
cy# @import com.Holothurian.current_vc
{}
  • 进入AlipayWallet的密码登录界面
    • 查看当前控制器
cy# HSCurrentVC()
#"<ALULoginVerifyController: 0x10ec9da00>"
  • 打印控制器下所有视图
cy# #0x10ec9da00.view.recursiveDescription().toString()
`<UIView: 0x11df16190; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x281dd1a00>>| <ALULoginContainerView: 0x11df1fad0; frame = (0 0; 414 736); layer = <CALayer: 0x281d298e0>>|    | <ALULoginVerifyPasswordView: 0x11cb31330; frame = (0 422; 414 314); layer = <CALayer: 0x281e836a0>>|    |    | <ALULoginPWDInputTextField: 0x11e57c310; frame = (20 87; 374 55); clipsToBounds = YES; layer = <CALayer: 0x281e83b60>>|    |    |    | <UIButton: 0x11cb277d0; frame = (296 16; 66 23); opaque = NO; layer = <CALayer: 0x281e944a0>>|    |    |    |    | <UIButtonLabel: 0x11cb27af0; frame = (0.333333 2; 65.3333 19.3333); text = '\u5fd8\u8bb0\u5bc6\u7801'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x283bd4f00>>|    |    |    |    |    | <_UILabelContentLayer: 0x281ee8b40> (layer)|    |    |    | <UIView: 0x11cb4e250; frame = (283.5 19.5; 0.5 16); layer = <CALayer: 0x281e94640>>|    |    |    | <UIButton: 0x11cb280c0; frame = (249.5 16.5; 22 22); opaque = NO; layer = <CALayer: 0x281e94700>>|    |    |    |    | <UIImageView: 0x10d5c8710; frame = (0.333333 4.33333; 21 13); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x281ee8920>>|    |    |    | <UIControl: 0x11e57e650; frame = (243.5 6; 34 43); layer = <CALayer: 0x281e8c820>>|    |    |    | <ALUPWDTextField: 0x10e852a00; baseClass = UITextField; frame = (12 9.5; 231.5 36); text = ''; opaque = NO; gestureRecognizers = <NSArray: 0x281422a60>; layer = <CALayer: 0x281e8cb00>>|    |    |    |    | <UITextFieldLabel: 0x11e57e860; frame = (0 8; 232 19.3333); text = '\u8bf7\u8f93\u5165\u767b\u5f55\u5bc6\u7801'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x283bdf700>>|    |    |    |    |    | <_UILabelContentLayer: 0x281ee8ca0> (layer)|    |    |    |    | <_UITextFieldContentView: 0x11cbd5a10; frame = (0 0; 232 36); opaque = NO; userInteractionEnabled = NO; layer = <__UITextTiledLayer: 0x283ea32a0>>|    |    |    |    |    | <UITextSelectionView: 0x11e580a30; frame = (0 0; 0 0); alpha = 0; userInteractionEnabled = NO; layer = <CALayer: 0x281e94280>>|    |    |    |    |    | <__UITileLayer: 0x280940f30> (layer)|    |    | <ALULoginAccountInfoView: 0x11e57c520; frame = (20 24; 374 55); layer = <CALayer: 0x281e8f680>>|    |    |    | <UIImageView: 0x11e5781d0; frame = (80 12; 31 31); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x281e8d240>>|    |    |    | <UILabel: 0x11e57eb50; frame = (123 9.5; 171 36); text = '180 **** **73'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x283bdf6b0>>|    |    | <UIView: 0x11e57c130; frame = (20 158; 374 49); layer = <CALayer: 0x281e83aa0>>|    |    | <AUButton: 0x11cbd5400; baseClass = UIButton; frame = (20 158; 374 49); clipsToBounds = YES; alpha = 0.4; opaque = NO; layer = <CALayer: 0x281e8ac60>>|    |    |    | <UIImageView: 0x10d531070; frame = (0 0; 374 49); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x281ee8340>>|    |    |    | <UIButtonLabel: 0x11e57b9d0; frame = (166.667 12.6667; 41 24); text = '\u767b\u5f55'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x283bded00>>|    |    |    |    | <_UILabelContentLayer: 0x281ee8aa0> (layer)| <ALULoginButtonListView: 0x11df1a3b0; frame = (0 680; 414 44); layer = <CALayer: 0x281b176e0>>|    | <UIView: 0x11df1a7b0; frame = (174 0; 66 44); layer = <CALayer: 0x281b175a0>>|    |    | <UIButton: 0x11e61a810; frame = (0 0; 66 44); opaque = NO; tag = 100; layer = <CALayer: 0x281dd3fa0>>|    |    |    | <UIButtonLabel: 0x11df00520; frame = (0.333333 12.3333; 65.3333 19.3333); text = '\u66f4\u591a\u9009\u9879'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x283b12170>>|    |    |    |    | <_UILabelContentLayer: 0x281b30f40> (layer)`
cy#
  • 首先找到登录按钮
  • 在输出的视图中,搜索“登录”文案,找不到是因为在cy环境中,中文使用了Unicode编码,将“登录”文案,通过Unicode编码为 \u767b\u5f55
  • 在输出的视图中,搜索得到“登录”按钮
   |    |    | <AUButton: 0x11cbd5400; baseClass = UIButton; frame = (20 158; 374 49); clipsToBounds = YES; alpha = 0.4; opaque = NO; layer = <CALayer: 0x281e8ac60>>|    |    |    | <UIImageView: 0x10d531070; frame = (0 0; 374 49); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x281ee8340>>|    |    |    | <UIButtonLabel: 0x11e57b9d0; frame = (166.667 12.6667; 41 24); text = '\u767b\u5f55'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x283bded00>>|    |    |    |    | <_UILabelContentLayer: 0x281ee8aa0> (layer)
  • 找到AUButton的事件响应者和事件名称
    • 找到AUButton的事件响应者
cy# #0x11cbd5400.allTargets
[NSSet setWithArray:@[#"<ALULoginVerifyPasswordViewModel: 0x281e83640>",#"<AUButton: 0x11cbd5400; baseClass = UIButton; frame = (20 158; 374 49); clipsToBounds = YES; alpha = 0.4; opaque = NO; layer = <CALayer: 0x281e8ac60>>"]]]
    • 此处存在两个响应者,一个是AUButton自身,另一个是 ALULoginVerifyPasswordViewModel
    • 确认AUButton的触摸事件 allControlEvents
cy# #0x11cbd5400.allControlEvents
64
    • 根据UIControlEvents枚举值,64为 2的6次方

    • 也就是AUButton触发UIControlEventTouchUpInside,事件响应者为 ALULoginVerifyPasswordViewModel
  • 找到响应者的事件名称
    • 通过响应者和触摸事件,找到事件名称
cy# [#0x11cbd5400 actionsForTarget: #0x281e83640 forControlEvent: 64]
@["onLoginMainButtonClicked:"]
      • 参数1为响应者对象,参数2为触摸事件的枚举值,返回事件名称 onLoginMainButtonClicked
    • 登录的AUButton可触发 ALULoginVerifyPasswordViewModel 对象的 onLoginMainButtonClicked 方法
  • 找到密码文本框
    • 在密码框中输入 haishen
    • 在输出的视图中,搜索 haishen

    • 从视图结构的层级分析来看
    • ALUPWDTextField --> ALULoginPWDInputTextField --> ALULoginVerifyPasswordView --> ALULoginContainerView
    • 和密码框相关的父视图,可以追溯到 ALULoginContainerView, 作为一个Container,应该只是一个容器, 然而其中包含的 ALULoginVerifyPasswordView 视图,与响应者 ALULoginVerifyPasswordViewModel 应该有所关联.
  • 在Header文件夹中搜索 ALULoginContainerView ,得到
@interface ALULoginContainerView : UIView
- (id)hitTest:(struct CGPoint)arg1 withEvent:(id)arg2;
@end
    • 它是做点击手势处理的View、并且仅用于 ALULoginBaseController 中.其中存在着ALULoginContainerView的一个实例对象_loginView

    • 然而当前的控制器为 ALULoginVerifyController, 继承于 ALULoginBaseController .因此关系逐渐清晰起来了
  • 查看 ALULoginVerifyController ,其中存在着 ALULoginVerifyPasswordView的实例对象_verifyPasswordView,

  • 继续寻找响应者链条、搜索 ALULoginVerifyPasswordView视图, 可以看到其中存在的实例为 _pwdTextField 的 ALULoginPWDInputTextField对象

  • 搜索 ALULoginPWDInputTextField 文件,得到 _pwdTextField 实例对象,并且有个ALULoginPWDInputTextFieldDelegate的代理对象 _delegate值得注意.

  • 继续查看ALUPWDTextField 对象的实现, 继承于 UITextField
@interface ALUPWDTextField : UITextField {_Bool _isSecurityField;
}
- (_Bool)canPerformAction:(SEL)arg1 withSender:(id)arg2;
@property(nonatomic) _Bool isSecurityField; // @synthesize isSecurityField=_isSecurityField;
@end
  • 对Headers文件夹搜索ALULoginVerifyPasswordViewModel : 其中内容如下, 可以看到我们的响应事件 onLoginMainButtonClicked就在其中
#import "ALULoginBaseViewModel.h"#import "ALULoginPWDInputTextFieldDelegate-Protocol.h"
@class NSString;
@interface ALULoginVerifyPasswordViewModel : ALULoginBaseViewModel <ALULoginPWDInputTextFieldDelegate>
...
- (void)checkStartPWDLogin;
- (id)currentLoginId;
- (id)currentPassword;
- (void)eyeBtnClicked:(id)arg1;
- (void)forgetBtnClicked:(id)arg1;
- (void)onLoginMainButtonClicked:(id)arg1;
- (void)pwdInputTextFieldDidBeginEdit:(id)arg1;
- (void)pwdInputTextFieldDidChanged:(id)arg1;
- (void)pwdInputTextFieldDidEndEdit:(id)arg1;
- (void)pwdInputTextFieldReturnClicked:(id)arg1;
....
@end

综上: 密码文本框的整体存在关系为

  • ALULoginVerifyController 的 父类存在着个 _loginView(ALULoginContainerView)对象;
  • ALULoginContainerView上添加了_verifyPasswordView (ALULoginVerifyPasswordView) 视图对象
  • ALULoginVerifyPasswordView 视图 存在 _pwdTextField(ALULoginPWDInputTextField)对象
  • ALULoginPWDInputTextField内存在_pwdTextField(ALUPWDTextField)对象
  • ALUPWDTextField继承于UITextField,那么密码内容也就是text(属性)了

那么我们从哪里开刀获取密码呢?

  • 就我看来,当点击了”登录“按钮之后,我们有多种方式获取密码
    • 1、直接从ALULoginVerifyPasswordView视图出发,通过 _pwdTextField 的代理方法依次获取,然而ALULoginPWDInputTextFieldDelegate的代理方法都在ALULoginVerifyPasswordViewModel中实现了
      • _pwdTextField --> _pwdTextField --> _textField --> text
    • 2、直接从ALULoginVerifyPasswordViewModel中的 currentPassword 方法,是不是就是密码?
      • - (id)currentPassword;

2.3.3 搭建theos插件

  • 使用nic.pl,创建组件
$ nic.pl
NIC 2.0 - New Instance Creator
------------------------------[1.] iphone/activator_event[2.] iphone/activator_listener[3.] iphone/application[4.] iphone/application_swift[5.] iphone/control_center_module-11up[6.] iphone/cydget[7.] iphone/flipswitch_switch[8.] iphone/framework[9.] iphone/library[10.] iphone/notification_center_widget[11.] iphone/notification_center_widget-7up[12.] iphone/preference_bundle[13.] iphone/preference_bundle_swift[14.] iphone/theme[15.] iphone/tool[16.] iphone/tool_swift[17.] iphone/tweak[18.] iphone/tweak_with_simple_preferences[19.] iphone/xpc_service[20.] iphone/xpc_service_modern
Choose a Template (required):
    • 输入17,选择 iphone/tweak插件
    • 输入工程名称
Project Name (required): AlipayPwdDemo
    • 输入包名称,类似BundleID,但是此处要求全部小写
Package Name [com.yourcompany.alipaypwddemo]: com.holothurian.alipaypwddemo
    • 输入作者名称,默认计算机名称.如果不修改,直接回车
Author/Maintainer Name [Holothurian]: Holothurian
    • 输入插件将要附件的进程,填写该进程的BundleID.可以在cy环境,通过APPID获取
[iphone/tweak] MobileSubstrate Bundle filter [com.apple.springboard]: com.alipay.iphoneclient
    • 输入附加后杀掉的进程,默认为SpringBoard(桌面进程),杀掉后所有进程都会重启.如果不修改,直接回车
[iphone/tweak] List of applications to terminate upon installation (space-separated, '-' for none) [SpringBoard]: Instantiating iphone/tweak in alipaypwddemo/... Done.
    • 插件创建完成,生成tweak工程

    • Tweak.x: 代码,使用Logos语法
    • control: 配置信息,版本号,作者名称等
    • Makefile: 编译时用到的文件,需要配置
    • AlipayPwdDemo.plist: 附加应用的包名称
  • 修改Tweak.x文件的后缀名
    • .x文件支持OC语法,我们需要支持OC,C/C++语法的 .xm文件,故此将Tweak.x修改为Tweak.xm
  • 修改Makefile
    • 手机安装插件,也是通过SSH连接的,所以在Makefile中,增加USB连接的IP和端口的配置
export THEOS_DEVICE_IP=192.168.124.12 
export THEOS_DEVICE_PORT=22
    • 由于Tweak.x文件的后缀名修改,在Makefile中,同步修改AlipayPwdDemo_FILES
AlipayPwdDemo_FILES = Tweak.xm
  • 将alipaypwddemo文件夹,使用VCCode打开
    • 打开Tweak.m文件,写入以下代码(选择最简便的方式:方法2) .有坑提示~~~
#import <UIKit/UIKit.h>
// 通过ViewModel的响应获取密码
%hook ALULoginVerifyPasswordViewModel- (id)currentLoginId {NSString *loginId = (NSString *)%orig;// 输出当前登录的loginId、因为本身带返回值,所以直接取值NSLog(@"HOOK当前登录的LoginId: %@", loginId);return %orig;
}
- (id)currentPassword{//NSString *pwd = (NSString *)%orig;//输出当前登录用户的密码//NSLog(@"HOOK当前密码----: %@",pwd);return %orig;
}- (void)onLoginMainButtonClicked:(id)arg1 {// 查看当前的登录Id[self currentLoginId];// 直接获取当前密码NSLog(@"HOOK点击后的响应登录密码: %@", (NSString *)[self currentPassword]);
}
%end

2.3.4 安装theos插件

  • 工程中,不允许包含中文,否则编译报错
    • 从终端进入aliwaypwddemo目录下
$ cd ~/Desktop/alipaypwddemo192  ~/Desktop/alipaypwddemo   master $ ls
AlipayPwdDemo.plist Makefile            Tweak.xm            control
    • 清理工程
make clean
==> Cleaning…
    • 编译工程
make
==> Notice: Build may be slow as Theos isn’t using all available CPU cores on this computer. Consider upgrading GNU Make: https://theos.dev/docs/parallel-building
==> Warning: Building for iOS 11.0, but the current toolchain can’t produce arm64e binaries for iOS earlier than 14.0. More information: https://theos.dev/docs/arm64e-deployment
> Making all for tweak AlipayPwdDemo…
==> Preprocessing Tweak.xm…
==> Compiling Tweak.xm (arm64)…
Tweak.xm:22:3: error: receiver type 'ALULoginVerifyPasswordViewModel' for instance message is a forward declaration[self currentLoginId];^~~~
Tweak.xm:25:8: note: forward declaration of class here
@class ALULoginVerifyPasswordViewModel;^
Tweak.xm:24:64: error: receiver type 'ALULoginVerifyPasswordViewModel' for instance message is a forward declarationNSLog(@"HOOK点击后的响应登录密码: %@", (NSString *)[self currentPassword]);^~~~
Tweak.xm:25:8: note: forward declaration of class here
@class ALULoginVerifyPasswordViewModel;^
2 errors generated.
make[3]: *** [/Users/chenxi/Desktop/alipaypwddemo/.theos/obj/debug/arm64/Tweak.xm.b0ccc732.o] Error 1
rm /Users/chenxi/Desktop/alipaypwddemo/.theos/obj/debug/arm64/Tweak.xm.mm
make[2]: *** [/Users/chenxi/Desktop/alipaypwddemo/.theos/obj/debug/arm64/AlipayPwdDemo.dylib] Error 2
make[1]: *** [internal-library-all_] Error 2
make: *** [AlipayPwdDemo.all.tweak.variables] Error 2
    • 发现一个警告问题, 支持的iOS系统版本7.0、去Makefile修改一下最低支持11.0
TARGET := iphone:clang:latest:11.0
    • 报错问题是因为使用了self、需要前置声明,ALULoginVerifyPasswordViewModel继承于ALULoginBaseViewModel翻看ALULoginBaseViewModel的头文件,发现它的内容

    • 那么ViewModel与Controller的关系在此体现; 在Tweak文件中 补上类的声明及方法
@interface ALULoginBaseViewModel :NSObject
- (NSString *)currentLoginId;
@end@interface ALULoginVerifyPasswordViewModel :ALULoginBaseViewModel
- (NSString *)currentPassword;
@end
    • 再次执行编译命令
make clean
==> Cleaning…
make
==> Notice: Build may be slow as Theos isn’t using all available CPU cores on this computer. Consider upgrading GNU Make: https://theos.dev/docs/parallel-building
==> Warning: Building for iOS 11.0, but the current toolchain can’t produce arm64e binaries for iOS earlier than 14.0. More information: https://theos.dev/docs/arm64e-deployment
> Making all for tweak AlipayPwdDemo…
==> Preprocessing Tweak.xm…
==> Compiling Tweak.xm (arm64)…
==> Linking tweak AlipayPwdDemo (arm64)…
ld: warning: directory not found for option '-F/opt/theos/vendor/lib/iphone/rootful'
==> Generating debug symbols for AlipayPwdDemo…
==> Preprocessing Tweak.xm…
==> Compiling Tweak.xm (arm64e)…
==> Linking tweak AlipayPwdDemo (arm64e)…
ld: warning: directory not found for option '-F/opt/theos/vendor/lib/iphone/rootful'
==> Generating debug symbols for AlipayPwdDemo…
==> Merging tweak AlipayPwdDemo…
==> Signing AlipayPwdDemo…
    • 编译完成后可以看到动态库的生成

  • 打包插件
 make package
==> Notice: Build may be slow as Theos isn’t using all available CPU cores on this computer. Consider upgrading GNU Make: https://theos.dev/docs/parallel-building
==> Warning: Building for iOS 11.0, but the current toolchain can’t produce arm64e binaries for iOS earlier than 14.0. More information: https://theos.dev/docs/arm64e-deployment
> Making all for tweak AlipayPwdDemo…
make[2]: Nothing to be done for `internal-library-compile'.
> Making stage for tweak AlipayPwdDemo…
dm.pl: building package `com.holothurian.alipaypwddemo:iphoneos-arm' in `./packages/com.holothurian.alipaypwddemo_0.0.1-1+debug_iphoneos-arm.deb'
    • 打包完成后的产物

  • 安装
 make install
==> Error: /Applications/Xcode.app/Contents/Developer/usr/bin/make install requires that you set THEOS_DEVICE_IP in your environment.
==> Notice: It is also recommended that you have public-key authentication set up for root over SSH, or you will be entering your password a lot.
make: *** [internal-install] Error 1
    • 在~/.bash_profile或~/.zshrc文件中添加 THEOS_DEVICE_IP和THEOS_DEVICE_PORT
export THEOS_DEVICE_IP=192.168.124.12
export THEOS_DEVICE_PORT=22
    • 再次执行安装
make install
==> Installing…
Selecting previously unselected package com.holothurian.alipaypwddemo.
(Reading database ... 2229 files and directories currently installed.)
Preparing to unpack /tmp/_theos_install.deb ...
Unpacking com.holothurian.alipaypwddemo (0.0.1-1+debug) ...
Setting up com.holothurian.alipaypwddemo (0.0.1-1+debug) ...
==> Unloading SpringBoard…
    • 安装成功后,设备的SpringBoard(桌面进程)重启
  • 在Cydia中,可以看到我们的自定义插件

  • Mac电脑上,打开Devices and Simulators,选择 Open Console,打开控制台

  • 手机上,打开AlipayWallet, 进入密码登录页,输入密码后点击登录按钮

    • HOOK成功,可以看到原来的账号和密码
    • 使用theos插件,在不污染应用的情况下,窃取到AlipayWallet的登录账号和密码

2.4 theos与Xcode

  • 如果电脑中有多个Xcode版本,需要指定Xcode路径
  • 获取Xcode路径
xcode-select -p /Applications/Xcode.app/Contents/Developer
  • 指定Xcode路径
xcode-select --switch /Applications/Xcode.app/Contents/Developer

三、总结

  • Cycript
    • 越狱手机安装Cycript插件,依赖于adv-cmds插件
    • 依附进程,使用cycript -p 进程id/名称
  • 导入cy文件
    • 将自定义cy文件,放入 /usr/lib/cycript0.9目录中
    • 为了不重名,让入com目录中,创建自己组织的文件夹
    • 加载时,使用 @import com.组织名称.文件名称
  • theos
    • 是一个越狱开发工具包
    • 可以创建Tweak项目,动态Hook第三方程序
  • 搭建theos插件
    • 使用 nic.pl --> 创建iphone/tweak插件, 17
    • 输入的包名称,类似BundleID, 要求全部小写
    • 需要支持OC、C/C++语法,修改Tweak.x文件后缀,改为.xm
    • 文件后缀名的修改,同步修改Makefile文件中的配置
    • Makefile文件中,增加USB连接的IP和端口,Mac环境变量中也需要
  • 安装theos插件
    • 工程目录中,不允许包含中文,否则编译报错
    • 清理工程: make clean
    • 编译工程: make
    • 打包: make package
    • 安装: make install
  • theos和Xcode
    • 多个版本的Xcode,需要指定Xcode路径
    • 获取Xcode路径,使用 xcode-select-p
    • 指定Xcode路径,使用 xcode-select --switch /Applications/Xcode.app/Contents/Developer

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_102776.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

苦熬10年,国产操作系统“归零”,新操作系统上新,跟Excel很像

苦熬10余年&#xff0c;国产操作系统自主研发 说到国内自主研发的操作系统&#xff0c;经验最丰富的品牌&#xff0c;当然是麒麟OS. 从诞生到发展&#xff0c;历经10多年的努力&#xff0c;麒麟os逐渐成为了国内自主研发操作系统领域中的一颗耀眼的明珠。麒麟OS不仅推出了许多…

typescript全局安装卸载以及npm相关问题

全局安装 npm install -g typescript 全局安装之后&#xff0c;如果想要卸载要使用 npm uninstall -g typescript 全局安装之后可以在终端使用 tsc xxx 编译ts文件 本地安装&#xff0c;也就是在项目目录下安装 npm install typescript 本地卸载 npm uninstall type…

DHCP 给内网客户端分配ip地址

~ 为 InsideCli 客户端网络分配地址&#xff0c;地址池范围&#xff1a; 192.168.0.110-192.168.0.190/24&#xff1b; ~ 域名解析服务器&#xff1a;按照实际需求配置 DNS 服务器地址选项&#xff1b; ~ 网关&#xff1a;按照实际需求配置网关地址选项&#xff1b; ~ 为…

基于Html+Css的图片展示25

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

自动化工具 基于 Antd+DRF 开发了一款适配 JMeter 的接口自动化测试报告

JMeter Report 基于 AntdDRF 开发的一款 JMeter 测试报告服务&#xff0c;用于在 JMeter 接口测试中使用。 &#x1f334; 背景 JMeter 是测试工作中常用的一款工具&#xff0c;除了压测还可以用来做接口自动化的测试。 从事测试多年&#xff0c;接口自动化也做过很多的尝试…

基于PWM技术的三相光伏逆变器研究(Simulink)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

一文让你熟练使用 JSONObject 和 JSONArray

依赖 导入阿里的 fastjson 依赖。 <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.78</version></dependency>类型转换 String 与 JSON 相互转换 通过 JSONObject.parseObject…

面试2个月没有一个offer?阿里技术官的800页知识宝典打破你的僵局~

在经历了一波裁员浪潮后&#xff0c;大环境似乎有所好转&#xff0c;但对于面试者来说&#xff0c;面试愈发困难&#xff0c;现在面试官动不动就是底层原理&#xff0c;动不动就是源码分析&#xff0c;面试一定会抓你擅长的地方&#xff0c;一直问&#xff0c;问到你不会为止。…

集成学习(Ensembles)

Ensembles 前言EnsemblesAveraging,StackingWhy does averaging work?如何理解&#xff1a;In practice errors won’t be completely independent due to noise in the labels Random ForestsDoes averaging work if you use trees with the same parameters?Bootstrap Samp…

【手把手做ROS2机器人系统开发一】开发环境搭建

【手把手做ROS2机器人系统开发一】开发环境搭建 目录 【手把手做ROS2机器人系统开发一】开发环境搭建 一、专栏介绍&#xff1a; 二、开发环境搭建&#xff1a; 1.Ubuntu系统安装 2.ROS2系统环境安装 3.测试系统运行 一、专栏介绍&#xff1a; 大家好&#xff0c;今天给大家…

自然语言处理基本任务综述

文章目录 1.多语言分词2.词性标注3.命名实体识别4.中心词提取5.依存句法分析6.文本纠错7.文本摘要8.文本相似度9.情感分析10.文本分类11.词向量 1.多语言分词 ​ 在自然语言处理中&#xff0c;分词&#xff08;Tokenization&#xff09;是指将自然语言文本中的连续字符序列划分…

VRP开源的算例资源

VRP开源的算例资源 开源的算例资源 开源的MIP算例网址 1. MISOCP网址 Benchmark instances&#xff1a;多种问题的算例数据 TSP算例网址 VRP标杆算例网址 1. Networking and Emerging Optimization发布的VRP算例 2. PRP算例 3. 一个学者的主页上的算例 4. Chair in L…

MySQL-----复合查询

文章目录 前言一、基本查询回顾二、 多表查询解决多表查询的思路 三、自连接四、子查询1. 单行子查询2. 多行子查询3. 多列子查询4. 在from子句中使用子查询5. 合并查询5.1 union5.2 unoin all 总结 前言 前面的学习中,对于mysql表的查询都是对一张表进行查询,在实际开发中这远…

医药之家:19家医药企业获机构调研,8家公司接待超100家

据医药之家了解&#xff0c;4月17日至21日&#xff0c;两市约113家公司接受了机构调研&#xff0c;其中有19家为医药生物公司。从这19家医药生物公司的调研榜单来看&#xff0c;8家公司近5日接待机构家数超100家&#xff0c;分别是长春高新、国际医学、美好医疗、迪瑞医疗、祥生…

【中标通知】塔望咨询中标新疆农发集团 品牌规划建设项目

【新疆农发集团供应链有限公司-品牌建设项目】于2022年5月正式启动。 本次项目2022年4月6日招标结果正式公示。【塔望咨询】凭借3W消费战略方法体系和专注食品行业丰富的品牌项目经验&#xff0c;中标新疆农发集团供应链有限公司兵团红品牌规划建设项目。 中标结果公告 新疆农…

天梯赛 L3-025 那就别担心了

原题链接&#xff1a; PTA | 程序设计类实验辅助教学平台 题目描述&#xff1a; 下图转自“英式没品笑话百科”的新浪微博 —— 所以无论有没有遇到难题&#xff0c;其实都不用担心。 博主将这种逻辑推演称为“逻辑自洽”&#xff0c;即从某个命题出发的所有推理路径都会将结…

用java 实现二叉树创建

二叉树是数据结构中的一个重要的概念&#xff0c;二叉树的概念最早由 Linus Torvalds在1958年提出。他给出了一个树形数据结构&#xff0c;可以用来存储二叉树。每个节点的左子树和右子树都是空&#xff0c;中间层是子树。在一个给定的空间中&#xff0c;每一个节点都有两个左右…

相机雷达联合标定cam_lidar_calibration

文章目录 运行环境&#xff1a;1.1 ROS环境配置1&#xff09;工作空间创建和编译2&#xff09;官方数据集测试环境 2.1 在线标定1&#xff09;数据类型2&#xff09;标定板制作3&#xff09;配置文件4&#xff09;开始标定5&#xff09;完整实现步骤 3.1 python版本选择3.2 rvi…

4年的测试工程师,你遇到过自身瓶颈期吗?又是怎样度过的?

从毕业到现在已经快4年啦&#xff0c;一直软件测试行业混迹。我不是牛人&#xff0c;但是自我感觉还算是个合格的测试工程师&#xff0c;有必要写下自己将近4年来的经历&#xff0c;给自我以提示&#xff0c;给刚入行的朋友提供点参考。 貌似这一点适应的行业最广&#xff0c;…

Java——二叉搜索树的后序遍历序列

题目链接 牛客在线oj题——二叉搜索树的后序遍历序列 题目描述 输入一个整数数组&#xff0c;判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回 true ,否则返回 false 。假设输入的数组的任意两个数字都互不相同。 数据范围&#xff1a; 节点数量 0≤n≤1000 …