上一篇博客“IOS 逆向开发(三)应用签名”中详细讲解了IOS 应用签名,证书的原理。本篇博客主要以实战为主,讲解具体如果绕过苹果证书签名,给App重签名,然后可以让我们的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 输出文件 输入文件
将输入文件压缩为输出文件
codesign -v -d WeChat.app
来查看一下包的内容下载的砸核过的越狱应用WeChat 7.0.8信息如下:
我们如果要用codesign这个命令签名,需要在命令后面跟上证书信息。
我们先通过命令:security find-identity -v -p codesigning
来查看mac电脑的证书信息
接下来我们进入WeChat.app 查看包里面的内容:
otool -l WeChat
:
otool -l WeChat > ~/Desktop/123.txt
otool -l WeChat | grep cry
筛选出想要的cryptid内容:otool -l WeChat 查出来的内容通过管道输出符,通过grep筛选出 “cry”开头的内容。
cryptid == 0 表示没有进行加密。cryptid == 1表示加密了。这个加密是对称加密,因为需要对整个app包进行加密,是appstore对其进行加密。
是安装的时候解密还是运行的时候解密呢,为了安全,必须运行时解密,每次运行都需要重新解密一次。这样虽然会影响运行效率,但是苹果为了安全不得不在运行时每次对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
查看一下这个描述文件:
描述文件里面有一个非常重要的东西,这个就是我们权限文件的内容:
我们再确认一下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后,会提示是否需要覆盖安装,选择是
- 新建工程WeChatDemo,选择证书和真机调试
- 进入包内容,因为免费证书无法重签名插件,所以删除PlugIns文件夹,Watch里也有插件,也删除
- 对Frameworks里的framework进行重签名,有些包没有Frameworks就忽略这步: 进入Frameworks 文件夹;然后一个一个的重签名 security find-identity -v -p codesigning //查看所有证书 codesign -fs "iPhone Developer: clwmac@icloud.com (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> </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
重签名app至少有这两个好处:
- 重签名后,我们可以通过xcode动态调试那些被我们重签名过后的app.
- 重签名后,我们还可以动态注入我们自己的代码,达到破解的目的。
Products/WeChat.app 通过右键Show Finder 可以找到在debug-iphoneos目录下面,直接替换如下图:
(3) 替换掉之后,我们并不能直接通过xcode运行到真机上面,我还需要完成几个步骤才行。和手动签名一样,首先我们要删除我们无法签名的插件信息,删除WeChat.app下的Watch目录和 Pluglsn目录
(4)然后,我们还需要对Frameworks目录下面的所以framework进行重签名。
注意:这里我们不需要去修改原始微信.app里面的bundle Id ,xcode运行自动会帮我们改为我们新建工程的bundle id.
- 新建工程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. 这样我们需要通过运行脚本的方式,来更加优雅的执行重签名操作。
# ${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 复制代码