1. 应用签名
- 应用签名原理回顾
上一篇博客“IOS 逆向开发(三)应用签名”中详细讲解了IOS 应用签名,证书的原理。本篇博客主要以实战为主,讲解具体如果绕过苹果证书签名,给App重签名,然后可以让我们的app可以任意安装到手机。
- 接下来,我将用3种方式来实现对app 的重签名。
2. App 重签名 3 种方式
- 其实我们最终签名app都是使用codesign工具,苹果也是用xcode集成了这个工具而已。这个工具为我们做了很多事情,而我们只需要敲几个命令就可以完成重签名工作。一切看起来都so easy!!!
- 那么,接下来,我们将用三种不同的方式来重签名App. 我们使用免费证书来重签名App.
2.0 签名前准备工作
- 我们重签名APP,这里签名的App是使用我们每个人都会使用的重磅级app 微信来重签名。我使用的版本是微信7.0.8版本
- 我们可以在mac 上面安装一个叫做PP 助手的工具,这个工具可以下载到你想要的ipa包。其他助手工具也可以,或者你直接冲网上下载。
- 先回顾一下上一篇博客“IOS 逆向开发(三)应用签名”中的开发者证书相关知识。
- 开发者调试安装app到手机的签名过程:
- Mac电脑生成公钥M和私钥M
- 公钥M传给苹果服务器,苹果服务器的私钥A对公钥M进行加密生成证书返回给xcode
- Xcode下载profile等描述文件,用公钥M对app进行加密生成app签名,然后把app签名和证书以及profile文件一起打包成ipa
- 手机进行两次解密,手机用手机系统里的公钥A对证书进行解密得到公钥M,然后对比profile描述文件,查看权限,看是否合法;然后用公钥M对app签名进行解密
手机里的公钥A与苹果服务器私钥A相对应
- 此外还需要了解一些加密和重签名相关的命令:
- base64加密文件:
base64 test.txt -o new.txt
- base64解密:
base64 new.txt -o abc.txt -D
- openssl生成私钥:
openssl genrsa -out private.pem 512
- 由私钥生成公钥:
openssl rsa -in private.pem -out public.pem -pubout
- 查看rsa的明文:
openssl rsa -in private.pem -text -out private.text
- 查看csr解密信息:
openssl asn1parse -i -in CertificateSigningRequest.certSigningRequest
- 查看profile文件信息:
/Users/mac/Library/MobileDevice/Provisioning\ Profiles 然后security cms -D -i e871987c-b4c5-4658-8338-f6e4cabaff8e.mobileprovision
- 查看签名信息:ipa包解压打开,进入Payload,查看.app的签名信息
codesign -vv -d WeChat.app
- 查看所有证书:
security find-identity -v -p codesigning
- 查看可执行文件macho的加密信息:.app显示包内容,找到同名的可执行文件otool -l WeChat | grep crypt
$security find-identity -v -p codesigning
列出钥匙串里可签名的证书$Codesign –fs
“证书串” 文件名 强制替换签名$Chmod +x
可执行文件 给文件添加权限$security cms -D -i ../embedded.mobileprovision
查看描述文件$codesign -fs “证书串” --no-strict --entitlements=权限文件.plist APP包
$Zip –ry 输出文件 输入文件
将输入文件压缩为输出文件
2.1 利用codesign进行重签名
- 首先,我们进入我们下载好的WeChat.app所在的目录,通过命令:
codesign -v -d WeChat.app
来查看一下包的内容
下载的砸核过的越狱应用WeChat 7.0.8信息如下:
我们如果要用codesign这个命令签名,需要在命令后面跟上证书信息。
-
我们先通过命令:
security find-identity -v -p codesigning
来查看mac电脑的证书信息
接下来我们进入WeChat.app 查看包里面的内容:
- 我们通过otool工具来查看WeChat可执行文件内容,终端输入:
otool -l WeChat
:
- 我们还可以把这些信息重定向到txt文本:终端输入命令:
otool -l WeChat > ~/Desktop/123.txt
- 此外我们还可以直接通过命令
otool -l WeChat | grep cry
筛选出想要的cryptid内容:
otool -l WeChat 查出来的内容通过管道输出符,通过grep筛选出 “cry”开头的内容。
cryptid == 0 表示没有进行加密。cryptid == 1表示加密了。这个加密是对称加密,因为需要对整个app包进行加密,是appstore对其进行加密。
- 我们来思考一个问题,是什么时候进行解密?
是安装的时候解密还是运行的时候解密呢,为了安全,必须运行时解密,每次运行都需要重新解密一次。这样虽然会影响运行效率,但是苹果为了安全不得不在运行时每次对APP进行解密操作。
- 没有进行加密的app 无法直接在苹果设备上安装。
2.1.1 手动进行app重签名
前面讲了这么多,都是在做准备工作,现在我们真正开始重签名操作。
-
首先,我们进入WeChat.app目录下面,找到Pluslns目录,因为普通的插件我们是无法签名的,所以必须干掉这些插件。
然后我们找到Watch目录。由于Watch目录下面也有插件,我们也必须干掉。
-
接下来,我们找到Frameworks目录,需要对该目录下的所以.framework文件,用我们自己的证书进行签名操作。
-
我们通过命令行,cd 到WeChat.app/Frameworks/目录下面,通过ls命令查看,有6个framework文件如下:
接下来,我要用我自己的证书:"Apple Development: chen lin (QY73GRZ4AG)" 对 上面6个framework分别进行签名操作。使用命令:
codesign -fs "Apple Development: chen lin (QY73GRZ4AG)" xx框架名称 .framework
进行签名。
-
如上图,这里系统会弹出访问秘钥的输入框,按要求输入,始终允许即可。输入你们自己电脑账号的登录密码即可。允许之后,可以看到如下,签名被替换的消息。
-
我们使用同样的命令,依次对6个framework进行签名。
接下来我们来查看一下可执行文件WeChat,那么我们怎么判断这个可执行文件有权限可以执行呢?
一般我们看这个可执行文件的颜色就可以判断,黑色是可以有执行权限的,白色是没有的。
-
我们现在使用
chmod +x WeChat
命令给整个WeChat.app增加可执行权限。
接下来,我们还需要对WeChat.app增加描述文件。
-
我们通过新建一个demo工程的方式来申请新的一个描述文件。描述文件无法新增,只能通过从苹果服务器申请的方式,新建一个工程,xcode会帮助我们申请。
-
描述文件申请了,但是如果没有连着真机运行,实际上描述文件并没有下载保存到我们的iphone手机中,所以我们还需要command+R运行一下,在真机上联调运行一下。
如果这个证书对应的描述文件是第一次在真机iphone上运行,手机系统会弹出信任对话框,让你信任一下,如果不是第一次,则不会弹框。运行完成后,我们需要的描述文件就进入到了我们的真机iphone中。
-
我们可以从项目WeChatDemo工程的Products/WeChatDemo.app中获取生成的描述文件。
-
得到描述文件后,我们用Command + C 复制这个embedded.mobileprovision描述文件,并Command+V粘贴到微信的WeChat.app目录下面。这样我们就给微信app增加了一个我们自己的描述文件。
-
描述文件拷贝到WeChat.app后,我们还需要修改WeChat.app里面的info.plist里面的描述文件配置,需要bundle identifier 保持一致。
接下来,我们还需要签名整个WeChat.app包,对WeChat.app签名就需要用到我们刚刚申请的描述文件里面的授权文件了。
我们先把申请的那个描述文件拷贝到WeChat.app同级目录
-
我们通过命令行:
security cms -Di embedded.mobileprovision
查看一下这个描述文件:
描述文件里面有一个非常重要的东西,这个就是我们权限文件的内容:
-
为了使用方便,我们在我们之前创建的那个demo工程里面新建一个plist文件。
-
我们再确认一下plist文件是否拷贝正确:
这样我们就成功从描述文件中提取出了权限文件到新增的kongyuluWechatEnt.plist文件了。
-
然后我们把这个文件拷贝到WeChat.app同级目录下面:
接下来,重要的步骤来了,我们通过命令行,输入命令:
codesign -fs "证书名称" --no-strict --entitlements=kongyuluWechatEnt.plist WeChat.app
codesign -fs "Apple Development: chen lin (QY73GRZ4AG)" --no-strict --entitlements=kongyuluWechatEnt.plist WeChat.app
这样我们就手动签名就大功告成了,这样处理过的WeChat.app就会让苹果手机认为我们的app 是一个正在开发阶段的app,这样就可以将我们的重签名过后的app,直接安装到我们的手机上面去了。
接下来我们可以测试一下,我们重签名过后的WeChat.app是否可以安装到手机上面
-
首先打开我们的xcode ,快捷键Command + Shift +2 调出设备页面
-
选择WeChat.app后,会提示是否需要覆盖安装,选择是
- 手动重签名的步骤有点多,这里再简单归纳总结一下,总共分为9步:
- 新建工程WeChatDemo,选择证书和真机调试
- 进入包内容,因为免费证书无法重签名插件,所以删除PlugIns文件夹,Watch里也有插件,也删除
- 对Frameworks里的framework进行重签名,有些包没有Frameworks就忽略这步:
进入Frameworks 文件夹;然后一个一个的重签名
security find-identity -v -p codesigning //查看所有证书
codesign -fs "iPhone Developer: [email protected] (Q4M32A5HU5)" QYUniversalFramework.framework //选择和工程codesignDemo一样的证书- 给可执行文件执行权限:chmod +x WeChat
- WeChatDemo工程里的Products里的WeChatDemo.app显示包内容,找到包内容里的embedded.mobileprovision文件,拷贝到需要重签名的爱奇艺.app包内容中
- WeChatDemo工程的Bundle identifier拷贝到WeChat.app的包内容中的Info.plist的Bundle identifier
- 找到第五步的embedded.mobileprovision文件,然后security cms -D -i embedded.mobileprovision找到
Entitlements ,然后把Entitlements 下面的:
"dict> 用Xcode生成plist文件PropertyList.plist,然后Open As -> Source Code,把刚才的拷贝进去,得到如下: - 把第7步得到的plist文件,和WeChat.app放在一个文件夹new中,进行重签名
- 安装到手机上
打包为ipa: zip -ry WeChat.ipa new 把new文件夹打包为WeChat.ipa
安装:Xcode command+shift+2进入到设备管理,选择+号找到刚才的WeChat.ipa
2.2 利用xcode进行重签名
- 上面详细介绍了手动重签名的过程,这里有很多小伙伴肯定会有疑惑,我们花这么大代价重签名是为的什么呢?
重签名app至少有这两个好处:
- 重签名后,我们可以通过xcode动态调试那些被我们重签名过后的app.
- 重签名后,我们还可以动态注入我们自己的代码,达到破解的目的。
- 接下来我们将通过xcode来实现重签名。
- (1)我们先打开xcode ,通过快捷键 :“Command + Shift + N”,创建一个新的工程名字叫做WeChat.
- (2) 我们需要先连接真机iphone,将WeChat工程在真机上运行一下。“Command + Shift + R”运行一次。这样可以得到我们需要的描述文件。然后我们需要拷贝现在的官方微信版本替换掉新建工程Products中的WeChat.app
Products/WeChat.app 通过右键Show Finder 可以找到在debug-iphoneos目录下面,直接替换如下图:
-
(3) 替换掉之后,我们并不能直接通过xcode运行到真机上面,我还需要完成几个步骤才行。和手动签名一样,首先我们要删除我们无法签名的插件信息,删除WeChat.app下的Watch目录和 Pluglsn目录
(4)然后,我们还需要对Frameworks目录下面的所以framework进行重签名。
- 这样我们就大功告成了,直接“Command + Shift + R” 运行app,这样重签名的微信就可以运行在我们的真机上面,so easy .
注意:这里我们不需要去修改原始微信.app里面的bundle Id ,xcode运行自动会帮我们改为我们新建工程的bundle id.
- 这里我们对xcode重签名步骤总结一下:
- 新建工程WeChat,选择证书和真机调试
- 把WeChat.app替换WeChat工程的Products的WeChat.app
- 进入替换后的WeChat.app包内容中,删除PlugIns文件夹和Watch文件夹
- 重签名对Frameworks里的framework进行重签名,有些包没有Frameworks就忽略这步
- 改替换后的WeChat.app包中的Info.plist的Bundle identifier改为WeChat工程的Bundle identifier
- 给可执行文件执行权限:chmod +x WeChat
- 运行工程WeChat
注意: 这里如果新建的工程名字和你要签名的app名称不一致,会签名失败,运行的还是你新建工程的那个demo,而不是你想覆盖的微信.app。因为xcode运行时,会自动将可执行文件改为你新建工程的名称。加入我们新建的工程名称叫demo,我们用WeChat.app改名后替换了demo.app,运行的时候会自动运行demo.app而不是WeChat.app. 这样我们需要通过运行脚本的方式,来更加优雅的执行重签名操作。
- 我们下面将讲述通过Shell脚本来重签名。
2.3 利用shell脚本进行重签名
- 新建工程cosignAutoDemo,选择证书和真机调试,在工程根目录里新建APP和Temp文件夹:
- xcode->Build Phases->+New Run Script Phase
- 在Run Script的shell代码如下:
# ${SRCROOT} 它是工程文件所在的目录
TEMP_PATH="${SRCROOT}/Temp"
#资源文件夹
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文件的路径
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
- 在APP文件夹下放ipa包,然后运行.这样就大功告成了,是不是更简单呢?
- 其实,我们也可以把脚本保存成xcodeCodesign.sh文件,然后在Run Script的shell的代码处,写入xcodeCodesign.sh文件的路径;最后要chmod +x xcodeCodesign.sh,就可以运行了。
- 下面将介绍一种更简单的方法,名字叫做第三方,第三方基本上就是傻瓜式的了,安装官方说明就可以完成了。
2.4 利用第三方工具 MonkeyDev重签名
- MonkeyDev安装,点击这里下载
- 新建MonkeyApp工程monkeyDemo
- 在monkeyDemo文件夹的TargetApp里放ipa包,然后运行