iOS非越狱逆向--代码注入

在iOS逆向过程中代码的注入无非是一个最关键的步骤。只有把你的代码注入到别人的代码中才能实现你想实现的目的,才能算实现了逆向。那么怎么才能将自己的代码注入到别人的ipa 里边的?

代码注入原理

众所周知,iOS app 在打包的过程中将代码全部转换成了 可执行文件 Mach - O 文件,所以说我们直接改源码是万万不可能的(除非你拿到的源码,话说你源码都拿到了你还逆向个?)。那么我们可不可以以第三方 lib 的(之前的博客中可以看到 第三方的 lib 是独立的)方式注入呢?必须可以啊!!

那么怎么才能将第三方的lib 注入目标程序呢?这个我们要从二进制文件的结构说起,Mach-O文件的数据主体可分为三大部分,分别是头部(Header)、加载命令(Load commands)、和最终的数据(Data)。mobileloader会在目标程序启动时,会根据指定的规则检查指定目录是否存在第三方库,如果有,则会通过修改二进制的loadCommands,来把自己注入进所有的app当中,然后加载第三方库。

这样就结束了么?远远不是的,到这里我们只是把自己的动态库注入到了目标程序中,但是我们自己写的代码还没有执行的入口,所以我们还是不能搞事情。我们还需要一个”main”函数来执行我们自己的代码,这个”main”函数在oc里面称为构造函数,只要在函数前声明 “attribute((constructor)) static” 即可,这样我们就能搞事情了。

代码注入的方式

上边讲过了可以通过第三方的lib 来实现代码注入,那么第三方的lib怎么才能实现注入呢?下边来讲两种不同的注入方式:Framework 和 dylib:

一下两种注入的前提是先实现代码的重签名,具体方式可参照:iOS非越狱逆向– ipa重签名

通过 Framework 实现代码注入

  • 创建一个framework 文件 并将这个文件添加引用

创建一个FrameWork文件


创建CopyFiles文件


导入创建的FrameWork文件, Destination属性 改为FrameWorks


  • 在 framework中添加一个要注入的代码
  • 在 + load 方法中实现你需要实现的方法

创建需要注入的代码文件,并在 + load 方法中需要实现的方法


  • 编译之后找到 可行性文件 Mach - O ‘Products –> xxxx.app(show in Finder) – > 显示包内容’
  • 增加 Mach - O 文件的执行权限
    chmod +x WeChat (微信为例)
  • 更改 Mach - O 文件 (将自己写的framework 加入到 Mach - O中)
    yololib WeChat Frameworks/自定义Framework文件名.framework/自定义Framework文件名
  • 重新打包 Payload 文件 可以直接压缩重新命名为 .ipa 格式
    zip -ry WeChat.ipa Payload
  • 将ipa 包放到 APP 文件夹中 编译运行 Bingo

通过 dylib 实现代码注入

其实dylib 的注入方式几乎一样,无非就是创建个lib 然后添加到 targets 里边然后命令行注入,但是使用 dylib 需要设置几个权限属性,因为iOS 现在默认不支持 dylib 了需要手动设置属性。
  • 创建一个 dylib 文件 并将这个文件添加引用

添加文件的方法参考 FrameWork 的引入的方法


  • 修改 dulib 的Base SDK 属性和 Signing 属性

设置Base SDK 属


设置 Signing 属性

  • 编译 执行注入命令

  • 编译之后找到 可行性文件 Mach - O ‘Products –> xxxx.app(show in Finder) – > 显示包内容’

  • 增加 Mach - O 文件的执行权限

    chmod +x WeChat (微信为例)

  • 更改 Mach - O 文件 (将自己写的framework 加入到 Mach - O中)

    yololib WeChat Frameworks/libxxxxx.dylib

  • 编译运行 Bingo

脚本修改

为了以后能更方便的执行代码的注入 现将之前的脚本修改下
想了解之前脚本(代码重签名)的可以参考 iOS非越狱逆向 – ipa 重签名


# ${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

# -------------------在之前脚本后边添加以下脚本--------------------------------
# 7. 注入我们编写的动态库
echo "开始注入"
# 需要注入的动态库的路径 可以固定 也可以自己随工程修改
INJECT_FRAMEWORK_RELATIVE_PATH="Frameworks/libLinkHook.dylib"
#
## 通过工具实现注入
yololib "$TARGET_APP_PATH/$APP_BINARY" "$INJECT_FRAMEWORK_RELATIVE_PATH"
echo "注入完成"

你可能感兴趣的:(iOS非越狱逆向)