20、Theos越狱调试Wallet

news2024/11/16 11:31:37

前面的总结中使用砸壳重签后的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/alipaypwddemo
 192  ~/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 declaration
        NSLog(@"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.coloradmin.cn/o/456770.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

观察者设计模式(Observer Design Pattern)[论点:概念、组成角色、相关图示、示例代码、框架中的运用、适用场景]

文章目录 概念组成角色相关图示示例代码框架中的运用适用场景 概念 观察者设计模式&#xff08;Observer Design Pattern&#xff09;是一种行为型设计模式&#xff0c;它定义了一种对象间的一对多的依赖关系&#xff0c;让多个观察者对象同时监听某一个主题对象&#xff0c;当…

LLaMA模型文件 (搬运工)

LLaMA需要进行申请才能获得官方模型权重。 但是申请的审批时间一般都很长。 这里提供现有的huggingface上&#xff0c;第三方上传的一些LLaMA模型文件&#xff1a; LLaMA-7BLLaMA-13BLLaMA-7B-hfLLaMA-13B-hf 这里要注意&#xff0c;原始的LLaMA权重文件&#xff0c;是不能…

【Java面试八股文】SSM,SpringBoot篇

引言&#xff1a; 本文对多个平台的面试题进行了汇总、分类、概括、整理&#xff0c;对重点进行了标出&#xff0c;更便于阅读和记忆。 【黑马Java笔记踩坑汇总】JavaSEJavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成在线牛客面试题 目录 Spring 简单介绍Spri…

ubuntu 20.04 安装obs 录屏软件

obs是一个非常好用的录屏软件&#xff0c;我们在windows安装和使用是非常的简单&#xff0c;但是在ubuntu安装还是比较麻烦的&#xff0c;需要使用命令行&#xff0c;还需要很多的依赖。 修改源 deb http://archive.ubuntu.com/ubuntu/ focal main restricted universe multi…

大白话告诉你!前端是怎么回事儿?

假期回家&#xff0c;学会计的表弟化身十万个为什么的问我&#xff01; 你们前端到底是干什么的&#xff1f;为什么我的同学好多转行去做这个的&#xff1f;你们前端程序员真的这么赚钱么&#xff1f;你也别跟我说什么敲代码的&#xff0c;你告诉我&#xff0c;你敲得这是什么代…

Linux网络——部署YUM仓库

Linux网络——部署YUM仓库 一、YUM仓库服务1.准备安装源&#xff1a;①.软件仓库的提供方式②.RPM软件包的来源③.构建CentOS7软件仓库④.在软件仓库中加入非官方RPM包组⑤.访问yum仓库 2.yum下载软件包的方式①..开启缓存下载②.通过yum命令的选项下载③.通过yumdownloader命令…

容器化实战--vmware安装centos7-安装docker-idea部署springBoot项目到docker

前言 走过的坑终将化为蒲公英&#xff0c;风一吹就消散了&#xff0c;然后继续掉坑… 整体背景 win10 idea2019.3 vmware15 pro CentOS-7-x86_64-DVD-2009.iso docker 23.0.4 redis mysql8 springBoot项目 1.安装虚拟软件vmware15 pro 安装vmware15 2.安装宿主机centos7 …

为什么你永远不应该在CSS中使用px来设置字体大小

代码部署后可能存在的BUG没法实时知道&#xff0c;事后为了解决这些BUG&#xff0c;花了大量的时间进行log 调试&#xff0c;这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。 在Josh Collinsworth的博客文章“永远不要用px作为字体大小”中&#xff0c;作者讨论了为什么不…

HashMap 的特点及其优缺点以及底层实现

Hash&#xff1a;散列 Map&#xff1a;映射 顾名思义&#xff0c;是以 key-value 的形式存储数据 public class HashMap<K,V> {transient Node<K,V>[] table;// 初始容量 16static final int DEFAULT_INITIAL_CAPACITY 1 << 4; }通过源码可知&#xff0c;…

Web安全 iwebsec 靶场搭建.

Web安全 iwebsec靶场搭建 iwebsec 本质上是一个漏洞集成容器&#xff0c;里面集成了大量的漏洞环境.&#xff08;如&#xff1a;集合了SQL注入、文件包含、命令执行、XXE、反序列化、SSRF、XSS、文件上传等常见的web漏洞环境&#xff09; 目录&#xff1a; 靶场安装步骤&#…

免费gpt-4-国内使用gpt-4

如何用上gpt-4 GPT-4尚未正式发布和公开&#xff0c;因此我们无法提供对GPT-4的具体使用方法。但是&#xff0c;可以从GPT-4的前一代——GPT-3的使用经验和GPT-4的预期功能来看&#xff0c;建议如下&#xff1a; 了解GPT-4的语言处理能力和适用场景&#xff1a;GPT-4预计将进一…

影视动画制作中的后期渲染是什么意思?

影视动画制作是一项非常复杂的任务&#xff0c;需要涵盖从剧本创作到角色设计、场景布置、动画制作、后期渲染等多个环节。其中&#xff0c;后期渲染是制作过程中的最后一步&#xff0c;也是非常重要的一步&#xff0c;它可以使得动画画面更加真实、细腻&#xff0c;达到更好的…

CPU Cache:访问存储速度是如何大幅提升的?

我们了解到不同的物理器件&#xff0c;它们的访问速度是不一样的&#xff1a;速度快的往往代价高、容量小&#xff1b;代价低且容量大的&#xff0c;速度通常比较慢。为了充分发挥各种器件的优点&#xff0c;计算机存储数据的物理器件不会只选择一种&#xff0c;而是以 CPU 为核…

浅析“04.23王者荣耀KPL比赛因出现硬件异常导致比赛延期”这一事件

背景 不知道朋友们有没有看昨天晚上八点多的王者荣耀KPL比赛&#xff08;成都AG超玩会VS广州TTG&#xff09;这一场&#xff0c;当时比赛进行到快15分钟的时候出现了红方请求暂停的情况&#xff0c;后来比赛直播界面就一直提示如下&#xff1a; 本以为这个问题应该不算太严重…

Java——栈的压入,弹出序列

题目链接 牛客网在线oj题——栈的压入,弹出序列 题目描述 输入两个整数序列&#xff0c;第一个序列表示栈的压入顺序&#xff0c;请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序&#xff0c;序列4,5,3,2,1是…

手把手教你PXE高效网络装机、Kickstart无人值守安装(详细版)

目录 一、部署PXE远程安装服务1.1PXE定义1.2PXE服务优点1.3搭建网络体系前提条件1.4 搭建PXE远程安装服务器 二. 实验2.1 服务器操作2.2 安装启动TFTP服务并修改TFTP服务的配置文件2.3 安装并启用DHCP服务2.4 准备linux内核&#xff0c;初始化镜像文件2.5 准备PXE引导程序2.6 安…

编程中最难的就是命名?这几招教你快速上手

作者&#xff1a;陈立(勤仁) 你可不能像给狗狗取名字那样给类、方法、变量命名。仅仅因为它很可爱或者听上去不错。 在写代码的时候&#xff0c;你要经常想着&#xff0c;那个最终维护你代码的人可能将是一个有暴力倾向的疯子&#xff0c;并且他还知道你住在哪里。 01 为什么…

GitHub star最多的 dnmp环境 安装

对于安装GitHub上start最多的dnmp环境的步骤及感悟 https://github.com/yeszao/dnmp/blob/master/README.md 在服务器上装docker与docker-compose 注意&#xff1a;安装docker-compose的时候选择官方版本安装(虽然慢但是请等等)&#xff0c;我操作时出现过国内镜像地址安装但…

flex弹性布局的基本操作知识

今天为大家阐述如何在开发APP或网站的时候&#xff0c;制定一套弹性布局&#xff0c;相互之间兼容&#xff0c;那么我们就可以用Flex来实现&#xff1a; 什么是flex?&#xff1a;Flex是Flexible Box的缩写&#xff0c;意为”弹性布局”&#xff0c;用来为盒状模型提供最大的灵…

Ubuntu 上使用nginx部署vue项目(403/(98: Address already in use))

准备好前端dist文件 保证dist/index.html 点击在本地可以访问&#xff0c; 一&#xff0c;nginx安装 第一步&#xff0c;更新源列表 apt-get update 第二步&#xff0c;安装nginx apt-get install nginx 第三步&#xff0c;检查nginx是否安装成功。如果出现版本号说明安…