【iOS逆向与安全】插件开发之某音App直播间自动发666

news/2024/7/20 21:57:57 标签: objective-c, frida, ios
1.目标

由于看直播的时候主播叫我发 666,支持他,我肯定支持他呀,就一直发,可是后来发现太浪费时间了,能不能做一个直播间自动发 666 呢?于是就花了几分钟做了一个。

2.操作环境
  • 越狱iPhone一台

  • frida

  • mac

 3.流程

下载最新某音App

既然是发送消息,那关键词 sendmessage 则是我们的切入点

在终端执行
//模糊匹配sendmessage
frida-trace -U  -m "*[* *messag*]" xxxxx音   

执行命令后,获取到信息列表:

经过一筛查打印以上方法的入参和返回值,输出的日志参数,引起了我们的注意

关键信息:sendComment
-[HTSLiveCommentFragment sendComment:0x9e4d4021463d8688 source:0x0 messageSource:0x0 completion:0x0]

验证我们的猜想

在终端执行,继续 hook

frida-trace -UF  -m "-[HTSLiveCommentFragment sendComment:source:messageSource:completion:]"

获取到信息列表:

 -[HTSLiveCommentFragment sendComment:666666666 source:0x0 messageSource:0x0 completion:0x0]

其中“6666666” 就我在直播间发送的内容

那么问题来了,发现这个发送方法是 减号 -[xxxx xxxxxx]

这样就没法直接调用 HTSLiveCommentFragment

那就继续 hook  HTSLiveCommentFragment,看看她是在哪里创建的

在终端执行,继续 hook
frida-trace -UF -m "-[HTSLiveCommentFragment *]"

获取到信息列表: 

  3964 ms  -[HTSLiveCommentFragment initWithStore:0x2836ef200]
  3964 ms  -[HTSLiveCommentFragment initWithStore:<HTSLiveCommentStore: 0x2836ef200>]

 发现 HTSLiveCommentFragment 是由 initWithStore 创建而来。

那就直接 hook 创建,在调用sendComment  来实现发送消息。

3、编写deb插件 logs

NSString *nickname=@"未获取昵称";

HTSLiveCommentFragment *liveComm;//全局 储存创建好的对象 类

%hook HTSLiveCommentFragment
//HTSLiveCommentStore
- (HTSLiveCommentFragment *)initWithStore:(id)arg1{
    
//    id mHTSLiveUser = MSHookIvar<id>(arg1,"_currentUse");//HTSLiveUser
//    NSString *name = MSHookIvar<NSString *>(mHTSLiveUser,"nickname");
//    nickname =name;
    
    liveComm = %orig;//获取到创建好的对象 类(每切换一次,自动覆盖

    return liveComm;
}

%end
 获取直播页面

HTSLiveAudienceViewController,给他添加一个按钮

 页面添加小圆圆 按钮
BallUIView *upASUserInfo;//移动圆圆

//直播页面 Controller
%hook HTSLiveAudienceViewController

- (void)viewDidLoad{
    %orig;// 页面加载完毕
    
    __weak typeof(self) weakSelf = self;
    if(upASUserInfo == nil){
        //配置
        CGRect rect_screen = [[UIScreen mainScreen]bounds];
        CGSize size_screen = rect_screen.size;
        int height = size_screen.height;
        int width  = size_screen.width;
        
        // 移动圆圆
        upASUserInfo = [[BallUIView alloc] initWithFrame:CGRectMake(width-80, height/2-200, 50, 50)];
        upASUserInfo.backgroundColor = [UIColor whiteColor];
        upASUserInfo.layer.cornerRadius = 25;
        upASUserInfo.layer.masksToBounds = YES;
        
        //小圆球 图标
        UIImageView *imgViewM = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"AppIcon60x60@2x.png"]];
        imgViewM.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        imgViewM.frame = CGRectMake(0, 0, 50, 50);
        [upASUserInfo insertSubview:imgViewM atIndex:0];
        
        
        
    }
    
    [weakSelf.view addSubview:upASUserInfo];
    
    upASUserInfo.btnClick = ^(UIButton *sender) {
        UIAlertController *ac = [UIAlertController alertControllerWithTitle:@"当前标识"
                                                                    message:nickname
                                                             preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *ala1 = [UIAlertAction actionWithTitle:@"666666" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action){

        }];
        UIAlertAction *ala2 = [UIAlertAction actionWithTitle:@"发送消息" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action){
            [xddCode userInfoModel:liveComm];//传入获取到的 对象,发送消息
        }];
        UIAlertAction *ala3 = [UIAlertAction actionWithTitle:@"退出应用" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action){
            exit(0);
        }];
        UIAlertAction *Cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            
        }];
        
        [ac addAction:ala1];
        [ac addAction:ala2];
        [ac addAction:ala3];
        [ac addAction:Cancel];
        
        [weakSelf presentViewController:ac animated:YES completion:nil];
    };
    
    
    
}
%end

 

xddCode.m

#import "xddCode.h"

@implementation xddCode

+(NSString *) userInfoModel:(HTSLiveCommentFragment*)info {

    [info sendComment:@"666666666" source:0x0 messageSource:0x0 completion:0x0];
}

@end

小园球源码

BallUIView.h


#import <UIKit/UIKit.h>

typedef void (^floatBtnClick)(UIButton *sender);

NS_ASSUME_NONNULL_BEGIN

@interface BallUIView : UIView
// 属性 机,记录起点

@property(nonatomic,assign)CGPoint startPoint;


//按钮点击事件
@property (nonatomic, copy)floatBtnClick btnClick;

@end

NS_ASSUME_NONNULL_END

BallUIView.m



#import "BallUIView.h"


#define screenW  [UIScreen mainScreen].bounds.size.width
#define screenH  [UIScreen mainScreen].bounds.size.height

@interface BallUIView()
//悬浮的按钮
//@property (nonatomic, strong) MNFloatContentBtn *floatBtn;
@end

@implementation BallUIView{
    
    //拖动按钮的起始坐标点
    CGPoint _touchPoint;
    
    //起始按钮的x,y值
    CGFloat _touchBtnX;
    CGFloat _touchBtnY;
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//    NSLog(@"按下 获取起点1");
    
    //获取 触摸 对象
    
    UITouch *touch = [touches anyObject];
    
    _touchBtnX = self.frame.origin.x;
    _touchBtnY = self.frame.origin.y;
    
    //找到点击的起点
    self.startPoint = [touch locationInView:self];
    
}

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//    NSLog(@"移动  让小球的运动起来2");
    
    //先回去  触摸对象
    
    UITouch * touch = [touches anyObject];

    //获取移动中的点
    CGPoint newPoint = [touch locationInView:self];
    
    //计算x y 坐标分别移动了多少
    CGFloat dx = newPoint.x - self.startPoint.x;
    CGFloat dy = newPoint.y - self.startPoint.y;
    
    //改变小球的位置
    self.center = CGPointMake(self.center.x + dx,
                                      self.center.y + dy);
    

}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
//    NSLog(@"按下 结束3");
    
    CGFloat btnY = self.frame.origin.y;
    CGFloat btnX = self.frame.origin.x;
    CGFloat minDistance = 3;
    
    //结束move的时候,计算移动的距离是>最低要求,如果没有,就调用按钮点击事件
    BOOL isOverX = fabs(btnX - _touchBtnX) > minDistance;
    BOOL isOverY = fabs(btnY - _touchBtnY) > minDistance;
    
    if (isOverX || isOverY) {
        //超过移动范围就不响应点击 - 只做移动操作
        //NSLog(@"move - btn");
        //设置移动方法
        [self setMovingDirectionWithBtnX:btnX btnY:btnY];
    }else{
        //NSLog(@"call - btn");
        if (self.btnClick) {
            self.btnClick(nil);
        }else{
            //[self changeEnv];
        }
    }
    
    
}

static CGFloat floatBtnW = 50;
static CGFloat floatBtnH = 50;
- (void)setMovingDirectionWithBtnX:(CGFloat)btnX btnY:(CGFloat)btnY{
//    switch (_type) {
//        case MNAssistiveTypeNone:{
            //自动识别贴边
            if (self.center.x >= screenW/2) {

                [UIView animateWithDuration:0.5 animations:^{
                    //按钮靠右自动吸边
                    CGFloat btnX = screenW - floatBtnW;
                    self.frame = CGRectMake(btnX, btnY, floatBtnW, floatBtnH);
                }];
            }else{

                [UIView animateWithDuration:0.5 animations:^{
                    //按钮靠左吸边
                    CGFloat btnX = 0;
                    self.frame = CGRectMake(btnX, btnY, floatBtnW, floatBtnH);
                }];
            }
//            break;
//        }
//        case MNAssistiveTypeNearLeft:{
//            [UIView animateWithDuration:0.5 animations:^{
//                //按钮靠左吸边
//                CGFloat btnX = 0;
//                self.frame = CGRectMake(btnX, btnY, floatBtnW, floatBtnH);
//            }];
//            break;
//        }
//        case MNAssistiveTypeNearRight:{
//            [UIView animateWithDuration:0.5 animations:^{
//                //按钮靠右自动吸边
//                CGFloat btnX = screenW - floatBtnW;
//                self.frame = CGRectMake(btnX, btnY, floatBtnW, floatBtnH);
//            }];
//        }
//    }
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

@end
  最后

就可以愉快的玩耍了,主播以后再也不会说我不支持他了。


http://www.niftyadmin.cn/n/5040994.html

相关文章

百度APP iOS端包体积50M优化实践(六)无用方法清理

一、前言 百度APP包体积经过一期优化&#xff0c;如无用资源清理&#xff0c;无用类下线&#xff0c;Xcode编译相关优化&#xff0c;体积已经有了明显的减少。但是优化后APP包体积在iPhone11上仍有350M的空间占用。与此同时百度APP作为百度的旗舰APP&#xff0c;业务迭代非常多…

家居服务小程序发展指南

随着互联网的快速发展&#xff0c;越来越多的企业开始关注并投资于线上平台的建设&#xff0c;以满足用户的多样化需求。家居服务行业也不例外&#xff0c;通过打造小程序平台&#xff0c;可以更好地服务用户&#xff0c;提供更便捷的家居服务体验。 首先&#xff0c;我们可以选…

基于TCP的Qt网络通信

目录 前言 实现原理 1. 模块添加 2.常用接口函数API 3. QTcpServer 3.1 公共成员函数 3.1.1 构造函数 3.1.2 给监听的套接字设置监听 3.1.3 返回监听成功的套接字对象 3.2 信号 4. QTcpSocket 4.1 公共成员函数 4.1.1 构造函数 4.1.2 连接服务器&#xff0c;需要…

第九天:QT入门保姆教程(常用的控件,信号与槽,定时器 QTimer,样式表 Qt Style Sheets,sqlite3数据库,开发板串口)

QT的简介 我另外分享了一个qt案例源码包&#xff0c;里面包括文章中的任务源码和一系列常用案例需要的点击此处下载 官网 www.qt.io QT 是一个基于C的 跨平台的 应用程序开发框架 跨平台&#xff1a;一次编写&#xff0c;到处编译 主流的平台都支持&#xff0c;如&#xff1a…

51单片机3【单片机的种类】

1.51单片机发展史 1. 发展史 &#xff08;1&#xff09;总结&#xff1a;早期是不分单片机和其他CPU的&#xff0c;早期都是一起的&#xff0c;后来应用级别的高端CPU相继推出用于别的行业&#xff08;PC&#xff0c;手机&#xff09;其中一支专用与低性能&#xff0c;低价格作…

【Java 基础篇】Java同步方法解决数据安全

多线程编程是现代应用程序开发中的常见需求&#xff0c;它可以提高程序的性能和响应能力。然而&#xff0c;多线程编程也带来了一个严重的问题&#xff1a;数据安全。在多线程环境下&#xff0c;多个线程同时访问和修改共享的数据可能导致数据不一致或损坏。为了解决这个问题&a…

Spring底层原理之 BeanFactory 与 ApplicationContext

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaEE 操作系统 Redis 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 Spring底层原理 一、 BeanFactory 与 Appli…

.NET中使用Quartz

Quartz是一个流行的开源任务调度库&#xff0c;它提供了强大的任务调度功能&#xff0c;可以方便地与.NET应用程序集成。 Quartz.NET是Quartz的.NET版本&#xff0c;它是为.NET框架编写的&#xff0c;并提供了与.NET应用程序的集成。它支持各种调度策略&#xff0c;包括定时、…