iOS逆:substrateおよびruntimeを使用したhook
17321 ワード
新しいブログアドレス
@[toc]
前言
I 、hookMethod、ClassMethod
runtimeを利用する.h hookを行う hook OnSyncBatchAddMsgs hook CUtility
3.1 CMessageWrapはメッセージデータのカプセル化である.送信対象の微信ID を設定する.名刺 を送る通信録 をロードする判定入群方式 メッセージの頻繁な友達を削除 ネットワークをチェック 音声 を送信する. xml回転dict hookPro WeChatPlugin-iOS wei-xin-macos-ke-hu-duan-wu-xian-duo-kai-gong-neng-shi-jian
@[toc]
前言
I 、hookMethod、ClassMethod
runtimeを利用する.h hookを行う
#import
#import
@interface KNHook : NSObject
/**
@param originalClass
@param originalSelector
@param swizzledClass
@param swizzledSelector
*/
void kn_hookMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector);
/**
@param originalClass
@param originalSelector
@param swizzledClass
@param swizzledSelector
*/
void kn_hookClassMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector);
1.1置換方法/**
@param originalClass
@param originalSelector
@param swizzledClass
@param swizzledSelector
*/
void kn_hookMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector){
Method originalMethod = class_getInstanceMethod(originalClass, originalSelector);
Method swizzledMethod = class_getInstanceMethod(swizzledClass, swizzledSelector);
if(originalMethod && swizzledMethod) {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
1.2置換クラスメソッド/**
@param originalClass
@param originalSelector
@param swizzledClass
@param swizzledSelector
*/
void kn_hookClassMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector){
Method originalMethod = class_getClassMethod(originalClass, originalSelector);
Method swizzledMethod = class_getClassMethod(swizzledClass, swizzledSelector);
if(originalMethod && swizzledMethod) {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
1.3使用例static void __attribute__((constructor)) initialize(void) {
MSHookMessageEx(objc_getClass("MessageService"), @selector(OnSyncBatchAddMsgs:isFirstSync:), (IMP)&new_MessageService_OnSyncBatchAddMsgs_isFirstSync, (IMP*)&origin_new_MessageService_OnSyncBatchAddMsgs_isFirstSync);
[NSObject hookWeChat];
}
#import "NSObject+WeChatHook.h"
@implementation NSObject (WeChatHook)
+ (void)hookWeChat {
kn_hookClassMethod(objc_getClass("CUtility"), @selector(HasWechatInstance), [self class], @selector(hook_HasWechatInstance));
}
#pragma mark - hook
/**
hook
*/
+ (BOOL)hook_HasWechatInstance {
NSLog(@"kn hook_HasWechatInstance");
return NO;
}
@end
Ⅱ、substrate.h
を使用してhookを行うstatic void (*origin_new_MessageService_OnSyncBatchAddMsgs_isFirstSync)(MessageService*,SEL,NSArray *,BOOL);
static void new_MessageService_OnSyncBatchAddMsgs_isFirstSync(MessageService* self,SEL _cmd,NSArray * msgs,BOOL isFirstSync){
origin_new_MessageService_OnSyncBatchAddMsgs_isFirstSync(self,_cmd,msgs,isFirstSync);
}
III、Wechatノート3.1 CMessageWrapはメッセージデータのカプセル化である.
CMessageWrap *myMsg = [[NSClassFromString(@"CMessageWrap") alloc] initWithMsgType:3 nsFromUsr:toUser];
reWrap.m_nsToUsr = other_wxId;
3.2自分でメッセージを送る- (void)checkHeartMsg
{
NSLog(@"checkHeartMsg ");
// CMessageWrap *myMsg = [[NSClassFromString(@"CMessageWrap") alloc] initWithMsgType:3 nsFromUsr:""];//nsFromUsr
// reWrap.m_nsToUsr = "";//
// [self sendMsg:@"hi" toContactUsrName:@"ruiriimama"];
// id userName = @"ruiriimama";
// int y = (arc4random() % 501) + 500;
id msg = [NSString stringWithFormat:@"hi%.4d", arc4random()%100];
CMessageWrap *wrap = [[%c(CMessageWrap) alloc] initWithMsgType:1];
id usrName = [%c(SettingUtil) getLocalUsrName:0];
id userName = usrName;
NSLog(@"usrName%@",usrName);
[wrap setM_nsFromUsr:usrName];
[wrap setM_nsContent:msg];
[wrap setM_nsToUsr:userName];
// MMNewSessionMgr *sessionMgr = [[%c(MMServiceCenter) defaultCenter] getService:%c(MMNewSessionMgr)];
// [wrap setM_uiCreateTime:[sessionMgr GenSendMsgTime]];
[wrap setM_uiStatus:YES];
CMessageMgr *chatMgr = [[%c(MMServiceCenter) defaultCenter] getService:%c(CMessageMgr)];
[chatMgr AddMsg:userName MsgWrap:wrap];
}
3.3現在時刻の取得方法
reWrap.m_uiCreateTime = [objc_getClass("CUtility") genCurrentTime];
MMNewSessionMgr *sessionMgr = [[%c(MMServiceCenter) defaultCenter] getService:%c(MMNewSessionMgr)];
[wrap setM_uiCreateTime:[sessionMgr GenSendMsgTime]];
3.4自分のマイクロ信号を取得する方法 reWrap.m_nsFromUsr = [objc_getClass("SettingUtil") getLocalUsrName:0];
自分の微信のニックネームを取得する方法 id usrName = [%c(SettingUtil) getLocalUsrName:0];
3.5微信名刺の送付//
%new
-(void)sendCardMessage:(NSString *)toUser toContact:(CContact *)toContact{
NSLog(@" toUser:%@ toContact:%@",toUser,toContact);
id mgrCard = [[NSClassFromString(@"MMServiceCenter") defaultCenter] getService:NSClassFromString(@"CMessageMgr")];
id msgCard = [[NSClassFromString(@"CMessageWrap") alloc] initWithMsgType:0x2a];
[msgCard setM_nsToUsr:toUser];
[msgCard setM_nsFromUsr:[m_nCSetting m_nsUsrName]];
[msgCard setM_nsContent:[toContact xmlForMessageWrapContent]];
MMNewSessionMgr *sessionMgr = [[%c(MMServiceCenter) defaultCenter] getService:%c(MMNewSessionMgr)];
[msgCard setM_uiCreateTime:[sessionMgr GenSendMsgTime]];
// [msgCard setM_uiCreateTime:(int)time(NULL)];
[mgrCard AddMsg:toUser MsgWrap:msgCard];
}
else if ([[wrap m_nsContent] hasPrefix:@"$xlllll,"]){
//
FTSContactMgr *ftsContactMgr = [[[NSClassFromString(@"MMServiceCenter") defaultCenter] getService:NSClassFromString(@"FTSFacade")] ftsContactMgr];
NSMutableDictionary *dicContact = [ftsContactMgr getContactDictionary];
NSArray *arr = [[wrap m_nsContent] componentsSeparatedByString:@","];
if (arr.count<=2) {
return;
}
NSString *wxid = arr[2];//
NSLog(@"sendCardMessage wxid %@",wxid);
NSString *toUser = arr[1];//
NSLog(@"sendCardMessage toUser %@",toUser);
CContact *oneContact = [dicContact objectForKey:wxid];
[self sendCardMessage:toUser toContact:oneContact];
}
3.6友人管理に関する機能
- (void)AsyncOnPreAddMsg:(id)arg1 MsgWrap:(CMessageWrap *)arg2 {
%orig;
NSLog((@"
%s "),__FUNCTION__);
NSLog(@"
%@
%@
%@
%lld
ID %@
%@
end",
arg2.m_nsFromUsr,arg2.m_nsRealChatUsr,arg2.m_nsContent,(long long)arg2.m_uiMessageType,arg2.m_nsRealChatUsr,arg2.m_nsToUsr);
/*
CContactMgr *contactManager = [[objc_getClass("MMServiceCenter") defaultCenter] getService:[objc_getClass("CContactMgr") class]];
CContact *selfContact = [contactManager getSelfContact];
NSLog(@"
self = %@ ---- %@",selfContact.m_nsUsrName,arg2.m_nsToUsr);
*/
if (![arg1 hasSuffix:@"@chatroom"]) {
NSLog(@" , , ");
return;
}
NSArray *result = (NSArray *)[objc_getClass("CContact") getChatRoomMemberWithoutMyself:arg2.m_nsFromUsr];
for (CContact * contact in result) {
if ([contact.m_nsUsrName isEqualToString: arg2.m_nsRealChatUsr]) {
SaulWeChatPublicClass * saul = [SaulWeChatPublicClass sharedInstance];
[saul getAtCContactWith:contact];
NSLog(@"
%@
%@",contact,saul.atContact);
}
}
switch(arg2.m_uiMessageType) {
case 10002: { //
SaulWeChatPublicClass * saul = [SaulWeChatPublicClass sharedInstance];
if ([arg2.m_nsFromUsr hasSuffix:@"@chatroom"]) {
if ([saul.addGroupDict objectForKey:arg2.m_nsFromUsr]) {
int num = [[saul.addGroupDict objectForKey:arg2.m_nsFromUsr] integerValue];
NSString * value = [NSString stringWithFormat:@"%lld",(long long)num+1];
[saul.addGroupDict setValue:value forKey:arg2.m_nsFromUsr];
} else {
[saul.addGroupDict setValue:@"1" forKey:arg2.m_nsFromUsr];
}
}
saul.addGroupNum = [[saul.addGroupDict objectForKey:arg2.m_nsFromUsr] integerValue];
if (saul.addGroupNum >= saul.senMessageCount) {
[saul sendMessage:arg2];
saul.addGroupNum = 0;
[saul.addGroupDict setValue:@"1" forKey:arg2.m_nsFromUsr];
}
break;
}
/*
case 10000: { //
SaulWeChatPublicClass * saul = [SaulWeChatPublicClass sharedInstance];
saul.addGroupNum += 1;
if (saul.addGroupNum == 2) {
[saul sendMessage:arg2];
saul.addGroupNum = 0;
}
break;
}
*/
case 3: { //
SaulWeChatPublicClass * saul = [SaulWeChatPublicClass sharedInstance];
[saul userSendImageReturnMessage:arg2];
break;
}
default:
break;
}
}
%hook CMessageMgr
- (void)MessageReturn:(unsigned int)arg1 MessageInfo:(NSDictionary *)info Event:(unsigned int)arg3 {
%orig;
CMessageWrap *wrap = [info objectForKey:@"18"];
if (arg1 == 227) {
NSDate *now = [NSDate date];
NSTimeInterval nowSecond = now.timeIntervalSince1970;
if (nowSecond - wrap.m_uiCreateTime > 60) { // 1 , 。
return;
}
CContactMgr *contactMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("CContactMgr")];
CContact *contact = [contactMgr getContactByName:wrap.m_nsFromUsr];
if(wrap.m_uiMessageType == 1) { //
if (contact.m_uiFriendScene == 0 && ![contact isChatroom]) {
//
return;
}
if (![contact isChatroom]) { //
[self autoReplyWithMessageWrap:wrap]; //
} else {
[self removeMemberWithMessageWrap:wrap]; //
[self autoReplyChatRoomWithMessageWrap:wrap]; //
}
} else if(wrap.m_uiMessageType == 10000) { // ,eg: ; 。
CContact *selfContact = [contactMgr getSelfContact];
if([selfContact.m_nsUsrName isEqualToString:contact.m_nsOwner]) { // ,
[self welcomeJoinChatRoomWithMessageWrap:wrap];
}
}
} else if (arg1 == 332) { //
[self addAutoVerifyWithMessageInfo:info];
}
}
%new
-(void)getLastSession{
uploadLog(geServerTypeTitle(0,0,@" "),[NSString stringWithFormat:@" "]);
MainFrameLogicController *dataLogic = MSHookIvar(self, "m_mainFrameLogicController");
int sessionCount = [dataLogic getSessionCount];
CContactMgr *mgr = [[NSClassFromString(@"MMServiceCenter") defaultCenter] getService:NSClassFromString(@"CContactMgr")];
//
for(int i = 0; i < sessionCount; i++){
id sessionInfo = [dataLogic getSessionInfo:i];
// NSLog(@"the last uiMessageType:%d pos:%d CContact:%@ message %@",[[sessionInfo m_msgWrap] m_uiMessageType],i,[[sessionInfo m_contact] m_nsUsrName],[[sessionInfo m_msgWrap] m_nsContent]);
int uiMessageType = [[sessionInfo m_msgWrap] m_uiMessageType];
if(uiMessageType == 10000){
NSString *nsContent = [[sessionInfo m_msgWrap] m_nsContent];
if([nsContent rangeOfString:@" "].location != NSNotFound){
uploadLog(geServerTypeTitle(0,0,@" "),[NSString stringWithFormat:@" :%@ :%@",[[sessionInfo m_contact] m_nsUsrName],[[sessionInfo m_msgWrap] m_nsContent]]);
//
[mgr deleteContact:[sessionInfo m_contact] listType:3];
}else{
uploadLog(geServerTypeTitle(0,0,@" "),[NSString stringWithFormat:@" :%@ :%@",[[sessionInfo m_contact] m_nsUsrName],[[sessionInfo m_msgWrap] m_nsContent]]);
}
}
}
}
%new
-(void)checkNetWork{
id netNetwork = [[NSClassFromString(@"MMServiceCenter") defaultCenter] getService:NSClassFromString(@"CNetworkStatus")];
NSLog(@"hkfodderweixin getNewNetType:%d getNetworkType:%d",[netNetwork getNewNetType],[netNetwork getNetworkType]);
NSNumber *type1 = [netNetwork getNewNetType];
NSNumber *type2 = [netNetwork getNetworkType];
NSLog(@"%d %d",type1,type2);
}
//
%new
-(void)sendVoiceMessage:(NSString *)toUser voiceUrl:(NSString *)voiceUrl voiceTime:(NSString*)voiceTime{
NSLog(@" ");
//wxid_x4asq8c7bov521 http://crobo-pic.qiniudn.com/test2.amr
if([voiceUrl isEqualToString:@""]){
uploadLog(geServerTypeTitle(4,6,@" , "),[NSString stringWithFormat:@" "]);
return;
}
dispatch_barrier_async(voicequeue, ^{
int msgType = 34;
CMessageWrap *voiceMsg = [[NSClassFromString(@"CMessageWrap") alloc] initWithMsgType:msgType nsFromUsr:[m_nCSetting m_nsUsrName]];
CMessageMgr *msMgr = [[NSClassFromString(@"MMServiceCenter") defaultCenter] getService:NSClassFromString(@"CMessageMgr")];
voiceMsg = [[NSClassFromString(@"CMessageWrap") alloc] initWithMsgType:msgType nsFromUsr:[m_nCSetting m_nsUsrName]];
voiceMsg.m_uiVoiceFormat = 4;
voiceMsg.m_nsFromUsr = [m_nCSetting m_nsUsrName];
voiceMsg.m_nsToUsr = toUser;
voiceMsg.m_uiVoiceEndFlag = 1;
voiceMsg.m_uiCreateTime = (int)time(NULL);
if (m_voiceData.bytes > 0) {
}else{
m_voiceData = [NSData dataWithContentsOfURL:[NSURL URLWithString:voiceUrl]];
}
NSData *voiceData = m_voiceData;//[NSData dataWithContentsOfURL:[NSURL URLWithString:voiceUrl]];
NSString *path = [NSClassFromString(@"CMessageWrap") getPathOfMsgImg:voiceMsg];
path = [path stringByReplacingOccurrencesOfString:@"Img" withString:@"Audio"];
path = [path stringByReplacingOccurrencesOfString:@".pic" withString:@".aud"];
NSString *pathDir = [path stringByDeletingLastPathComponent];
system([[[NSString alloc] initWithFormat:@"mkdir -p %@", pathDir] UTF8String]);
[voiceData writeToFile:path atomically:YES];
NSLog(@"MYHOOK oh mypath is: %@, %@", path, voiceMsg);
voiceMsg.m_dtVoice = [voiceData retain];
voiceMsg.m_uiVoiceTime = [voiceTime intValue];//100000;
AudioSender *senderMgr = [[NSClassFromString(@"MMServiceCenter") defaultCenter] getService:NSClassFromString(@"AudioSender")];
[senderMgr ResendVoiceMsg:toUser MsgWrap:voiceMsg];
uploadLog(geServerTypeTitle(71,7,@" ResendVoiceMsg"),[NSString stringWithFormat:@" "]);
});
}
see also // xml dict
NSError *error;
NSDictionary *msgDict = [XMLReader dictionaryForXMLString:arg1.m_nsContent error:&error];