美文网首页
代码注入

代码注入

作者: coder_feng | 来源:发表于2020-04-28 17:01 被阅读0次

代码注入

一般修改原始的程序,是利用代码注入的方式,注入代码就会选择利用FrameWork或者Dylib等第三方库的方式注入

注入步骤

Framework 注入
- 通过Xcode新建Framework,将库安装进入App包
- 通过yololib注入Framework库路径,命令:$yololib MachO文件路径 库路径
所有的famework加载都是由DYLD加载进入内存被执行的
注入成功的库路径会写入到MachO文件的LC_LOAD_DYLIB字段中

Framework 实操

  • 先下载yololib二进制到/usr/local/bin 目录下 Snip20200424_74.png
  • 新建Xcode工程,目录结构如下 Snip20200424_75.png
  • 建立Framework(TestHook) Snip20200424_76.png
Snip20200424_77.png Snip20200424_78.png
+ (void)load{
    NSLog(@"test InjectCode");
}
@end
  • 将需要注入代码的ipa放入到APP目录下
  • 配置Run Script脚本 Snip20200424_79.png
# ${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文件的路径
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


#注入(这一步是注入核心)
yololib "$TARGET_APP_PATH/$APP_BINARY" "Frameworks/TestHook.framework/TestHook"
  • 编译安装
如果出现Unable to install .... 可能是Framework的版本高于手机版本,或者是没有embed & sign
如果脚本中没有执行yololib这条指令的话,动态库是没有被注入的,虽然安装的app的Framework目录下包含来我们自定义的动态库TestHook Snip20200424_83.png
但是其实是没有加载到的,我们可以通过MachOView这个工具,查看这个重签名的ipa的二进制文件 Snip20200424_8.png
Snip20200424_9.png
Snip20200424_10.png

可以看到TestHook其实并没有加载到里面,所以终端也并没有输出;

另外使用yololib注入的

Snip20200424_7.png
是可以看到TestHook是已经注入的,并且终端也是有打印输出的
Snip20200424_4.png

Dylib 实操

Dylib注入
- 通过Xcode新建Dylib库(注意:Dylib属于MacOS所以需要修改属性)
- 添加Target依赖,让Xcode将定义Dylib文件打包进入APP包。
- 利用yololib进行注入

其实操作和Framework注入的操作差不多的,区别的不同仅仅在于形式而已

#注入
yololib "$TARGET_APP_PATH/$APP_BINARY" "Frameworks/TestHook.dylib"

Method Swizzle

利用OC的Runtime特性,动态改变SEL(方法编号)和IMP(方法实现)的对应关系,达到OC方法调用流程改变的目的。主要用于OC方法
在OC中,SEL和IMP之间的关系,就好像一本书的目录。SEL是方法编号,就像标题一样,IMP是方法实现的真是地址,就像页码一样,两者之间是一一对应关系,Runtime提供了交换两个SEL和IMP对应关系的函数

OBJC_EXPORT void method_exchangeImplementations(Method _Nonnull m1,Method _Nonull m2) OBJC_
AVAILABLE(10.5,2.0,9.0,1.0,2.0);
通过这个函数交换两个SEL和IMP丢应关系的技术,我们称之为Method Swizzle image.png

例子说明

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    NSURL *url = [NSURL URLWithString:@"https://www.baidu.com/中文"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    //发请求
    NSLog(@"%@",request);
}

这种情况下,终端打印出来的结果会是MethodSwizzle[3940:1232344] <NSURLRequest: 0x15fdad630> { URL: (null) },因为中文没有经过转义,针对这个情形,我们可以对URL方法进行hook,添加一个分类如下


+(void)load
{
    Method URLWithStr = class_getClassMethod(self, @selector(URLWithString:));
    
    Method HKURL = class_getClassMethod(self, @selector(HKURLWithStr:));
    
    //交换
    method_exchangeImplementations(URLWithStr, HKURL);
}

+(instancetype)HKURLWithStr:(NSString *)str{
    //调用系统原来的方法
    NSURL * url = [NSURL HKURLWithStr:str];
    if (url == nil) {
       str = [str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    }
    url = [NSURL HKURLWithStr:str];
    
    return url;
}

可以看到输入结果:2020-04-26 10:41:53.522 MethodSwizzle[3954:1233403] <NSURLRequest: 0x125e5ab50> { URL: https://www.baidu.com/%E4%B8%AD%E6%96%87 }

多种HOOK方式

  • class_addMethod方式:
利用AddMethod方式,让原始方法可以被调用,不至于因为找不到SEL而奔溃
  • class_replaceMethod方式:
利用class_replaceMethod,直接改原始的方法替换IMP
  • method_selImplementation方式:
利用method_setImplementation,直接重新赋值给原始的新的IMP

相关文章

  • iOS逆向 代码注入+Hook

    iOS逆向 代码注入+HookiOS逆向 代码注入+Hook

  • iOS应用代码注入防护

    iOS应用代码注入防护 iOS应用代码注入防护

  • iOS开发逆向之代码注入(上)

    本文主要讲解代码注入的两种方式:FrameWork注入、dylib注入 代码注入 一般修改原始的程序,是利用代码注...

  • 代码注入

    Framework库中代码注入工程的步骤:(选择iOS下创建库) Dylib库中代码注入工程的步骤:(选择MacO...

  • 代码注入

  • 代码注入

    typedef注意用法

  • 代码注入

    在学习代码注入之前,先看一下iOS 程序 main 函数之前发生了什么 一、framework形式代码注入 1.创...

  • 代码注入

    代码注入 一般修改原始的程序,是利用代码注入的方式,注入代码就会选择利用FrameWork或者Dylib等第三方库...

  • 代码注入

    前提使用了重签名脚本。1.framework注入(1)新建名为YPHOOK的framework (2)在YPHOO...

  • 代码注入

    代码注入 一般修改原始的程序,是利用代码注入的方式,注入代码就会选择利用FrameWork或者Dylib等三方库的...

网友评论

      本文标题:代码注入

      本文链接:https://www.haomeiwen.com/subject/cysrihtx.html