本篇文章创建在上篇博客 :shell
iOS逆向 - 应用签名原理及重签名 (重签微信应用实战) 的基础知识之上的 , 不了解的同窗欢迎去阅读 . 本篇会讲述如何利用 shell
脚本自动重签名和应用调试 .数据库
若是篇幅不过长的话 , 咱们再来玩一玩代码注入 .bash
另外 笔者使用的是 Xcode 11
, 因此 Xcode 新版本目前没发现有问题 . 同样玩 .微信
这里之因此要用 Xcode
来作一次重签 , 有如下几个目的 :app
利用 Xcode
重签的原理和上篇博客中基本同样 ( 由于咱们也提到过 , Xcode
自己也就是利用 codeSign
来作的 ) , 所以 , 我这边快速过一遍 , 不过多讲述了 .函数
之因此要用同名工程 , 由于是有一些坑的 .工具
( 不使用同名工程时 , 每次 build
会从新建立一个 Mach-O
, 也就是说此时你就算更换了包 , 可是这个包里有两个 Mach-O
, 而运行的还会是你本身的空工程 , 因此在咱们已经下载到 ipa
看获得包里的 Mach-O
的状况下 , 咱们就起和它同样的名字就好 )post
ok , 新建工程 , 选择开发者 , 选择真机 , 直接 run
.ui
run
成功以后查看生产的 app
包spa
看完前面一篇博客的同窗应该都清楚 , 这一步是为了把描述文件安装到手机里 .
找到以前从pp助手里下载好的 已经砸过壳的微信应用包 , 直接替换.
这一步跟咱们以前本身纯手动操做同样 .
打开 WeChat
, 显示包内容 . 找到 PlugIns
文件夹, 直接删除 插件普通帐号是签不了的 .
找到 Watch
文件夹 , 由于这里也有插件 , 咱们暂时不须要 Watch
, 直接删掉 .
进入 FrameWork
文件夹
利用 CodeSign
, 使用咱们的证书进行重签名.
codesign -fs "复制的你本身的证书名字" 要重签的FrameWork名称
复制代码
例如:
codesign -fs "iPhone Developer: ha ha (123456)" andromeda.framework
复制代码
把 FrameWork
文件夹下全部的库所有重签.
这个时候 App 包里的Bundle ID 仍是微信的 ,可是咱们先不改 , 直接运行 .
注意看本来咱们的空工程 , 在手机上已经安装上了微信的包 ,
那么你再去查看微信包里的 Info.plist
里的 Bundle ID
, 已经被自动替换成咱们的包名了 .
那么对比一下咱们纯手写的重签 , 这个显然更加简单且实用 . 可是每次重签都这么搞一下也不太合适 , 当咱们理解了重签原理以后 , 就没有必要每次这么搞了 .
并且我也不必定能保证我确实是同名工程 , 我但愿我随便叫什么名字均可以重签 .
ok. 进入 Shell
部分 .
为了统一你们前导知识的前提 , 咱们仍是先来介绍下 SHELL
脚本 , 已经熟悉的同窗能够自行跳过 .
Shell
是一种特殊的交互式工具,它为用户提供了启动程序、管理文件系统中文件以及运行在系统上的进程的途径。
Shell
通常是指命令行工具。它容许你输入文本命令,而后解释命令,并在内核中执行。
Shell
脚本,也就是用各种命令预先放入到一个文本文件中,方便一次性执行的一个脚本文件。
简单来讲 , 你们能够理解为咱们平时在 终端
/ iTerm2
中写的命令的集合 . 固然 , 它就必不可少的设计到环境变量和权限等问题 .
在
MAC
系统中 , 默认使用的shell
是bash
. 咱们使用iTerm
的时候 , 常常会配置另外一个shell
叫zsh
. 固然 , 还有一些其余的shell
.咱们须要知道的是
bash
的初始化文件是家目录下的.bash_profile
zsh
的初始化文件一样是家目录下的.zshrc
. 里面配置了一些环境变量.
例如咱们常常有如下操做 :
mkdir test
cd test
touch 123.txt
cd ..
复制代码
那么咱们想将这些指令打包在一块儿 , 统一运行 . 相似于数据库中事务同样 .
输入命令 :
vi 123.sh
复制代码
输入文件内容:
mkdir test
cd test
touch 123.txt
复制代码
好 , 此时 咱们已经生成了一个最简单的脚本 123.sh
.
那么如何执行呢 . 方法有不少种
MAC
自带的 bash
shell
:bash 123.sh
复制代码
脚本执行完 , 咱们的文件也建立好了 .
zsh
zsh 123.sh
复制代码
source
source 123.sh
复制代码
./
./123.sh
复制代码
注意 :
source
执行完以后停留在子目录里 .
./
可能会报没有执行权限的问题 . +x
便可
$source FileName
shell
环境中读取并执行 FileName
中的命令$bash FileName
/ $zsh FileName
shell
,在子 shell
中执行脚本里面的句子。$./FileName
名称随意 , 新建完毕选择开发者 . 证书
复制代码
运行一下空工程 ( 将描述文件安装到手机上 )
APP
文件夹 , 也能够起其余名称 , 与 Shell
脚本中的文件名对应起来就能够.ipa
放入 APP
文件夹中.
能够看到他默认使用的是 sh
的 shell
.
固然 你们能够先随便写点 而后 build
一下看看有没有执行.
开始编写脚本 :
# ${SRCROOT} 它是工程文件所在的目录
TEMP_PATH="${SRCROOT}/Temp"
#资源文件夹,咱们提早在工程目录下新建一个APP文件夹,里面放ipa包
ASSETS_PATH="${SRCROOT}/APP"
#目标ipa包路径
TARGET_IPA_PATH="${ASSETS_PATH}/*.ipa"
#清空Temp文件夹
rm -rf "${SRCROOT}/Temp"
mkdir -p "${SRCROOT}/Temp"
#----------------------------------------
# 1. 解压IPA到Temp下
unzip -oqq "$TARGET_IPA_PATH" -d "$TEMP_PATH"
# 拿到解压的临时的APP的路径
TEMP_APP_PATH=$(set -- "$TEMP_PATH/Payload/"*.app;echo "$1")
# echo "路径是:$TEMP_APP_PATH"
#----------------------------------------
# 2. 将解压出来的.app拷贝进入工程下
# BUILT_PRODUCTS_DIR 工程生成的APP包的路径
# TARGET_NAME target名称
TARGET_APP_PATH="$BUILT_PRODUCTS_DIR/$TARGET_NAME.app"
echo "app路径:$TARGET_APP_PATH"
rm -rf "$TARGET_APP_PATH"
mkdir -p "$TARGET_APP_PATH"
cp -rf "$TEMP_APP_PATH/" "$TARGET_APP_PATH"
#----------------------------------------
# 3. 删除extension和WatchAPP.我的证书无法签名Extention
rm -rf "$TARGET_APP_PATH/PlugIns"
rm -rf "$TARGET_APP_PATH/Watch"
#----------------------------------------
# 4. 更新info.plist文件 CFBundleIdentifier
# 设置:"Set : KEY Value" "目标文件路径"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $PRODUCT_BUNDLE_IDENTIFIER" "$TARGET_APP_PATH/Info.plist"
#----------------------------------------
# 5. 给MachO文件上执行权限
# 拿到MachO文件的路径WeChat
APP_BINARY=`plutil -convert xml1 -o - $TARGET_APP_PATH/Info.plist|grep -A1 Exec|tail -n1|cut -f2 -d\>|cut -f1 -d\<`
#上可执行权限
chmod +x "$TARGET_APP_PATH/$APP_BINARY"
#----------------------------------------
# 6. 重签名第三方 FrameWorks
TARGET_APP_FRAMEWORKS_PATH="$TARGET_APP_PATH/Frameworks"
if [ -d "$TARGET_APP_FRAMEWORKS_PATH" ];
then
for FRAMEWORK in "$TARGET_APP_FRAMEWORKS_PATH/"*
do
#签名
/usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" "$FRAMEWORK"
done
fi
复制代码
脚本中步骤都有详细注释说明. 那么咱们来总结一下这个脚本作了什么.
其实跟咱们手动重签的步骤是如出一辙的.
1 在工程跟目录中找到
APP
文件夹. 找到里面的后缀为.ipa
的文件路径 , 建立并清空Temp
文件夹 . (以便后面存放解压ipa包的内容)2 将
ipa
解压到Temp
路径中 , 找到其中app
包的路径. ( Palyod 里的 .app 包) 并将解压出来的.app
包拷贝进入工程下 ( 其实就是替换掉工程 build 产生的.app 包)3 删除
PlugIns
和WatchAPP
.4 更新
info.plist
文件CFBundleIdentifier
5 给
MachO
文件上执行权限6 重签名第三方 FrameWorks
( shell
中添加 echo
能够进行打印输出 , 在 build
记录中 )
固然 , 你能够直接在 Run Script Phase
里写完这些 shell
, 也能够写到一个 app.sh
脚本文件中 , 而后在 Run Script Phase
里写一个 ./app.sh
便可 .
若是你遇到
相信你已经知道怎么解决了. 是的 chmod +x app.sh
通常修改原始的程序,是利用代码注入的方式,注入代码就会选择利用 FrameWork
或者 Dylib
等三方库的方式注入。
固然 , 也能够直接修改 Mach-O
文件 , 这个涉及到汇编以及二进制 , 后面会考虑要不要继续解读 .
首先咱们须要知道的是 Mach-O 文件拥有固定的格式 , 而对于 iOS
系统应用来讲 , 须要经过 dyld
去读取 Mach-O
, 从而决定文件包须要加载哪些库 , 如何去加载等等 ,
后续我会专门讲一讲 Mach-O
文件 以及 dyld
连接流程 和 符号表的一些内容.
使用 MachOView
可视化预览 Mach-O
文件内容 ( otools 命令也能够 ) .
那么所以 , 咱们能够思考 :
若是我能够修改 Mach-O
文件的 Load Commands
( 加载指令 , 就是告诉 dyld
如何去加载 ) , 往其中添加一条 , 添加一条指令让其去加载 咱们本身生成的 framework
, 是否可行呢 .
答案是确定的 .
准备好已经重签完的工程 或者上述 准备好了 shell
和 ipa
的工程.
File - New - Target
选 Cocoa Touch Framework
, 我这里取名 LBHook
在 .m
文件中写 load
方法 .
熟悉 load
方法机制的同窗都知道 , load
方法是在 main
函数以前 , dyld
加载 _objc_init
时就会调用的. ( 不清楚的同窗能够去阅读一下 iOS load方法调用机制解析 这篇文章 )
编译后打开包内容 , 查看 Frameworks 文件夹 , 能够看到咱们的 framework 已经放进去了 .
可是没用啊 , 微信的 Mach-O
的 加载指令 load Commands
里并不会去加载个人这个库 .
给当前 Mach-O
添加指令 让其加载咱们的 framework
. 这里要使用一个工具 yololib 提取码 : wxvv
下载完毕后 , 将其复制到 usr/local/bin
中 , 这样环境变量就能够在任意路径下使用 yololib
了.
随便找一个 Mach-O
文件 , go2shell
, 或者手动 cd
到这个目录.
yololib Wechat Frameworks/你的framework名称路径/你的framework
yololib Wechat Frameworks/LBHook.framework/LBHook
framework
路径是至关于前面 macho
文件的路径 .修改完毕后能够利用 MachOView 来看下咱们的加载指令添加进去了没.
Mach-O
, 让其加载咱们的 framework
.APP
路径下的 ipa
包 , 改成 zip
, 解压 , Payload
里的包 , 显示包内容 , 找到 Mach-O
.yololib Wechat Frameworks/LBHook.framework/LBHook
zip -ry Wechat.ipa Payload
( 其实不从新压缩也能够 跟咱们 shell
脚本里对应起来就行了 ) .cmd + r
运行 . 看控制台打印
那么既然咱们能够注入代码 . 那咱们能够作什么 ?
给个思路 :
能够注入代码 , 咱们就能够
hook
微信的方法 . 上一篇文章我提到过view Debug
, 咱们是能够看获得点击登陆
/注册
的时候 , 调用的具体是什么方法的 . 又有黑魔法的存在 , 咱们能够作的不少 . 你们本身去玩 .
load commands
咱们是使用手动注入的 . 其实咱们在把 yololib
环境变量配置好以后 , 彻底能够在以前的 shell 脚本里作注入 .
- 上面
shell
脚本中最后一行 加上yololib "$TARGET_APP_PATH/$APP_BINARY" "Frameworks/HankHook.framework/HankHook"
- framework 的名称注意去修改就行
- 这样的话 , 咱们作重签名和代码注入只须要 新建个空工程 运行 , 而后下载完微信的
ipa
, 根目录新建个APP
文件夹 , 放进去运行便可.
有些工具作代码注入的是 Library
就是 dylib
的库 , 其实它的原理和咱们注入 framework
是同样的 , 只不过步骤上略有不一样.
咱们就使用 shell
简单带过一下.
另外 , iOS
如今已经不能添加 dylib
,只能从 macOS
添加
一样是准备好已经重签完的工程 或者上述 准备好了 shell
和 ipa
的工程 .
File - New - Target
选 macOS
- Library
, 我这里取名 LBHookDylib
Build Settings
, 选择 target
, 找到 Base SDK
, 选择 iOS
.
Code Sign Identity
, 选择 iOS
的证书
Build Phases
, 切换为主工程的 target
, 新建 Copy Files
Destination
选择 Frameworks
shell
脚本中最后一行多加一句
yololib "$TARGET_APP_PATH/$APP_BINARY" "Frameworks/libLBHookDylib.dylib"
运行 , 代码注入成功 .