brack 发表于 2016-6-6 18:40:17

关于IOS QQ6.0抖动窗口那些事

初涉IOS逆向,蓄势待发,偶然被一好友无限抖动的头疼,所以就去想去看看IOS QQ是否也能无限抖动.就当练手了.
当然了,作为一只菜鸟,仅是分享自己的学习过程,大牛勿喷,么么哒.
所需工具:Reveal,IDA,theos
QQ版本:6.0.0
测试环境:ios8.4,iPhone 5s
备注:QQ为App Store安装已提前砸壳并导出头文件

首先打开QQ界面,并打开Reveal选择iphone看QQ界面的控件.因为点击抖一抖图片才会发送抖动,所以在控件的头文件或者Controller里面有响应事件.


发现控件类是QQRichControl,转至头文件去看一下.
#import "UIButton.h"
   
#import "AvatarServiceDelegate.h"
   
@Class NSString, UIImageView;
   
@interface QQRichControl : UIButton <AvatarServiceDelegate>
{
    NSString *_controlKey;
    unsigned long long _flag;
    id _userData;
    _Bool _shouldShowRedPoint;
    int _xo;
    NSString *_imageName;
    UIImageView *_redPoint;
}
   
+ (id)buttonWithFlag:(unsigned long long)arg1;
+ (id)buttonWithFlag:(unsigned long long)arg1 title:(id)arg2 icon:(id)arg3;
+ (id)buttonWithFlag:(unsigned long long)arg1 title:(id)arg2 icon:(id)arg3 userData:(id)arg4;
- (void)dealloc;
- (void)didLoadImage:(id)arg1 identity:(id)arg2 type:(int)arg3 size:(int)arg4 shape:(int)arg5 avatarInfo:(id)arg6;
- (struct CGRect)imageRectForContentRect:(struct CGRect)arg1;
- (id)initWithFrame:(struct CGRect)arg1;
- (void)loadImageWithImageName:(id)arg1 defaultImage:(id)arg2;
- (id)redPoint;
@property(nonatomic) _Bool shouldShowRedPoint; // @Dynamic shouldShowRedPoint;
- (struct CGRect)titleRectForContentRect:(struct CGRect)arg1;
   
// Remaining properties
@property(retain, nonatomic) NSString *controlKey; // @dynamic controlKey;
@property(readonly, copy) NSString *debugDescription;
@property(readonly, copy) NSString *description;
@property(nonatomic) unsigned long long flag; // @dynamic flag;
@property(readonly) unsigned long long hash;
@property(readonly) Class superclass;
@property(retain, nonatomic) id userData; // @dynamic userData;
   
@end


QQRichControl继承自UIButton,但是在头文件里面并没有发现有跟点击相关的 去Controller的头文件里面去看看





//
//   Generated by class-dump 3.5 (64 bit).
//
//   class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.
//
   
#import "QQBaseChatViewController.h"
   
#import "GetTroopMemberProtocol.h"
#import "GetTroopRemarkProtocol.h"
#import "UIAlertViewDelegate.h"
   
@class NSDictionary, NSMutableArray, NSMutableDictionary, NSString, QC2CRoamMessageService, QCCallEntry, QQAIOTipModel, QQBlueTimer, QQEncounterChatSettingController, QQMessageModel, QQNetWorkTipsView, QQPublicAccountLoadingView, QQRichMsgPreviewDialog, UIActionSheet, UIActivityIndicatorView, UIButton, UILabel, UIProgressView, UIView;
   
@interface QQChatViewController : QQBaseChatViewController <UIAlertViewDelegate, GetTroopMemberProtocol, GetTroopRemarkProtocol>
{
    UIButton *_historyButton;
    UIButton *_voiceModal;
    UIButton *_cardButton;
    QQBlueTimer *timer;
    QQBlueTimer *processTimer;
    UIProgressView *progress;
    UIActivityIndicatorView *act;
    NSDictionary *Imagedict;
    NSMutableDictionary *identDic;
    _Bool ifint;
    _Bool KeyBoard;
    int _displayMsgCount;
    _Bool _flagMsgBarInfoGroup;
    int _flagMsgTmp;
    NSString *_flagMsgBarValueUin;
    _Bool _isReqVideActionSheetShow;
    _Bool _supportInterfaceRote;
    ............
}
   
- (void)ActionSelectVideoFromAlbum;
- (void)ActionShakeWindowMsg;
- (_Bool)Confirmation;
       ........
   
@end

发现了个可疑的函数 - (void)ActionShakeWindowMsg; Shake的意思是抖动的意思.(事实其实是我刚开始也不确定是不是这个,用lldb挂载QQ后下断后才确定就是抖动函数:)
在IDA中 转到 ;





__text:00000001003F3990               MOV             X19, X0
__text:00000001003F3994               BL            _CFAbsoluteTimeGetCurrent
__text:00000001003F3998               ADRP            X8, #qword_10368B8F8@PAGE
__text:00000001003F399C               LDR             D1,
__text:00000001003F39A0               FSUB            D1, D0, D1
__text:00000001003F39A4               FCMP            D0, #0.0
__text:00000001003F39A8               FMOV            D2, #10.0
__text:00000001003F39AC               FCCMP         D1, D2, #8, PL
__text:00000001003F39B0               B.MI            loc_1003F3C24

CFAbsoluteTimeGetCurrent   看函数名就猜出是获取当前时间
__text:00000001003F39A8 FMOV D2, #10.0
这句赋值给D2一个常量10,而QQ的抖动间隔正是10S的时间.

分析到这其实修改跳转就已经理论实现无间隔抖动了(经测试手机抖动有效果,Windows下还是一样,应该是接收消息的函数有判断).
但是并不会用Tweak修改App的二进制内存,在Windows下直接劫持补丁或者WriteProcesMemory就ok了.被难到了.
于是苦逼的去逆了那段间隔大于10S才执行的函数.(具体过程就不贴了)
直接贴代码,英文太渣,大牛看见命名一笑而过就好了...

Tweak.xm
#import "QQShakeOffImpose.h"
   
%hook QQChatViewController
   
- (void)ActionShakeWindowMsg
{
   
    QQMessageModel *message = [%c(QQMessageModel) new];
    ;
    GetServerTimeDiff]];
    ;
;
;
;
;
   
QQBaseChatModel *TchatModel = ;
NSString* Tuin = ;
;
;
unsigned int random = [[%c(QQMsgSyncManager) sharedInstance] getC2CSendMessageRandom];
   
unsigned short msgseq = [[%c(QQMsgSyncManager) sharedInstance] getC2CSendMessageSeq:.longLongValue];
   
;
;
   
];
QQPlatform *Tplatform = [%c(QQPlatform) sharedPlatform];
QQServiceCenter* TserviceCenter = ;
C2CDBService_MultiTable *multiTablwDB =;
;
QQAIOMsgModel *msgModel = [%c(QQAIOMsgModel) createAIOModelWithMessageModel:message];
   
QQChatListManager* listManager = [[%c(QServiceFactory) sharedFactory] getMessageListService];
   
;
;
[[%c(QQF2FMessageSender) getInstance] SendPbShakeWindowMessage:message];
   
}
   
%end

QQShakeOffImpose.h


@interface QServiceFactory : NSObject
+ (id)sharedFactory;
- (id)getMessageListService;
@end
   
@interface C2CDBService_MultiTable : NSObject
- (_Bool)insertSendMessage:(id)arg1;
@end
   
@interface QQServiceCenter : NSObject
{
    C2CDBService_MultiTable *m_c2cMultiTableDB;
}
- (id)C2CMultiTableDB;
@end
   
@interface CIMEngine : NSObject
+ (id)GetInstance;
- (int)GetServerTimeDiff;
@end
   
   
@interface QQPlatform : NSObject
+ (id)sharedPlatform;
- (id)QQServiceCenter;
@end
   
@interface QQMsgSyncManager : NSObject
   
+ (id)sharedInstance;
- (unsigned int)getC2CSendMessageRandom;
- (unsigned short)getC2CSendMessageSeq:(long long)arg1;
@end
   
@interface QQChatListManager : NSObject
- (void)addMessage:(id)arg1;
@end
   
@interface QQAIOModel : NSObject
+ (id)createAIOModelWithMessageModel:(id)arg1;
@end
   
@interface QQAIOMsgModel : QQAIOModel
{
}
@end
   
@interface QQPbMsgSenderBase : NSObject
- (int)SendPbShakeWindowMessage:(id)arg1;
@end
   
@interface QQF2FMessageSender : QQPbMsgSenderBase
+ (id)getInstance;
@end
   
@interface QQBaseChatModel : NSObject
@property(retain, nonatomic) NSString *uin;
@end
   
   
@interface QQMessageModel : NSObject
@property(nonatomic) _Bool loadingState;
@property(nonatomic) unsigned long long time;
@property(retain, nonatomic) id content;
@property(nonatomic) _Bool inOut;
@property(nonatomic) int read;
@property(nonatomic) int msgType;
@property(nonatomic, getter=msgState) int msgState;
@property(retain, nonatomic) NSString *uin;
@property(retain, nonatomic) NSString *groupCode;
@property(nonatomic) long long msgSeq;
@property(nonatomic) long long messageRandom;
@property(nonatomic) long long msgUid;
   
+ (unsigned long long)randomToUid:(unsigned int)arg1;
   
@end
   
   
   
   
@interface QQBaseChatViewController : NSObject
{
      QQBaseChatModel *_chatModel;
}
- (void)appendMessage:(id)arg1;
- (id)GetBaseChatModel;
@end
   
@interface QQChatViewController : QQBaseChatViewController
@end

Makefile


THEOS_DEVICE_IP = 192.168.0.100 //此行为make package install使用 生成deb可删除
ARCHS = armv7 arm64
   
TARGET = iPhone:latest:7.0
   
include theos/makefiles/common.mk
   
TWEAK_NAME = QQShakeOffImpose
QQShakeOffImpose_FILES = Tweak.xm
   
include $(THEOS_MAKE_PATH)/tweak.mk
   
after-install::
    install.exec "killall -9 QQ"



control


Package: com.brack.qqshakeoffimpose
Name: QQShakeOffImpose
Depends: mobilesubstrate
Version: 0.0.1
Architecture: iphoneos-arm
Description: An awesome MobileSubstrate tweak!
Maintainer: brack
Author: brack
Section: Tweaks

nfuyou 发表于 2016-6-6 22:03:17

ontroller : QQBaseChatViewController

Dxer 发表于 2016-6-7 09:05:39

打劫,把**之类的全部上缴

smallhorse 发表于 2016-6-7 09:22:55

跪舔B牛!

hexagon008 发表于 2016-6-7 09:27:19

学习咯谢谢啦

tree_fly 发表于 2016-6-7 13:16:47

支持支持,希望发布更多优秀的帖子~

devin 发表于 2016-6-18 11:18:32

我竟然有点看不懂了

BinCrack 发表于 2018-5-2 13:08:54

学习了。。。。。。

chunwei_2015 发表于 2019-2-28 17:07:38

感谢楼主分享,学习了~
页: [1]
查看完整版本: 关于IOS QQ6.0抖动窗口那些事