1. Goal
Because when I was watching the live broadcast, the anchor asked me to send 666 to support him. I definitely supported him, so I kept sending it. But later I found that it was a waste of time. Can I make a live broadcast room to automatically send 666? So I spent a few minutes making one.
2. Operating environment
-
Jailbreak an iPhone
-
frida
-
mac
3. Process
Download the latest Yin App
Since we are sending messages, the keyword sendmessage is our entry point.
Execute in terminal
//模糊匹配sendmessage
frida-trace -U -m "*[* *messag*]" xxxxx音
After executing the command, the information list is obtained:
After screening and printing the input parameters and return values of the above methods, the output log parameters attracted our attention.
Key information: sendComment
-[HTSLiveCommentFragment sendComment:0x9e4d4021463d8688 source:0x0 messageSource:0x0 completion:0x0]
Verify our conjecture
Execute in the terminal and continue hooking
frida-trace -UF -m "-[HTSLiveCommentFragment sendComment:source:messageSource:completion:]"
Get the information list:
-[HTSLiveCommentFragment sendComment:666666666 source:0x0 messageSource:0x0 completion:0x0]
Among them, "6666666" is the content I sent in the live broadcast room.
Then the problem comes, I found that the sending method is minus sign - [xxxx xxxxxx]
In this way, HTSLiveCommentFragment cannot be called directly.
Then continue hooking HTSLiveCommentFragment and see where she was created.
Execute in the terminal and continue hooking
frida-trace -UF -m "-[HTSLiveCommentFragment *]"
Get the information list:
3964 ms -[HTSLiveCommentFragment initWithStore:0x2836ef200]
3964 ms -[HTSLiveCommentFragment initWithStore:<HTSLiveCommentStore: 0x2836ef200>]
Found that HTSLiveCommentFragment is created by initWithStore.
Then create the hook directly and call sendComment to send the message.
3. Write deb plug-in 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
Get the live broadcast page
HTSLiveAudienceViewController, add a button to it
Add a small round button to the page
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:@"[email protected]"]];
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
Xiaoyuanqiu source code
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
at last
You can have fun and the host will never say that I don’t support him again.