ios微信逆向實戰--自動搶紅包、修改步數、防止消息撤回

八九個月以前就看到了這篇文章
一步一步實現iOS微信自動搶紅包(非越獄),然后自己嘗試著開始自己弄一個,但由于我的設備是ios9.3.2有點奇怪,在砸殼和打包的環節卡住了。在一兩個月以前又看見有人成功了:Make WeChat Great Again,這次自己也下決心弄一弄。最終還是被我搞出來了O(∩_∩)O哈!

已經用了很長時間了,沒有被封號!

需要準備的東西
dumpdecrypted 砸殼用
yololib 注入需要用到
class-dump 獲取頭文件用到,用于分析代碼
iOSOpenDev
iTools或者pp助手等
OpenSSH(通過越獄手機Cydia安裝)
Cycript(通過越獄手機Cydia安裝)
Command Line Tools
reveal(查看應用運行界面)
hopper(查看二進制文件,用于分析代碼)
Xcode
蘋果開發者證書或企業證書以及配置文件
一臺越獄的iPhone
微信程序安裝包

一、砸殼

 獲取砸殼后的文件有兩種 :1.自己手動砸殼 2.通過第三方越獄平臺下載已經砸殼的微信(如itools  pp助手等)

手動砸殼:

1.先在越獄軟件上安裝ssh插件OpenSSH ,命令行下和應用交互的插件Cycript

2.讓越獄手機和mac電腦在同一個局域網下(為了能夠通過ssh服務從mac電腦訪問手機)

3.在mac的命令行終端 通過ssh服務登錄手機 輸入ssh root@192.168.80.212(手機ip)。默認情況下的root密碼是alpine。root密碼可以自己修改。

399D152C-81F3-4FCA-9DDF-D351FBE72C13.png

4.在手機上運行微信 , 然后通過獲取運行程序的命令加上管道命令 ps -e | grep WeChat 篩選出WeChat的文件路徑 并做記錄稍后會用到

我這里得到的路徑是 /var/containers/Bundle/Application/D7DA798A-006B-4B9F-AD53-EDF4D52A1BAE/WeChat.app/WeChat(需要自己去獲取)

56D7977B-3E75-4505-98B7-2B1BAFDCD991.png

5.查找到WeChat的Documents路徑,輸入cycript -p WeChat,進入cycript命令狀態

57DAC8A2-AD31-4972-A921-F0C7CAAF85CA.png

6.輸入NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)[0],獲得Documents路徑 并做記錄稍后會用到.(需要微信在運行中,ctrl + d cycript結束命令狀態

這里得到的路徑是 /var/mobile/Containers/Data/Application/B3DFAF56-E8EE-4CAD-A56B-884C21C43049/Documents(需要自己去獲取)

2711B4E5-C657-4FF4-BF00-E760207C0A00.png

7.將dumpdecrypted拷貝到WeChat的Documents目錄下,用于砸殼。將命令行切回Mac os,使用scp命令將文件拷貝到WeChat的Documents目錄下

輸入scp dumpdecrypted.dylib root@192.168.80.212:****Documents目錄

5F78387A-7807-4723-973F-3409D7144C17.png

8.重新通過ssh服務登錄手機,開始砸殼

使用命令 DYLD_INSERT_LIBRARIES=/Documents路徑dumpdecrypted.dylib 可執行文件路徑
 在我的手機(ios9.3.2)上執行以上命令的時候出現了以下錯誤:

Killed: 9

189F2AC1-1B83-4D33-9DF7-57792510C5EB.png

查了一下資料說要在mobile模式下運行以上命令,然后我再次執行,出現如下錯誤
Failed opening: Permission denied

31692734-D1E3-424A-8A14-F2BECC80DAAA.png

八九個月以前 就是這個錯誤阻擋我前進的 但是我不甘心 經過反復嘗試 使用下面的方法砸殼成功

cd到Documents目錄下 以mobile身份執行命令
DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib WeChat可執行文件目錄。 終于成功了


EB4A14E5-720B-48F8-853C-DC836780271A.png

命令會在當前目錄下生成砸殼后的的文件 WeChat.decrypted

B0619C85-E3CA-4089-8A53-24FB113F15A9.png

9.將WeChat.decrypted拷貝到Mac電腦上

scp root@192.168.80.212:/var/mobile/Containers/Data/Application/B3DFAF56-E8EE-4CAD-A56B-884C21C43049/Documents/WeChat.decrypted ./ (拷貝到當前目錄)

918C6A80-4C07-4040-870B-29B06403B896.png

檢查砸殼是否成功 otool -l WeChat.decrypted | grep -B 2 crypt 。 cryptid 0表示成功 cryptid 1表示未成功 我的手機是5s,arm64中的cryptid是0 代表砸殼成功

54FCCBEF-9FA2-4A68-BDC0-841E74D94C4E.png

10.將WeChat.app拷貝出來待使用

 這里拷貝的時候要使用  scp -r 

scp -r root@192.168.80.212:/var/containers/Bundle/Application/D7DA798A-006B-4B9F-AD53-EDF4D52A1BAE/WeChat.app ./

二、注入

一.安裝iOSOpenDev

http://iosopendev.com/download/

xcode8及以上直接安裝會出錯 解決辦法:
如果你們也遇到類似的問題,可以嘗試下載iOSOpenDev_Patches,然后按照如下步驟:

1、

把Specifications1文件夾重命名為Specifications放到/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/

2、

把Specifications2文件夾重命名為Specifications放到/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/

3、

把usr3重命名為usr放到/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/

4、

安裝iOSOpenDev

二、生成dylib文件

 新建項目的時候選擇Cocoa Touch Library,項目名為 autoGetRedEnv
6986DB9C-EE6F-46BC-B03E-73E5AAA232E7.png

從github中下載autoGetRedEnv工程源碼中的CaptainHook.h和autoGetRedEnv.mm拷貝源碼,復制到工程中對應文件中,完成后進行編譯,即可得到libautoGetRedEnv.dylib文件。.mm文件里面搶紅包的方法需要做修改,因為搶紅包的方法已經改變。 不再是hook微信的AsyncOnAddMsg: MsgWrap:方法 然后調用打開紅包的的方法 那么簡單

新的自動獲取紅包的方法:

hook微信的AsyncOnAddMsg: MsgWrap: ,在這個方法中調用接收紅包的方法 ReceiverQueryRedEnvelopesRequest


CHMethod(2, void, CMessageMgr, AsyncOnAddMsg, id, arg1, MsgWrap, id, arg2) {
    CHSuper(2, CMessageMgr, AsyncOnAddMsg, arg1, MsgWrap, arg2);
    
    NSUInteger m_uiMessageType = [arg2 m_uiMessageType];
    
    id m_nsFromUsr = [arg2 m_nsFromUsr];
    id m_nsContent = [arg2 m_nsContent];
    
    switch(m_uiMessageType) {
            
        case 49: {
            id logicMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("WCRedEnvelopesLogicMgr")];
            id contactManager =[[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("CContactMgr")];
            id selfContact = [contactManager getSelfContact];
            id m_nsUsrName = [selfContact m_nsUsrName];
            
            if ([m_nsFromUsr isEqualToString:m_nsUsrName]) {//不搶自己的紅包
                return;
            }
            
            if ([m_nsContent rangeOfString:@"wxpay://"].location != NSNotFound) {
                if (!kZTConfig.isAutoGrapEnv) {
                    return;
                }
                
                NSString *nativeUrl = m_nsContent;
                NSRange rangeStart = [m_nsContent rangeOfString:@"wxpay://c2cbizmessagehandler/hongbao"];
                if (rangeStart.location != NSNotFound) {
                    NSUInteger locationStart = rangeStart.location;
                    nativeUrl = [nativeUrl substringFromIndex:locationStart];
                }
                
                NSRange rangeEnd = [nativeUrl rangeOfString:@"]]"];
                if (rangeEnd.location != NSNotFound) {
                    NSUInteger locationEnd = rangeEnd.location;
                    nativeUrl = [nativeUrl substringToIndex:locationEnd];
                }
                
                NSString *naUrl = [nativeUrl substringFromIndex:[@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao?" length]];
                
                NSArray *parameterPairs =[naUrl componentsSeparatedByString:@"&"];
                
                NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithCapacity:[parameterPairs count]];
                for (NSString *currentPair in parameterPairs) {
                    NSRange range = [currentPair rangeOfString:@"="];
                    if(range.location == NSNotFound)
                        continue;
                    NSString *key = [currentPair substringToIndex:range.location];
                    NSString *value =[currentPair substringFromIndex:range.location + 1];
                    [parameters SafetySetObject:value forKey:key];
                }
                
                //紅包參數...
   
                NSLog(@"dictParam=%@", dictParam);
                ((void (*)(id, SEL, NSMutableDictionary*))objc_msgSend)(logicMgr, @selector(ReceiverQueryRedEnvelopesRequest:), dictParam);
                
                return;
            }
            
            break;
        }
        default:
            break;
    }
}

再hook OnWCToHongbaoCommonResponse 方法,在這個方法中再去調用 打開紅包的方法 OpenRedEnvelopesRequest

CHDeclareClass(WCRedEnvelopesLogicMgr);

CHOptimizedMethod2(self, void, WCRedEnvelopesLogicMgr, OnWCToHongbaoCommonResponse, id, arg1, Request, id, arg2) {
    
    CHSuper2(WCRedEnvelopesLogicMgr, OnWCToHongbaoCommonResponse, arg1, Request, arg2);
    
    if ([ZTUserDefaults boolForKey:kZTAutoGrapEnvKey]) {
        if ([NSStringFromClass([arg1 class]) isEqualToString:@"HongBaoRes"]) {
            NSData *data = [[arg1 retText] buffer];
            
            if (nil != data && 0 < [data length]) {
                NSError* error = nil;
                id jsonObj = [NSJSONSerialization JSONObjectWithData:data
                                                             options:NSJSONReadingAllowFragments
                                                               error:&error];
                if (nil != error) {
                    NSLog(@"error %@", [error localizedDescription]);
                }
                else if (nil != jsonObj)
                {
                    if ([NSJSONSerialization isValidJSONObject:jsonObj]) {
                        if ([jsonObj isKindOfClass:[NSDictionary class]]) {
                            id idTemp = jsonObj[@"timingIdentifier"];
                            if (idTemp) {
                                NSMutableDictionary *params = [[ZTUserDefaults objectForKey:ZTParamKey] mutableCopy];
                                [ZTUserDefaults setObject:[NSMutableDictionary dictionary] forKey:ZTParamKey];
                                [params SafetySetObject:idTemp forKey:@"timingIdentifier"]; // "timingIdentifier"字段
                                
                                // 防止重復請求
                                if (params.allKeys.count < 2) {
                                    return;
                                }
                                
                                id logicMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("WCRedEnvelopesLogicMgr")];
                                //延遲1秒搶紅包
                                dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC);
                                dispatch_after(delayTime, dispatch_get_main_queue(), ^(void) {
                                    ((void (*)(id, SEL, NSMutableDictionary*))objc_msgSend)(logicMgr, @selector(OpenRedEnvelopesRequest:), params);
                                });
                            }
                        }
                    }
                }
            }
        }
    }
}

為了減少被封號的幾率 在前紅包的時候 不要去搶自己的紅包 不要重復去搶紅包 必要的可以加上搶紅包的延時

修改微信步數

#pragma mark - WCDeviceStepObjectCHDeclareClass(WCDeviceStepObject)////修改步數CHOptimizedMethod(0, self, unsigned long, WCDeviceStepObject, m7StepCount) {    return 6666;
}

CHOptimizedMethod(0, self, unsigned long, WCDeviceStepObject, hkStepCount) {    return 6666;

}

__attribute__((constructor)) static void entry()
{
    // 微信步數    CHLoadLateClass(WCDeviceStepObject);    CHHook(0, WCDeviceStepObject, m7StepCount);    CHHook(0, WCDeviceStepObject, hkStepCount);   
}

防止消息撤回 撤回消息的時候會調用onRevokeMsg 方法,我們hook這個方法 讓它什么都不做


CHDeclareClass(CMessageMgr);
CHOptimizedMethod(1, self, void, CMessageMgr, onRevokeMsg, id, value1) {   
}

__attribute__((constructor)) static void entry(){    //加載CMessageMgr類
    CHLoadLateClass(CMessageMgr);
    // 消息防撤回
    CHHook(1, CMessageMgr, onRevokeMsg);  
}

我們還可以在設置界面中加入控制開關哦 微信中的設置頁面是 NewSettingViewController 我們可以在里面添加兩個cell來控制 搶紅包的開關 以及設置步數。在設置頁面中的cell類是MMTableViewSectionInfo 通過hopper可以看到里面有很多創建cell的方法 這里我們會用到下面兩個方法。對于步數的保存以及紅包開關的控制,使用一個單利類來保存

EA14B06C-B893-4E99-A177-BD7740DB3DCF.png

//添加搶紅包以及修改步數選擇
CHDeclareClass(NewSettingViewController)

CHOptimizedMethod0(self, void, NewSettingViewController, reloadTableData) {
    CHSuper0(NewSettingViewController, reloadTableData);
    MMTableViewInfo *tableInfo = [self valueForKey:@"m_tableViewInfo"];
    MMTableViewSectionInfo *sectionInfo = [objc_getClass("MMTableViewSectionInfo") sectionInfoDefaut];
    
    MMTableViewCellInfo *autoGrapRedEnvCellInfo = [objc_getClass("MMTableViewCellInfo")
                                                   switchCellForSel:@selector(autoGrabEnvSwitchAction:)
                                                   target:kZTConfig
                                                   
                                                   title:@"自動搶紅包"
                                                   
                                                   on:kZTConfig.isAutoGrapEnv];
    [sectionInfo addCell:autoGrapRedEnvCellInfo];
    
    MMTableViewCellInfo *setpCell = [objc_getClass("MMTableViewCellInfo") editorCellForSel:@selector(handleStepCount:)
                                                                                    target:kZTConfig
                                                                                       tip:@"請輸入步數"
                                                                                     focus:NO
                                                                                      text:[NSString stringWithFormat:@"%ld", (long)kZTConfig.stepCount]];
    [sectionInfo addCell:setpCell];
    
    [tableInfo insertSection:sectionInfo At:0];
    MMTableView *tableView = [tableInfo getTableView];
    [tableView reloadData];
}

編譯得到libautoGetRedEnv.dylib文件

三、注入dylib

 1.將WeChat.decrypted  改名為WeChat,然后通過**yoyolib**向**WeChat**注入**dylib**

****./yololib 目標可執行文件 需注入的dylib。注入成功如下所示****

059F5C48-C8A2-4706-A373-27A023CFCE3D.png

三、重新簽名打包

新建Entitlements.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>application-identifier</key>
<string>證書id.com.xx.xx</string>
<key>aps-environment</key>
<string>production</string>
<key>com.apple.developer.team-identifier</key>
<string>證書id</string>
<key>get-task-allow</key>
<false/>
</dict>
</plist>

當中所需要的信息 可以從以往的項目的app中得到
/opt/iOSOpenDev/bin/ldid -e ./Demo.app/Demo

2.下載配置文件

從開發者網站下載一個與上面plist相匹配的配置文件,并命名為embedded.mobileprovision

3.將四個文件,放入到之前備份好的WeChat.app文件夾中:
1.embedded.mobileprovision
2.libautoGetRedEnv.dylib
3.注入libautoGetRedEnv.dylib后的WeChat文件
4.Entitlements.plist

這里需要注意 .plist文件 embedded.mobileprovision 以及打包需要的證書 這三個需要對應 不然打包會失敗,無論嘗試多少次 都會失敗

4.重新給微信程序簽名
codesign -f -s 證書名字 目標文件
具體操作步驟

codesign -f -s "iPhone Developer:xxxxx" WeChat.app/libautoGetRedEnv.dylib
codesign -f -s "iPhone Developer:xxxxx" WeChat.app/Watch/WeChatWatchNative.app/PlugIns/WeChatWatchNativeExtension.appex
codesign -f -s "iPhone Developer:xxxxx" WeChat.app/Watch/WeChatWatchNative.app
codesign -f -s "iPhone Developer:xxxxx" WeChat.app/PlugIns/WeChatShareExtensionNew.appex
codesign -f -s "iPhone Developer:xxxxx" --entitlements Entitlements.plist WeChat.app

打包成ipa
給微信重新簽名后,我們就可以用xcrun來生成ipa了,具體實現如下:
xcrun -sdk iphoneos PackageApplication -v WeChat.app -o ~/WeChat.ipa
如果不想手動那樣麻煩的操作的話 還可以使用簽名的工具進行簽名 我使用的是ios app signer

81E5DCF6-8FCC-4B9E-BDDA-8BA0EF4C8DEB.png

打包出WeChat.ipa 然后使用itools安裝到手機上

AE75B962-0D48-4C6E-9710-45CA1E8A6023.png

直接上效果

自動搶紅包

198F81BB-EFDB-439F-AAC1-B8F0E3399A2B.png

防止群消息撤回

27C473B4-9407-4235-B473-3C4718FD60B3.png

修改步數

324B1D90-0CA4-4D66-A92A-FB8A97709EBE.png

自動搶紅包開關以及設置步數

71508837055_.pic.jpg

源碼在這里

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,480評論 2 379

推薦閱讀更多精彩內容