16、CycriptLogos

news2024/9/28 9:24:56

一、Cycript

  • Cycript是由Cydia创始人Saurik推出的一款脚本语言,Cycript混合了OC、JavaScript语法的解释器,这意味着我们能够在一个命令中使用OC或者JavaScript,甚至两者并用.它能够挂钩正在运行的进程,能够在运行时修改很多东西.
    • 官网下载/ MonkeyDev自动配置下载
    • 是一种脚本语言,混合了多种语法.(混合了多种语法的解释器),所以可以兼容
    • Cycript可以附加到进程,动态调试应用的

1.1 安装

  • 下载后使用Cycript可执行文件、MonkeyDev安装成功后可不用配置.bash_profile/.zshrc路径,因为MonkeyDev中有

1.2 基本使用

  • cy文件
    • Cycript是一门脚本语言,它可以加载封装好的.cy文件
    • 将常用的Cycript功能封装到.cy文件中,便于调试
    • 非越狱设备,导入.cy文件
      • 利用MonkeyDev工具导入.cy文件
      • MonkeyDev本身集成了Cycript.我们只需要将.cy文件,通过Xcode导入Frameworks目录即可
    • 进入Cycript环境
$ cycript
cy#
    • 退出环境: control +d
  • MonkeyDev中集成了Cycript,使用MonkeyDev重签名应用,会自动注入libcycript.dylib相关文件
  • 当Cycript注入到目标应用,应用进程就会调用Cycript的方法,开启相应的端口,以供第三方监听
  • 第三方可通过端口链接进程,进入cy环境,HOOK当前进程中的内存数据

1.3 使用实战

  • 附加进程
    • 使用MonkeyDev的Demo安装并运行wx8.0.2.ipa
    • 让手机与Mac处于同一网络环境,来到终端,使用设备ip+端口号(默认6666)附加进程
    • 未链接成功时:
      • cyConnect.sh脚本中代码: cycript -r 192.168.124.12:6666
sh cyConnect.sh
*** _syscall(connect(socket_, info->ai_addr, info->ai_addrlen)):/Users/monkey/Documents/Cycript_Project/src/Console.cpp(306):CYSocketRemote [errno=61]
    • 如下显示则表明附加成功
$ cycript -r 192.168.124.12:6666
cy# 
  • 获取keyWindow
cy# UIWindow.keyWindow()
#"<iConsoleWindow: 0x111760ba0; baseClass = UIWindow; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x28347a1f0>; layer = <UIWindowLayer: 0x283b5ed20>>"
  • 获取UIApplication单例对象
cy# UIApp
#"<UIApplication: 0x1117241e0>"
  • 设置当前附加程序App角标数量
cy# [UIApp setApplicationBadgeString: @"999"]
  • 退出后台、设置完当前代码后、可以看到角标数量

  • 但是回到前台时,该角标就会清零,因为修改的是内存中的代码.
  • 再比如修改聊天界面上一个人的名字: “Gray皓白”

    • 通过Cycript链接着运行中的App、
    • 搜索当前界面的UILabel、然后根据关键字“Gray”找到这个label对象地址0x122907c40.
    • 将text内容改为Gray
cy# choose(UILabel)
[#"<MMUILabel: 0x121253a10; baseClass = UILabel; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x28075f930>>",#"<MMUILabel: 0x12126eba0; baseClass = UILabel; frame = (0 0; 0 0); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280747480>>",#"<MMUILabel: 0x121270a50; baseClass = UILabel; frame = (0 0; 0 0); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280747660>>",#"<MMUILabel: 0x121272900; baseClass = UILabel; frame = (0 0; 0 0); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280747700>>",#"<MMUILabel: 0x1212747b0; baseClass = UILabel; frame = (0 0; 0 0); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280744730>>",#"<MMCPLabel: 0x1212b5e50; baseClass = UILabel; frame = (269 0; 414 16); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280730cd0>>",#"<MMUILabel: 0x1212eb8f0; baseClass = UILabel; frame = (56 48; 0 0); text = ''; clipsToBounds = YES; hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2807845a0>>",#"<MMUILabel: 0x1212f97e0; baseClass = UILabel; frame = (56 48; 0 0); text = ''; clipsToBounds = YES; hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280784c80>>",#"<MMUILabel: 0x110c4bce0; baseClass = UILabel; frame = (-22.6667 7.33333; 67 21); text = '\xe6\x94\xb6\xe5\x8f\x96\xe4\xb8\xad\xe2\x80\xa6'; hidden = YES; userInteractionEnabled = NO; tag = 102; layer = <_UILabelLayer: 0x2804feb20>>",#"<MMUILabel: 0x110c86ea0; baseClass = UILabel; frame = (11 7.5; 8 15); text = '7'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280483ac0>>",#"<MMUILabel: 0x110c89200; baseClass = UILabel; frame = (0 0; 0 0); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2804ac320>>",#"<MMUILabel: 0x110c8adb0; baseClass = UILabel; frame = (10.5 7.5; 9 15); text = '4'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2804ac5f0>>",#"<MMCPLabel: 0x110ccf970; baseClass = UILabel; frame = (65 0; 200 16); text = '\xe5\xa4\xa9\xe6\xb4\xa5-\xe5\x88\x98\xe6\xb4\xaa\xe6\xb6\x9b'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2807659f0>>",#"<MMUILabel: 0x110cecf00; baseClass = UILabel; frame = (184.667 40; 69 17); text = '\xe6\xad\xa3\xe5\x9c\xa8\xe5\x8a\xa0\xe8\xbd\xbd\xe2\x80\xa6'; hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2804f16d0>>",#"<MMCPLabel: 0x123107700; baseClass = UILabel; frame = (65 0; 200 16); text = '\xe5\xa4\xa9\xe6\xb4\xa5-\xe5\x88\x98\xe6\xb4\xaa\xe6\xb6\x9b'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280730230>>",#"<MMCPLabel: 0x123108910; baseClass = UILabel; frame = (269 0; 414 16); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280731cc0>>",#"<MMCPLabel: 0x12310d440; baseClass = UILabel; frame = (65 0; 200 16); text = '\xe7\xad\x94\xe7\x96\x91\xe2\x80\x94jz'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280730460>>",#"<MMCPLabel: 0x12310e650; baseClass = UILabel; frame = (269 0; 414 16); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280730f00>>",#"<MMUILabel: 0x12318f140; baseClass = UILabel; frame = (-38 1.33333; 35 21); text = '\xe5\xba\x95\xe5\xb1\x82'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280732990>>",#"<MMUILabel: 0x12318f430; baseClass = UILabel; frame = (-33.3333 22.3333; 67 12); text = '\xe5\xa4\xa7\xe5\xb8\x88\xe7\x8f\xad\xe4\xb8\x89\xe6\x9c\x9f1\xe7\xbe\xa4'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280732c10>>",#"<MMCPLabel: 0x1231b1030; baseClass = UILabel; frame = (65 0; 200 16); text = '\xe7\xad\x94\xe7\x96\x91\xe2\x80\x94jz'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280731d60>>",#"<MMUILabel: 0x1231b8b30; baseClass = UILabel; frame = (0 0; 41 21); text = '(313)'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2807329e0>>",#"<MMCPLabel: 0x122907640; baseClass = UILabel; frame = (65 0; 200 16); text = '\xe5\xa4\xa9\xe6\xb4\xa5-\xe5\x88\x98\xe6\xb4\xaa\xe6\xb6\x9b'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280795630>>",#"<MMCPLabel: 0x122907c40; baseClass = UILabel; frame = (65 0; 200 16); text = 'Gray\xe7\x9a\x93\xe7\x99\xbd'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280794be0>>",#"<MMCPLabel: 0x122908240; baseClass = UILabel; frame = (269 0; 414 16); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280794d70>>",#"<MMUILabel: 0x122913840; baseClass = UILabel; frame = (56 48; 0 0); text = ''; clipsToBounds = YES; hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2807b9860>>",#"<MMCPLabel: 0x122918230; baseClass = UILabel; frame = (65 0; 200 16); text = '\xe7\xad\x94\xe7\x96\x91\xe2\x80\x94jz'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280794410>>",#"<MMUILabel: 0x12292fd00; baseClass = UILabel; frame = (56 48; 0 0); text = ''; clipsToBounds = YES; hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2807b9220>>",#"<MMCPLabel: 0x122933120; baseClass = UILabel; frame = (65 0; 200 16); text = '\xe7\xad\x94\xe7\x96\x91\xe2\x80\x94jz'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280794690>>",#"<MMCPLabel: 0x122938770; baseClass = UILabel; frame = (269 0; 414 16); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280794910>>",#"<MMUILabel: 0x12295b160; baseClass = UILabel; frame = (56 48; 0 0); text = ''; clipsToBounds = YES; hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2807b3d40>>",#"<MMCPLabel: 0x12295fc50; baseClass = UILabel; frame = (269 0; 414 16); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2807957c0>>",#"<MMUILabel: 0x1229780a0; baseClass = UILabel; frame = (56 48; 0 0); text = ''; clipsToBounds = YES; hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280760000>>",#"<MMUILabel: 0x12297a0c0; baseClass = UILabel; frame = (0 0; 0 0); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280797ca0>>",#"<MMUILabel: 0x12297d350; baseClass = UILabel; frame = (56 48; 0 0); text = ''; clipsToBounds = YES; hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2807605f0>>",#"<MMUILabel: 0x122981cb0; baseClass = UILabel; frame = (56 48; 0 0); text = ''; clipsToBounds = YES; hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280760af0>>",#"<MMUILabel: 0x1229868a0; baseClass = UILabel; frame = (56 48; 0 0); clipsToBounds = YES; hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280760e60>>",#"<MMCPLabel: 0x1229b1360; baseClass = UILabel; frame = (65 0; 200 16); text = '\xe5\xa4\xa9\xe6\xb4\xa5-\xe5\x88\x98\xe6\xb4\xaa\xe6\xb6\x9b'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280764320>>",#"<MMCPLabel: 0x1229b2570; baseClass = UILabel; frame = (269 0; 414 16); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280764a00>>",#"<MMUILabel: 0x12116cb60; baseClass = UILabel; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x28048e990>>",#"<MMUILabel: 0x12118f9b0; baseClass = UILabel; frame = (0 0; 0 36); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280747f20>>",#"<MMUILabel: 0x12119c430; baseClass = UILabel; frame = (-19 7.33333; 35 21); text = '\xe5\xbe\xae\xe4\xbf\xa1'; userInteractionEnabled = NO; tag = 104; layer = <_UILabelLayer: 0x2807b0820>>",#"<MMUILabel: 0x12119cfa0; baseClass = UILabel; frame = (56 48; 0 0); text = ''; clipsToBounds = YES; hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2807b8a00>>",#"<MMUILabel: 0x1211a6970; baseClass = UILabel; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2807b1130>>",#"<MMCPLabel: 0x1211b81f0; baseClass = UILabel; frame = (269 0; 414 16); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2807660d0>>",#"<MMUILabel: 0x1211d9090; baseClass = UILabel; frame = (12 4; 60 32); text = '\xe4\xbd\xa0\xe5\x8f\xaf\xe8\x83\xbd\xe8\xa6\x81\xe5\x8f\x91\xe9\x80\x81\xe7\x9a\x84\xe7\x85\xa7\xe7\x89\x87:'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280720c80>>",#"<MMCPLabel: 0x1211dad90; baseClass = UILabel; frame = (269 0; 414 16); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280795090>>",#"<MMUILabel: 0x110d479a0; baseClass = UILabel; frame = (0 -1; 1 20); text = '\xe5\xbe\xae\xe4\xbf\xa1(\xe6\x9c\xaa\xe8\xbf\x9e\xe6\x8e\xa5)'; hidden = YES; userInteractionEnabled = NO; tag = 103; layer = <_UILabelLayer: 0x2804fc140>>",#"<MMUILabel: 0x110d68980; baseClass = UILabel; frame = (-17 0; 35 36); text = '\xe5\xbe\xae\xe4\xbf\xa1'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2804ab2f0>>",#"<MMUILabel: 0x110d76ed0; baseClass = UILabel; frame = (0 0; 0 0); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2804b7980>>",#"<MMUILabel: 0x110d8bf20; baseClass = UILabel; frame = (-19 7.33333; 35 21); text = '\xe5\xbe\xae\xe4\xbf\xa1'; userInteractionEnabled = NO; tag = 104; layer = <_UILabelLayer: 0x2804fc320>>",#"<MMUILabel: 0x110dab3a0; baseClass = UILabel; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x28075d9a0>>",#"<MMUILabel: 0x110dce470; baseClass = UILabel; frame = (180.667 796; 53 15); text = '\xe6\x8c\x89\xe4\xbd\x8f \xe8\xaf\xb4\xe8\xaf\x9d'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2804ff110>>",#"<MMUILabel: 0x110dcfde0; baseClass = UILabel; frame = (176 30; 62 18); text = '\xe5\x8a\xa0\xe8\xbd\xbd\xe6\x9b\xb4\xe5\xa4\x9a'; autoresize = W; userInteractionEnabled = NO; tag = 1680; layer = <_UILabelLayer: 0x2804ff340>>",#"<MMUILabel: 0x110dd7930; baseClass = UILabel; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2804fd590>>",#"<MMUILabel: 0x110dda360; baseClass = UILabel; frame = (0 0; 0 36); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2804ff890>>",#"<MMUILabel: 0x110deb860; baseClass = UILabel; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2807768f0>>",#"<MMUILabel: 0x122a00710; baseClass = UILabel; frame = (56 48; 0 0); text = ''; clipsToBounds = YES; hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280785720>>",#"<MMUILabel: 0x122a2c940; baseClass = UILabel; frame = (56 48; 0 0); text = ''; clipsToBounds = YES; hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280784870>>",#"<MMUILabel: 0x122a430f0; baseClass = UILabel; frame = (56 48; 0 0); text = ''; clipsToBounds = YES; hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280784c30>>",#"<MMUILabel: 0x122a43830; baseClass = UILabel; frame = (56 48; 0 0); text = ''; clipsToBounds = YES; hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280785090>>",#"<MMUILabel: 0x122a99eb0; baseClass = UILabel; frame = (24 -1; 90 36); text = '\xe8\xbf\x9e\xe6\x8e\xa5\xe4\xb8\xad\xe2\x80\xa6'; hidden = YES; userInteractionEnabled = NO; tag = 102; layer = <_UILabelLayer: 0x2807bd7c0>>",#"<MMUILabel: 0x122a9b040; baseClass = UILabel; frame = (0 -1; 1 20); text = '\xe5\xbe\xae\xe4\xbf\xa1(\xe6\x9c\xaa\xe8\xbf\x9e\xe6\x8e\xa5)'; hidden = YES; userInteractionEnabled = NO; tag = 103; layer = <_UILabelLayer: 0x2807bd860>>",#"<MMUILabel: 0x122ab0ba0; baseClass = UILabel; frame = (0 0; 0 0); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280796580>>",#"<MMUILabel: 0x122ab6c70; baseClass = UILabel; frame = (184 12; 46 20); text = '17:40'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280796df0>>",#"<MMCPLabel: 0x122abc110; baseClass = UILabel; frame = (65 0; 200 16); text = '\xe7\xad\x94\xe7\x96\x91\xe2\x80\x94jz'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280764500>>",#"<MMCPLabel: 0x127310960; baseClass = UILabel; frame = (269 0; 414 16); hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x2804d5090>>",#"<RichTextView: 0x1123eba00; baseClass = UILabel; frame = (12 10; 104 21); opaque = NO; layer = <YYAsyncLayer: 0x2837f1fb0>>",#"<RichTextView: 0x1125b8000; baseClass = UILabel; frame = (12 10; 21 21); opaque = NO; layer = <YYAsyncLayer: 0x2837f7570>>",#"<RichTextView: 0x112641c00; baseClass = UILabel; frame = (12 10; 70 21); opaque = NO; layer = <YYAsyncLayer: 0x283769590>>",#"<RichTextView: 0x112673a00; baseClass = UILabel; frame = (12 10; 161 21); opaque = NO; layer = <YYAsyncLayer: 0x283768510>>",#"<RichTextView: 0x112680600; baseClass = UILabel; frame = (12 10; 87 21); opaque = NO; layer = <YYAsyncLayer: 0x28376a6a0>>",#"<RichTextView: 0x111373800; baseClass = UILabel; frame = (12 10; 79 21); opaque = NO; layer = <YYAsyncLayer: 0x2837bcd20>>",#"<RichTextView: 0x1113f4600; baseClass = UILabel; frame = (12 10; 171 21); opaque = NO; layer = <YYAsyncLayer: 0x28376d860>>",#"<RichTextView: 0x1115d5200; baseClass = UILabel; frame = (12 10; 70 21); opaque = NO; layer = <YYAsyncLayer: 0x28376e310>>",#"<RichTextView: 0x11171dc00; baseClass = UILabel; frame = (12 10; 40 21); opaque = NO; layer = <YYAsyncLayer: 0x28376f300>>",#"<RichTextView: 0x111763c00; baseClass = UILabel; frame = (12 10; 84 21); opaque = NO; layer = <YYAsyncLayer: 0x283794240>>"]
cy# 0x122907c40.text = @"Gray"
@"Gray"
    • 这个时候就可以看到界面上已经显示了 Gray

    • 当退出当前群聊、再次进入、上次的修改也会消失.修改的是当时当刻、当前内存中的对象
  • 综上: 我们采用Cycript去调试界面、但是这样步骤比较繁琐;
    • 在Xcode中采用 Debug View Hierarchy直接对界面查找元素比较快.
    • 或者通过Reveal查看元素

1.4 Cycript高级用法

  • MonkeyDev中这些就是封装的高级语法

1.5 Cycript封装

//IIFE 匿名函数自执行表达式
(function(exports){
 APPID = [NSBundle mainBundle].bundleIdentifier,
 APPPATH = [NSBundle mainBundle].bundlePath,
 APPHOME = NSHomeDirectory(),
 //如果有变化,就用function去定义!!
 HKRootvc = function(){
 return UIApp.keyWindow.rootViewController;
 };  
 HKKeyWindow = function(){
 return UIApp.keyWindow;
 };
 HKGetCurrentVCFromRootVc = function(rootVC){
    var currentVC;
    if([rootVC presentedViewController]){
    rootVC = [rootVC presentedViewController];
    }
 
    if([rootVC isKindOfClass:[UITabBarController class]]){
     currentVC = HKGetCurrentVCFromRootVc(rootVC.selectedViewController);
}else if([rootVC isKindOfClass:[UINavigationController class]]){
    currentVC = HKGetCurrentVCFromRootVc(rootVC.visibleViewController);
}else{
    currentVC = rootVC;
}
     return currentVC;
 };
 HKCurrentVC = function(){
     return HKGetCurrentVCFromRootVc(HKRootvc());
 };
 })(exports);
  • 将该文件拷贝进项目中、
    • Build Phases --> Copy Files --> add

  • 导入文件
$ sh cyConnect.sh
cy# @import hank
{}
cy# APPID //Bundle ID
cy# APPHOME //HomeDirectory
cy# HKCurrentVC() //当前控制器
cy# pvcs() //当前控制器层级结构
  • 官网中有详细的使用语法案例:Cycript

二、Logos

  • Logos是一个基于Perl正则表达式的预处理器,它使用优雅的类似Objective-C的语法简化了为OC方法和C函数创建挂钩所需的样板代码.它最常与Theos构建系统一起使用,该系统最初是为创建越狱调整而开发的.Logos曾经与Theos集成在同一个Git仓库中,但现在已经从Theos解耦到它自己的仓库中.
  • Logos语法,其实是CydiaSubstrate框架提供的一组宏定义.便于开发者使用宏进行HOOK操作,语法简单,功能强大且稳定.

2.1 案例使用

  • 创建一个普通项目的iOS LogosDemo、随便写点代码
- (void)loginButtonEvent:(UIButton *)sender {
    [self postUID:self.uid.text PWD:self.pwd.text];
}
- (void)postUID:(NSString *)uid
            PWD:(NSString *)pwd{
    if ([uid isEqualToString:@"Holo"] && [pwd isEqualToString:@"123456"]) {
        UIAlertController * alertVC = [UIAlertController alertControllerWithTitle:@"登录成功" message:nil preferredStyle:(UIAlertControllerStyleAlert)];
        UIAlertAction * cancel = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleCancel) handler:nil];
        [alertVC addAction:cancel];
        [self showViewController:alertVC sender:nil];
    }else{
        UIAlertController * alertVC = [UIAlertController alertControllerWithTitle:@"登录失败" message:nil preferredStyle:(UIAlertControllerStyleAlert)];
        UIAlertAction * cancel = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleCancel) handler:nil];
        [alertVC addAction:cancel];
        [self showViewController:alertVC sender:nil];
    }
}
    • 编译运行Demo、取出MachO文件、来到终端:
      • 通过class-dump取出Headers
class-dump -H LogosDemo -o LogosDemoHeaders/
    • 执行结果如下

    • 这个时候我们需要对该LogosDemo进行重签名、对它进行方法的HOOK操作、
      • HOOK的时候,需要注入一个动态库,load中写一堆HOOK代码
  • 然而回想到MonkeyDev的作用
    • 1、重签名
    • 2、代码注入
    • 3、HOOK注入
  • 此时此刻,我们创建一个MonkeyApp项目、然后将LogosDemo的包放入TargetApp文件夹下.运行LogosMonkey项目、
    • 接下来,根据LogosDemo头文件,我们想要改变登录的状态、开始做HOOK操作
      • 来到LogosMonkeyDylib.xm文件中、删除所有示例代码

      • 稍微写点HOOK后的代码
//告诉当前,ViewController是继承于UIViewCotnroller的
@interface ViewController : UIViewController
@property (nonatomic,strong)UITextField *uid;
@property (nonatomic,strong)UITextField *pwd;
@end;

%hook ViewController
//HOOK的方法
- (void)loginButtonEvent:(id )sender {
    NSString *str = [NSString stringWithFormat:@"%@-%@",self.uid.text,self.pwd.text];
    UIAlertController * alertVC = [UIAlertController alertControllerWithTitle:@"HOOK Success!!!" message:str preferredStyle:(UIAlertControllerStyleAlert)];
    UIAlertAction * cancel = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleCancel) handler:nil];
    [alertVC addAction:cancel];
    [self showViewController:alertVC sender:nil];
}

%end
  • 运行项目、输入账号密码、点击登录、这个时候,我们可以看到我们自己写的HOOK弹窗.操作成功

  • 综上: 这就是简单的利用MonkeyDev中的Logos进行HOOK的操作.

2.2 Logos语法

2.2.1 Logos Tips

  • “LogosMonkeyDylib.xm”后缀名为
    • .x 表示支持logos和C语法
    • .xm表示支持logos、C以及C++语法

2.2.2 Logos语法分为三大类:

  • Block level
    • 这一类型的指令会开辟一个代码块,以 %end结束
    • %group、%hook、%subclass、%end
  • Top Level
    • 这个TopLevel指令不放在BlockLevel中
    • %config、%hookf、%ctor、%dtor
  • Function Level
    • 这一块的指令就放在方法中
    • %init、%class、%c、%orig、%log
  • 常用语法
    • %hook: HOOK某个类里面的某个方法
%hook ClassName
-(void)instanceMethod { }
+(void)classMethod{ }
%end
    • %new: 为某个类添加新方法,在%hook和%end中使用
%hook ClassName
// 添加一个类方法
%new
+(void)newClassMethod{}
//添加一个对象方法
%new
-(void)newInstanceMethod{}
%end
    • %group用来将代码分组.开发中hook代码会很多,这样方便管理Logos代码
%group group1
%hook ClassName

%end
%end
    • %ctor(constructor):构造函数、用于确定加载哪个组.和%init结合用
    • %init: 用来初始化某个组
    • %log: 能够输出日志,输出方法调用的详细信息
    • %orig(original): 这个就是保持原有的方法实现,如果原来的方法有返回值,那么%orig就有返回值的
    • %c: 类似getClass函数,获得一个类对象.一般用于调用类方法

2.2.3 Logos语法使用案例

案例1:

    • 比如刚才的案例: 我们使用%group来做不同的事件、那么需要配合 %ctor来使用
#import <UIKit/UIKit.h>
//告诉当前,ViewController是继承于UIViewCotnroller的
@interface ViewController : UIViewController
@property (nonatomic,strong)UITextField *uid;
@property (nonatomic,strong)UITextField *pwd;
@end;

%group group1
%hook ViewController
//HOOK的方法
- (void)loginButtonEvent:(id )sender {
    NSString *str = [NSString stringWithFormat:@"%@ - %@",self.uid.text,self.pwd.text];
    UIAlertController * alertVC = [UIAlertController alertControllerWithTitle:@"HOOK Group1 Success!!!" message:str preferredStyle:(UIAlertControllerStyleAlert)];
    UIAlertAction * cancel = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleCancel) handler:nil];
    [alertVC addAction:cancel];
    [self showViewController:alertVC sender:nil];
}
%end
%end

%group group2
%hook ViewController
//HOOK的方法
- (void)loginButtonEvent:(id )sender {
    NSString *str = [NSString stringWithFormat:@"%@ - %@",self.uid.text,self.pwd.text];
    UIAlertController * alertVC = [UIAlertController alertControllerWithTitle:@"HOOK Group2 Success!!!" message:str preferredStyle:(UIAlertControllerStyleAlert)];
    UIAlertAction * cancel = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleCancel) handler:nil];
    [alertVC addAction:cancel];
    [self showViewController:alertVC sender:nil];
}
%end
%end

%ctor {
    %init(group1)
}
    • 编写代码如上、这个时候,运行得出错误
Preparing to run Xcode Build Phase for Logos Processor...
Logos Processor: LogosMonkeyDylib.xm -> LogosMonkeyDylib.mm...
Failed Logos Processor: ~/LogosMonkey/LogosMonkeyDylib/Logos/LogosMonkeyDylib.xm:45: 
error: non-initialized hook group: group2
    • 这里表示、group2没有进行初始化: 也就是一旦写了就要初始化
%ctor {
    %init(group1) %init(group2)
}
      • 运行后我们可以发现、起作用的是group2的代码: 也就是说代码会覆盖,执行最后一个分组
    • 添加一个版本判断来单向执行
%ctor {
    NSString *version = [UIDevice currentDevice].systemVersion;
    if (version.doubleValue >= 13.0) {
        %init(group2)
    } else {
        %init(group1)
    }
}
  • 注: logos中使用ctor 则也会有 dtor:析构函数,做一些收尾工作,比如应用挂起时的操作

案例2:

    • 常用的语法: %log的使用
%group group1
%hook ViewController
//HOOK的方法
- (void)loginButtonEvent:(id )sender {
    %log;
}
%end
%end
    • 输出结果为
2023-04-11 21:30:19.813331+0800 LogosDemo[26917:903478] -[<ViewController: 0x127d131d0> loginButtonEvent:<UIButton: 0x127d16750; frame = (50 300; 200 50); clipsToBounds = YES; opaque = NO; layer = <CALayer: 0x28044a240>>]
    • 控制器对象: 方法名称 : 方法参数: 调用者.
    • 如此可见: %log相当于LLDB中的po.

案例3

  • %orig: 这个就是保持原有的方法实现,如果原来的方法有返回值,那么%orig就有返回值的
    • 如果原来的方法有返回值,我们用参数接收,在接收参数后对原始值进行操作.
id  result = %orig;
result += 1;

案例4

  • %new的使用: 为某个类添加新方法,在%hook和%end中使用
@interface ViewController : UIViewController
@property (nonatomic,strong)UITextField *uid;
@property (nonatomic,strong)UITextField *pwd;
@end;

%group group1
%hook ViewController
//HOOK的方法
- (void)loginButtonEvent:(id )sender {
    
    NSString *str = [NSString stringWithFormat:@"%@ - %@",self.uid.text,self.pwd.text];
    UIAlertController * alertVC = [UIAlertController alertControllerWithTitle:@"HOOK Group1 Success!!!" message:str preferredStyle:(UIAlertControllerStyleAlert)];
    UIAlertAction * cancel = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleCancel) handler:nil];
    [alertVC addAction:cancel];
    [self showViewController:alertVC sender:nil];
}

%new
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self.view endEditing:YES];
}
%end
%end
    • 键盘弹起后,点击空白区域,键盘回收.

案例5

  • 当想创建一个类方法时,需要在类中声明及实现
@interface ViewController : UIViewController
@property (nonatomic,strong)UITextField *uid;
@property (nonatomic,strong)UITextField *pwd;
//新增声明的类方法
+ (void)hs_classMethod;
@end;
%group group1
%hook ViewController
%new
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self.view endEditing:YES];
    //[self.class hs_classMethod];
    //通过获取类名 调用类方法
    [NSClassFromString(@"ViewController") hs_classMethod];
}

%new
+ (void)hs_classMethod{
    NSLog(@"This is a class method");
}
%end
%end
    • 获取类名: NSClassFromString(@"ViewController")
  • 另外: 这个时候我们可以引入 %c 来替代上述的获取类名的方法
%new
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self.view endEditing:YES];
    //通过获取类名 调用类方法
    [%c(ViewController) hs_classMethod];
}

案例6

  • %hookf官方案例
// Given the function prototype (only add it yourself if it's not declared in an included/imported header)

FILE *fopen(const char *path, const char *mode);

// The hook is thus made
%hookf(FILE *, fopen, const char *path, const char *mode) {
    puts("Hey, we're hooking fopen to deny relative paths!");
    if (path[0] != '/') {
        return NULL;
    }
    return %orig; // Call the original implementation of this function
}

// functions can also be looked up at runtime, if, for example, the function is in a private framework
%hookf(BOOL, MGGetBoolAnswer, CFStringRef string) {
    if (CFEqual(string, CFSTR("StarkCapability"))) {
        return YES;
    }
    return %orig;
}
%ctor() {
    %init(MGGetBoolAnswer = MSFindSymbol(NULL, "_MGGetBoolAnswer"));
}

三、总结

  • Logos语法其实就是Cydia Substrate框架提供的一组宏定义
  • 语法
    • %hook、%end勾住某个类,在一个代码块中直接写需要勾住的方法
    • %group,%end用于分组: 一般用于不同的系统中做不同的hook内容
      • 每一组都需要 %ctor()函数初始化
      • 通过%init(组名) 进行初始化
    • %log输出方法的详细信息(调用者、方法名、方法参数)
    • %orig调用原始方法.可以传递参数,接收返回值
    • %c类似getClass函数,获得一个类对象
    • %new添加某个方法
  • 关于xm文件, .xm代表支持OC、C/C++语法
  • 编译该文件时,我们需要导入一些头文件,以便编译通过.

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

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

相关文章

浅析EasyCVR平台基于B/S架构的技术特点与应用

EasyCVR基于云边端协同&#xff0c;可支持海量视频的轻量化接入与汇聚管理。平台兼容性强、拓展度高&#xff0c;可提供视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、平台级联等功能。 EasyCVR视频融合平台采用…

手把手教你针对层级时间轮(TimingWheel)延时队列的实战落地

承接上文 承接上文&#xff0c;让我们基本上已经知道了「时间轮算法」原理和核心算法机制&#xff0c;接下来我们需要面向于实战开发以及落地角度进行分析如何实现时间轮的算法机制体系。 前言回顾 什么是时间轮 调度模型&#xff1a;时间轮是为解决高效调度任务而产生的调…

Delphi大师弗兰克·宝兰德(Frank Borland)回来了!

弗兰克宝兰德&#xff08;Frank Borland&#xff09; begin 弗兰克宝兰德&#xff08;Frank Borland&#xff09;的名字其实代表的是我们这些长期坚守Delphi的老程序员。但并非所有Delphi新开发人员都熟悉Borland。 弗兰克宝兰德是谁&#xff1f;他来自哪里&#xff1f;他的主…

动力节点Springsecurity笔记01-05认证入门

1 问题 如何保护我们的程序&#xff1f; 1.1 创建code目录 目的&#xff1a;后面的security工程均在此目录下学习 创建code目录&#xff0c;并使用idea打开 1.2 不使用安全框架的springboot web程序 1.2.1 新建子模块springboot-01-hello [外链图片转存失败,源站可能有防盗…

全志V85x MPP模块概述以及编译sample步骤

本文转载自&#xff1a;https://bbs.aw-ol.com/topic/3286/ 1. MPP 模块概述 MPP 系统控制模块&#xff0c;根据芯片特性&#xff0c;完成硬件各个部件的复位、基本初始化工作&#xff0c;同时负责完成 MPP&#xff08;Media Process Platform 媒体处理平台&#xff09;系统各…

索引失效了?看看这几个常见的原因!

索引是 MySQL 数据库中优化查询性能的重要工具&#xff0c;通过对查询条件和表数据的索引&#xff0c;MySQL可以快速定位数据&#xff0c;提高查询效率。但是&#xff0c;在实际的数据库开发和维护中&#xff0c;我们经常会遇到一些情况&#xff0c;导致索引失效&#xff0c;从…

2、八个JS中你见过的类型

1、前言 为一个变量指定类型的语法是使用"变量: 类型"的形式&#xff0c;如下&#xff1a; let num: number 123如果你没有为这个变量指定类型&#xff0c;编译器会自动根据你赋给这个变量的值来推断这个变量的类型&#xff1a; let num 123 num abc // error 不…

最简洁快速的kaggle注册(无需翻墙)

目录 1.打开浏览器&#xff0c;点击搜索栏最后3个点点 2.点击扩展&#xff0c;会到一个新页面 3.搜索获取&#xff08;安装插件&#xff09; 4.获取之后&#xff0c;网页搜索栏右边会出现该插件&#xff1a; 5.点击管理&#xff1a; 6.在下载规则中&#xff0c;填入下面的地…

SpringBoot整合JWT

一、What is JWT&#xff1f; Json web token (JWT)&#xff0c;是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准&#xff08;(RFC 7519)&#xff0c;该 token 被设计为紧凑且安全的&#xff0c;特别适用于分布式站点的单点登录&#xff08;SSO&#xff09;场…

认识Spring 和 IoC

目录 何为Spring 1. 何为容器 2. 何为 IoC 2.1 传统的程序开发&#xff1a;耦合性太高 2.2 解决传统开发中的缺陷 2.3 对比总结&#xff1a;IoC的实现思想 3. 理解Spring IoC 4. 理解 DI 5. 总结 何为Spring Spring是一个包含了众多工具方法的 IoC 容器&#xff1…

【Scala入门】Scala下载及安装(Windows)以及Idea创建第一个scala项目

目录 一、安装准备 二、Scala下载安装 三、Idea 创建Scala项目 一、安装准备 在安装之前&#xff0c;确保你的电脑上装有Jdk 8&#xff08;Jdk 1.8&#xff09;&#xff0c;且环境变量配置正确。如果没有安装Jdk&#xff0c;请参照其他文章先安装Jdk 8&#xff08;Jdk 1.8&a…

vue3之Teleport传送组件

一、前言 Teleport 是 Vue3.x 新推出的功能&#xff0c; 没听过这个词的小伙伴可能会感到陌生&#xff1b;翻译过来是传送的意思&#xff0c;可能还是觉得不知所以&#xff0c;没事下边我就给大家形象的描述一下。 二、Teleport 是什么呢&#xff1f;干嘛用的&#xff1f; T…

【PMP】敏捷项目月报模板

敏捷项目月报怎么写呢&#xff1f;和普通项目周报有什么不同呢&#xff1f;不知道大家思考过没有&#xff1f; 为此咱们把敏捷项目月报和普通项目月报进行了对比&#xff0c;并且给出了一个参考月报模板和实例&#xff0c;供大家参考。 敏捷项目月报模板 [项目名称]敏捷月报 …

大屏如何打造智慧城市?30张大屏模板送你,零代码基础也会用

超500个智慧城市在路上了 根据国际数据公司&#xff08;IDC&#xff09;最新发布的《全球半年度智慧城市支出指南》显示&#xff0c;2023年全球智慧城市支出预计将达到1895亿美元。中国智慧城市市场在2023年规模将达到389.2亿美元&#xff0c;超过全球平均水平 德勤咨询发布的一…

电脑端(PC)按键精灵——3.其他命令

电脑端(PC)按键精灵——3.其他命令 前两节说了安装、键盘和鼠标命令&#xff0c;这一章说下其他命令 按键精灵小白入门详细教程&#xff1a; 电脑端(PC)按键精灵—小白入门 详细教程 命令介绍 1. Delay 延时 简介 //1秒&#xff1d;1000毫秒, 1分钟&#xff1d;60000毫秒,…

段式内存管理VS页式内存管理

在讲解段式内存管理、页式内存管理之前&#xff0c;需要了解X86体系结构中的实模式和保护模式相关内容。 在 X86 架构诞生之初&#xff0c;其实是没有虚拟内存的概念的。1978 年发行的 8086 芯片是 X86 架构的首款芯片&#xff0c;它在内存管理上使用的是直接访问物理内存的方…

Java版本-招投标采购系统源代码-高效管控招采流程-降低采购成本

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及…

Java数据结构和算法之第五章、LinkedList与链表

一、ArrayList的缺陷 public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable {// ... // 默认容量是10private static final int DEFAULT_CAPACITY 10;//... // 数组&#xff1a;用来存储…

分布式链路追踪之SkyWalking

一 链路追踪简介 在微服务架构中&#xff0c;一次请求往往涉及到多个模块&#xff0c;多个中间件&#xff0c;多台机器的相互协作才能完成。这一系列调用请求中&#xff0c;有些是串行的&#xff0c;有些是并行的&#xff0c;那么如何确定这个请求背后调用了哪些应用&#xff0…

self-attention和cross-attention

为什么Self-Attention要通过线性变换计算Q K V&#xff0c;背后的原理或直观解释是什么&#xff1f; - 知乎回答题主问题题主的问题: 在attention中都经过一个映射&#xff0c;那么建模的相似度是否就没有意义了&#xff1f;个人感觉这…https://www.zhihu.com/question/592626…