iOS Hacker 动态库 dylib 注入

很多情况下我们希望自己写的代码能够在其他应用中运行,如果代码简单的话,可以写 Tweak 或者使用 Cycript。但如果代码多的话,那最好是写一个动态库,然后把文件注入到应用中得到代码的执行。一般有三种方法,本文简单的讲解一下。

一、编写 dylib

​ 首先得先写一个测试用的动态库。Xcode 新建 iOS 工程的时候,选择 Framework 工程,默认文件格式为动态库,如图:

​ 动态库的入口函数可以这样写

__attribute__((constructor)) static void EntryPoint()
{NSLog(@"EntryPoint");
}

二、DynamicLibraries

​ 注入动态库的第一种方法可以将 dylib 文件放入 DynamicLibraries 目录。写过 Tweak 的朋友,应该知道 Tweak 产生的 dylib 实际会安装到 /Library/MobileSubstrate/DynamicLibraries 目录,在这个目录的 dylib 会被应用加载,里面的 dylib 会有一个 plist 文件,标识哪些进程会加载,如图:


这样我们只需要将我们自己的 dylib 放入这个目录,然后新建一个 plist 把微信的包名加进去,就可以让微信加载我们的代码了。

三、修改可执行文件

​ 注入动态库的第二种方法就是修改可执行文件。OSX 和 iOS 应用的可执行文件都属于 Mach-O 文件格式,只要我们在可执行文件的添加了一条 LoadCommand 为 LC_LOAD_DYLIB,将路径指定我们的 dylib,不就行了吗?下面的图可以看出,LoadCommand 加载系统的动态库。

使用开源工具 optool 可以添加 LoadCommand,方法如下:

git clone –recursive https://github.com/alexzielenski/optool.git
cd optool
xcodebuild -project optool.xcodeproj -configuration Release ARCHS=”x86_64” build //编译
/path/to/optool install -c load -p “@executable_path/yourdylib.dylib” -t /yourexefile

因为 optool 添加了 submodule,所以需要使用 –recuresive 选项,将子模块全部 clone 下来。optool 执行之后的效果如图:

我们添加的 dylib 的路径是 executable_path/yourdylib.dylib, 所以需要将 dylib 复制到应用可执行文件自身目录下,这样应用打开就能加载我们的动态库。

如果对文件重签名,打包成 ipa,就可以安装到未越狱的手机上,也就是实现了不越狱也能注入动态库。

四、DYLD_INSERT_LIBRARIES

第三种方法是使用 DYLD_INSERT_LIBRARIES 环境变量启动进程。

DYLD_INSERT_LIBRARIES=test.dylib /var/mobile/Containers/Bundle/Application/143A710D-4395-4765-872C-148EA6C86936/WeChat.app/WeChat

通过设置 DYLD_INSERT_LIBRARIES 环境变量也可以实现注入,还记得 dumpdecrypted 脱壳吗?它就是使用 DYLD_INSERT_LIBRARIES 注入进程,然后把文件从内存中给 dump 下来。

有人会奇怪,为什么 DYLD_INSERT_LIBRARIES 能够注入呢?其实这就是苹果本身提供的一个功能,我们可以看苹果开源的 dyld 的源码,在 main 函数里相关的代码,判断了 DYLD_INSERT_LIBRARIES 环境变量,如果有的话就会加载。

// load any inserted libraries
if  ( sEnv.DYLD_INSERT_LIBRARIES != NULL ) {for (const char* const* lib = sEnv.DYLD_INSERT_LIBRARIES; *lib != NULL; ++lib) loadInsertedDylib(*lib);
}
// state of all environment variables dyld uses
//
struct EnvironmentVariables {const char* const *         DYLD_FRAMEWORK_PATH;const char* const *         DYLD_FALLBACK_FRAMEWORK_PATH;const char* const *         DYLD_LIBRARY_PATH;const char* const *         DYLD_FALLBACK_LIBRARY_PATH;const char* const *         DYLD_INSERT_LIBRARIES;const char* const *         LD_LIBRARY_PATH;            // for unix conformanceconst char* const *         DYLD_VERSIONED_LIBRARY_PATH;const char* const *         DYLD_VERSIONED_FRAMEWORK_PATH;bool                        DYLD_PRINT_LIBRARIES;bool                        DYLD_PRINT_LIBRARIES_POST_LAUNCH;bool                        DYLD_BIND_AT_LAUNCH;bool                        DYLD_PRINT_STATISTICS;bool                        DYLD_PRINT_OPTS;bool                        DYLD_PRINT_ENV;bool                        DYLD_DISABLE_DOFS;bool                        DYLD_PRINT_CS_NOTIFICATIONS;//  DYLD_SHARED_CACHE_DONT_VALIDATE ==> sSharedCacheIgnoreInodeAndTimeStamp//  DYLD_SHARED_CACHE_DIR           ==> sSharedCacheDir//  DYLD_ROOT_PATH                  ==> gLinkContext.rootPaths//  DYLD_IMAGE_SUFFIX               ==> gLinkContext.imageSuffix//  DYLD_PRINT_OPTS                 ==> gLinkContext.verboseOpts//  DYLD_PRINT_ENV                  ==> gLinkContext.verboseEnv//  DYLD_FORCE_FLAT_NAMESPACE       ==> gLinkContext.bindFlat//  DYLD_PRINT_INITIALIZERS         ==> gLinkContext.verboseInit//  DYLD_PRINT_SEGMENTS             ==> gLinkContext.verboseMapping//  DYLD_PRINT_BINDINGS             ==> gLinkContext.verboseBind//  DYLD_PRINT_WEAK_BINDINGS        ==> gLinkContext.verboseWeakBind//  DYLD_PRINT_REBASINGS            ==> gLinkContext.verboseRebase//  DYLD_PRINT_DOFS                 ==> gLinkContext.verboseDOF//  DYLD_PRINT_APIS                 ==> gLogAPIs//  DYLD_IGNORE_PREBINDING          ==> gLinkContext.prebindUsage//  DYLD_PREBIND_DEBUG              ==> gLinkContext.verbosePrebinding//  DYLD_NEW_LOCAL_SHARED_REGIONS   ==> gLinkContext.sharedRegionMode//  DYLD_SHARED_REGION              ==> gLinkContext.sharedRegionMode//  DYLD_PRINT_WARNINGS             ==> gLinkContext.verboseWarnings//  DYLD_PRINT_RPATHS               ==> gLinkContext.verboseRPaths//  DYLD_PRINT_INTERPOSING          ==> gLinkContext.verboseInterposing
};

苹果开源的 dyld 源码地址,里面有各种版本的
https://opensource.apple.com/source/dyld/

苹果的开源项目,里面东西很多,还有 xun 内核的源码,方便做内核调试。
https://opensource.apple.com/
https://opensource.apple.com/release/os-x-1011.html
https://opensource.apple.com/source/dyld/dyld-360.14/

iOS Hacker 动态库 dylib 注入相关推荐

  1. iOS Hacker 重签名实现无需越狱注入动态库 dylib

    iOS Hacker 重签名实现无需越狱注入动态库 dylib 一.获取 ipa 文件 iOS 的应用都是打包成 ipa 的文件格式,ipa 文件实际上就是 zip 格式的文件,通过 unzip 可以 ...

  2. iOS中创建,使用动态库(dylib)

    测试环境: xcode4.5.2   Mac OS X 10.8.2 重要:由于苹果不支持自己创建动态库,所以这里需要替换两个文件 1:iOS Device 需要替换的文件 替换路径:/Applica ...

  3. macOS下加载动态库dylib报code signature invalid错误的解决办法

    一.现象描述 在macOS上搞开发也有一段时间了,也积攒了一定的经验.然而,今天在替换工程中的一个动态库时还是碰到了一个问题.原来工程中用的是一个静态库,调试时发现有问题就把它替换成了动态库.这本来没 ...

  4. iphone开发中使用动态库(dylib)和动态加载framework (获取iphone的IMSI和设置飞行模式)

    在iphone上使用动态库的多为dylib文件,这些文件使用标准的dlopen方式来使用是可以的.那相同的在使用framework文件也可以当做动态库的方式来动态加载,这样就可以比较自由的使用appl ...

  5. ios .framework动态库重签名

    真机上运行.framework时,如果报 dyld'dyld_fatal_error:dyld: Library not loaded: @rpath/XX.framework/XXReference ...

  6. ios动态库注入把越狱手机上自制的动态库安装到普通手机上

    文章目录 预备条件 导出越狱手机上的app包和自己注入的动态库 导出自己写的tweak动态库文件 查看依赖库 执行命令查看程序依赖的动态库名字 用machoview查看 安装insert_dylib ...

  7. IOS FRAMEWORK,动态库 等几个问题

    1,关于性能剖析工具的overhead问题,影响不影响数据统计出的函数时间的准确性??? 比如unity的deepprofiling在移动平台上开销很大,那么这时候剖析出的数据还准不准确呢? 答案:总 ...

  8. 【Android 逆向】Android 进程注入工具开发 ( 远程进程注入动态库文件操作 | 注入动态库 加载 业务动态库 | 业务动态库启动 | pthread_create 线程开发 )

    文章目录 前言 一.加载 libnattive.so 动态库 二. libnattive.so 动态库启动 三. pthread_create 线程开发 四. 线程执行函数 前言 libbridge. ...

  9. 【Android 逆向】Android 进程代码注入原理 ( 注入本质 | 静态注入和动态注入 | 静态注入两种方式 | 修改动态库重打包 | 修改 /data/app/xx/libs 动态库 )

    文章目录 一.注入本质 二.静态注入和动态注入 三.静态注入两种方式 ( 修改动态库重打包 | 修改 /data/app/packageName/libs/ 下的动态库 ) 一.注入本质 进程注入本质 ...

最新文章

  1. Matlab绘图高级部分
  2. 《Head First设计模式》第三章笔记 装饰者模式
  3. TensorFlow3-会话
  4. 父亲节——女儿的礼物
  5. git命令详解( 六 )
  6. require.js 的简单运用 --兰
  7. java私有 公开 保护_性能与设计相关的java中的私有/受保护方法
  8. 【青草识别】基于matlab GUI形态学马唐草+牛筋草识别【含Matlab源码 1041期】
  9. VBA 收集 Word关键字批量处理-Excel版
  10. Docker 如何安全地进入到容器内部
  11. Django快速上手
  12. 【JavaSE】Lambda表达式、接口组成更新、方法引用
  13. 曲线绕x轴旋转曲面方程_曲线绕着Ox轴旋转所得的曲面方程是______。
  14. 元学习入门:MAML
  15. c#NPOI操作word小心得
  16. Win10:解决Win10的录音设备只能录制系统内部声音无法录制麦克风声音的问题
  17. git切换master项目,新建分支new branch
  18. unity3d环境搭建
  19. 2013年08月威海之旅
  20. 数字图像处理领域的二十四个典型算法

热门文章

  1. S2SH框架入门之使用hibernate进行基础的增删改查
  2. 寻找数组中的第二大数
  3. OSI七层模型非专业简介
  4. linux下的ssh和rynsc
  5. [BZOJ 2734] 集合选数
  6. 关于ESXI能虚拟出多少个虚拟机和CPU的关系
  7. css 两边宽度固定中间自适应宽度
  8. linux各种查看端口号
  9. Day11多态部分-6 【1.3 对象的向上转型和向下转型】
  10. 隐藏画质代码_和平精英120帧率怎么设置?和平精英120帧率代码介绍!