iOS逆向开发先导篇-我是这么调试开发的
今天在整理东西的时候,无意间发现一个逆向微信的功能清单,想起来原来自己曾经学过一些iOS逆向工程的皮毛知识。

虽然答应了朋友最终没实现,但我还是想分享下我的经验和想法,最后顺便再看看【微信群id】长什么样子的。
话不多说,开启本文的主旨:iOS逆向开发的先导篇-调整编写之前的准备。
现在网上太多有关逆向向微信的帖子了。我总不能和他们一样,也是说说什么是逆向,什么是tweak之类的,这也太入俗套了。本文的顺序是:
1.要逆向微信,首先考虑的是如何注入我们编写的动态库和重签名,所以先从编写脚本脚本;
2.如何利用xcode调试和执行脚本在非越狱手机上安装微信;
- 编写调整代码,生成动态库,来点实在的功能,如:防重启等功能;
4.整理下工具以供开发使用。
编写脚本
#!/bin/bash
# 利用开发者证书申请一个 id
BUNDLEIDENTIFIER=com.meishu.ye
APPLICATIONIDENTIFIER=***.${BUNDLEIDENTIFIER}
WECHATFILEPATH=/Users/****/git/jailbreak/6.5.3/WeChat2
install_name_tool -change /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate @loader_path/libsubstrate.dylib ./Debug-iphoneos/bot.dylib
ls
ORIGINDIR=$(pwd)
cp ./Debug-iphoneos/bot.dylib bot.dylib
cp ./libsubstrate.dylib libsubstrate.dylib
cp ./FontAwesome.otf FontAwesome.otf
cp ./WechatIMG1.png WechatIMG1.png
LIBNAME=$(find bot.dylib)
LIBSUBNAME=$(find libsubstrate.dylib)
FONTNAME=$(find FontAwesome.otf)
WECHATIMG1=$(find WechatIMG1.png)
# $(find *.dylib)
TEMPDIR=$(mktemp -d)
# 0.get argv
if [ x$1 != x ]
then
BUNDLEIDENTIFIER=$1
fi
# 1.unzip ipa
unzip -qo ${WECHATFILEPATH}/WeChat.ipa -d $TEMPDIR
# 2.copy files
cp ${WECHATFILEPATH}/embedded.mobileprovision $TEMPDIR/
cp ${WECHATFILEPATH}/entitlements.plist $TEMPDIR/
cp ${LIBNAME} $TEMPDIR/
cp ${LIBSUBNAME} $TEMPDIR/
cp ${FONTNAME} $TEMPDIR/
cp ${WECHATIMG1} $TEMPDIR/
# 2.1 rm origin WeChat 1月22日 begin
# rm $TEMPDIR/Payload/WeChat.app/WeChat
# cp ${WECHATFILEPATH}/WeChat $TEMPDIR/Payload/WeChat.app/
# 2.1 rm origin WeChat 1月22日 end
# 3.resign
cd $TEMPDIR
plutil -replace application-identifier -string ${APPLICATIONIDENTIFIER} entitlements.plist
plutil -replace CFBundleIdentifier -string ${BUNDLEIDENTIFIER} Payload/WeChat.app/Info.plist
mv ${FONTNAME} Payload/WeChat.app/
mv ${LIBNAME} Payload/WeChat.app/
mv ${LIBSUBNAME} Payload/WeChat.app/
#${WECHATFILEPATH}/insert_dylib --all-yes @executable_path/${LIBSUBNAME} Payload/WeChat.app/WeChat
#mv Payload/WeChat.app/WeChat_patched Payload/WeChat.app/WeChat
#chmod +x Payload/WeChat.app/WeChat
${WECHATFILEPATH}/insert_dylib --all-yes @executable_path/${LIBNAME} Payload/WeChat.app/WeChat
${WECHATFILEPATH}/optool install -c load -p @executable_path/${LIBNAME} -t Payload/WeChat.app/WeChat
mv Payload/WeChat.app/WeChat_patched Payload/WeChat.app/WeChat
chmod +x Payload/WeChat.app/WeChat
rm -rf Payload/WeChat.app/_CodeSignature
rm -rf Payload/WeChat.app/PlugIns
rm -rf Payload/WeChat.app/Watch
cp embedded.mobileprovision Payload/WeChat.app/
codesign -fs "iPhone Developer: **** (****)" --no-strict --entitlements=entitlements.plist Payload/WeChat.app/${LIBSUBNAME}
codesign -fs "iPhone Developer: **** (****)" --no-strict --entitlements=entitlements.plist Payload/WeChat.app/${LIBNAME}
codesign -fs "iPhone Developer: **** (****)" --no-strict --entitlements=entitlements.plist Payload/WeChat.app
# 4.end
rm -rf ${ORIGINDIR}/WeChat.app
mv Payload/WeChat.app ${ORIGINDIR}
rm -rf ${TEMPDIR}
解释:
1.我们只是为了学习,逆向一些APP,所以没必要去越狱我们的iPhone手机,所以这里的最主要目标就是不越狱的情况下逆向微信功能;
2.如果没有没有越狱手机,最好的方法是通过某助手下载破解的微信APP,如本文中用到的是6.5.3版本;
- 最核心就是被替换依赖的名字。简单的做成把原来的libsubstrate.dylib替换为带路径的版本,第三个参数是要修改的替换文件名称,如此处的注入文件:bot.dylib。有关的更多功能,可参考链接:
install_name_tool
install_name_tool
http://www.unix.com/man-page/osx/1/安装名称工具/
4. plutil命令的作用是替换到原有的embedded.mobileprovision和entitlements.plist替换成自己的.plutil命令格式:5.利用insert_dylib工具注入动态库和依赖库; 6.删除多余的文件:,,,以免注入失败;7.最后就是利用codesign命令来为微信中的相关文件签名,签名完后的写入文件就可以顺利安装到非越狱手机上了
_CodeSignature
PlugIns
Watch
xcode调试
太懒的写字了,直接看图,主要有三个步骤来生成破解的WeChat APP,安装到手机上进行调试:

1.创建WeChat同名工程,用于多次编译和运行时生成WeChat.app;
2。在构建阶段中设置目标依赖项,增加dylib,只要每次运行都会先编译最新的动态库;
3.在运行脚本中增加一条脚本将我们上面写的副本复制过来;
4.运行微信。这里需要将第3步的生成的WeChat.app替换掉第1步的。

运行结果,就可以在所有输出上看到所有运行的日志了:


有了log,编写tweak动态链接库代码就可以调试了。同时安装了两个微信已经是傻傻分不清了。
编写调整
工欲善其事,必先利其器。看看我的利器吧:


有利器了,我们就可以编写tweak代码了。如果说只是为了如何创建和编写tweak代码,相信有很多网上教程注意到参考的。这里就不再多余述了,可见文末的推荐。
编写第一个hook函数:
// 防撤销
- (void)DelMsg:(id)arg1 MsgWrap:(CMessageWrap *)wrap {
NSLog(@"CMessageMgr:DelMsg:arg1:%@, MsgWrap:%@", arg1, wrap);
BOOL isMesasgeFromMe = NO;
CContactMgr *contactManager = [[objc_getClass("MMServiceCenter") defaultCenter] getService:[objc_getClass("CContactMgr") class]];
CContact *selfContact = [contactManager getSelfContact];
if ([[wrap m_nsFromUsr] isEqualToString:[selfContact m_nsUsrName]]) {
%orig;
}
}
- (void)DelMsg:(id)arg1 MsgList:(id)arg2 DelAll:(BOOL)arg3 {
NSLog(@"CMessageMgr:DelMsg:arg1:%@, MsgList: %@, DelAll: %d", arg1, arg2, arg3);
BOOL isMesasgeFromMe = NO;
CContactMgr *contactManager = [[objc_getClass("MMServiceCenter") defaultCenter] getService:[objc_getClass("CContactMgr") class]];
CContact *selfContact = [contactManager getSelfContact];
for (CMessageWrap* wrap in arg2) {
if ([[wrap m_nsFromUsr] isEqualToString:[selfContact m_nsUsrName]]) {
isMesasgeFromMe = YES;
break;
}
}
if(isMesasgeFromMe || arg3) {
%orig;
}
}


工具篇
- 料斗拆卸器v3
Hopper是OS X和Linux的逆向工程工具,可让您反汇编和反编译32/64位Intel Mac,Linux,Windows和iOS可执行文件!请查看功能列表!
Hopper是一种在Mac,Windows和Linux下的调试(仅OS X),反汇编和反编译的互补工具。可以对32、64位的Mac,Windows,和iOS应用进行调试,反编译等。
只要将WeChat二进制文件拖到Hopper Disassembler就可以了,我们可以在左边看到很亲切的Objective-C语法的方法列表,我们可以搜索想要了解的函数或者类,这里很明显;中间是每个函数的汇编语言吧,虽然我的汇编学的还不错,但我还是喜欢看代码,比较亲切。如下图的[CMessageWrap nativeUrl]
方法。

- insert_dylib
用于将dylib加载命令插入Mach-O二进制文件的命令行实用程序。
我们需要利用命令将我们写的动态库bot.dylib和依赖库libsubstrate.dylib注入到WeChat.app/WeChat目标二进制文件中,最后生成WeChat.app/WeChat_patched。最后只需替换生成的文件替换为WeChat。 app / WeChat即可。 insert_dylib
insert_dylib github:
https://github.com/Tyilo/insert_dylib
- 操作工具
optool是一种与MachO二进制文件交互的工具,用于插入/删除加载命令,剥离代码签名,辞职和删除aslr。下面是它的帮助。
optool github:
https://github.com/alexzielenski/optool
总结
本文是iOS逆向开发的先导篇,通过一些工具和xcode来调试开发tweak,为下一步的具体开发做好铺垫。
推荐👇:
作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:789143298 ,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!
申请即送:
-
BAT大厂面试题、独家面试工具包,
-
资料免费领取,包括 数据结构、底层进阶、图形视觉、音视频、架构设计、逆向安防、RxSwift、flutter,