在应用开发过程中,我们不仅仅需要完成正常的业务逻辑,考虑应用性能、代码健壮相关的问题,我们有时还需要考虑到应用安全的问题。
那么应用安全的问题涉及到很多方面。比如防止静态分析的,代码混淆、逻辑混淆;防止重签名的,应用ID检测、甚至是代码的HASH检测等等。那么这篇文章我想聊聊关于代码的注入检测,因为发现随着iOS系统的更新,我们防护的手段发生了一些变化。

代码注入的方式

代码注入的方式大致分为两种

  • 越狱注入:通过修改DYLD_INSERT_LIBRARIES 环境变量的值,来插入动态库并执行
  • 非越狱注入:

    • 直接将自定义的Framwork或者dylib库打包进入APP并重签名。
    • 利用yololib修改MachO文件,添加库路径.在应用启动时,dyld会加载并执行.

早期防护方式

在工程的Build Settings中找到Other Linker Flages 并添加字段
-Wl,-sectcreate,__RESTRICT,__raestrict,/dev/null
此操作的作用是在可执行文件中添加一个Section.我们使用MachOView分析如下:

当MachO文件中拥有这个字段,那么我们通过越狱环境插入动态库的方式就会失效.起到防护的作用.其原理在DYLD源码中可以分析到.

dyld源码分析

首先这里分析的DYLD源码版本是519.2.2版本.
我们可以通过检索DYLD_INSERT_LIBRARIES定位到_main函数加载插入动态库的代码如下.

            // load any inserted librariesif  ( sEnv.DYLD_INSERT_LIBRARIES != NULL ) {for (const char* const* lib = sEnv.DYLD_INSERT_LIBRARIES; *lib != NULL; ++lib) loadInsertedDylib(*lib);}

但是早在这个环境变量判断之前,dyld已经做了一个判断

    if ( gLinkContext.processIsRestricted ) {pruneEnvironmentVariables(envp, &apple);// set again because envp and apple may have changed or movedsetContext(mainExecutableMH, argc, argv, envp, apple);}

如果判断出进程是restricted!也就是当前进程是限制插入动态库的!就会调用pruneEnvironmentVariables函数移除相关的环境变量.
那么我们的processIsRestricted值什么时候为true呢?
继续分析源码可以发现两个关键函数影响其值.其中 hasRestrictedSegment 函数专门检测RESTRICT段

// any processes with setuid or setgid bit set or with __RESTRICT segment is restrictedif ( issetugid() || hasRestrictedSegment(mainExecutableMH) ) {gLinkContext.processIsRestricted = true;}

通过注释也能发现.任意进程的__RESTRICT段设置为restricted动态库插入将被限制.
我们进入到processIsRestricted函数内,实现如下.

#if __MAC_OS_X_VERSION_MIN_REQUIRED
static bool hasRestrictedSegment(const macho_header* mh)
{const uint32_t cmd_count = mh->ncmds;const struct load_command* const cmds = (struct load_command*)(((char*)mh)+sizeof(macho_header));const struct load_command* cmd = cmds;for (uint32_t i = 0; i < cmd_count; ++i) {switch (cmd->cmd) {case LC_SEGMENT_COMMAND:{const struct macho_segment_command* seg = (struct macho_segment_command*)cmd;//dyld::log("seg name: %s\n", seg->segname);if (strcmp(seg->segname, "__RESTRICT") == 0) {const struct macho_section* const sectionsStart = (struct macho_section*)((char*)seg + sizeof(struct macho_segment_command));const struct macho_section* const sectionsEnd = &sectionsStart[seg->nsects];for (const struct macho_section* sect=sectionsStart; sect < sectionsEnd; ++sect) {if (strcmp(sect->sectname, "__restrict") == 0) return true;}}}break;}cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);}return false;
}

所以通过添加Other Linker Flags 在MachO中设置RESTRICT段赋值为restricted可以用来防护越狱的代码注入.
但是新版的dyld源码中去掉了__RESTRICT检测.从iOS10开始,这种防护手段已失效

DYLD_INSERT_LIBRARIES 检测

那么既然dyld加载过程不再检测__RESTRICT段了我们就手动的检测DYLD_INSERT_LIBRARIES环境变量.通过函数可查看当前进程环境变量的值.

  char *env = getenv("DYLD_INSERT_LIBRARIES");NSLog(@"%s",env);

在没有插入动态库时,env为null.
那么一旦为自己的应用写入插件时,我们就可以看到控制台的输出

2019-01-03 19:20:37.285 antiInject[7482:630392] /Library/MobileSubstrate/MobileSubstrate.dylib

白名单检测

那么上面的检测只可以检测越狱环境中的代码注入,在非越狱环境中,逆向工程师可以利用yololib工具注入动态库.所以我们可以检索一下自己的应用程序所加载的动态库是否是我们源程序所有

bool HKCheckWhitelist(){int count = _dyld_image_count();for (int i = 0; i < count; i++) {//遍历拿到库名称!const char * imageName = _dyld_get_image_name(i);//判断是否在白名单内,应用本身的路径是不确定的,所以要除外.if (!strstr(libraries, imageName)&&!strstr(imageName, "/var/mobile/Containers/Bundle/Application")) {printf("该库非白名单之内!!\n%s",imageName);return NO;}}return YES;
}

其中libraries变量是<q style="box-sizing: border-box;">白名单</q>.

iOS应用代码注入防护 1相关推荐

  1. iOS应用代码注入防护

    在应用开发过程中,我们不仅仅需要完成正常的业务逻辑,考虑应用性能.代码健壮相关的问题,我们有时还需要考虑到应用安全的问题. 那么应用安全的问题涉及到很多方面.比如防止静态分析的,代码混淆.逻辑混淆:防 ...

  2. iOS开发技术之应用代码注入防护

    1.介绍 在应用开发过程中,我们需要考虑到应用安全的问题.而应用安全的问题涉及到很多方面的内容,随着iOS系统的不断更新,我们需要在防护的手段上发生一些改变. 如下所示: [1]防止静态分析:代码混淆 ...

  3. ios 自动代码注入dylib脚本并重新打包ipa

    用MonkeyDev 编写好了一个hook库 但是又不想每次把ipa 拖到MonkeyDev里面再用xcode 跑一次 于是乎 懒人计划开始: 直接编写一个脚本 自动注入dylib 打包 签名 批量处 ...

  4. 【原】iOS动态性(三) Method Swizzling以及AOP编程:在运行时进行代码注入

    概述 今天我们主要讨论iOS runtime中的一种黑色技术,称为Method Swizzling.字面上理解Method Swizzling可能比较晦涩难懂,毕竟不是中文,不过你可以理解为" ...

  5. iOS 非越狱下的代码注入

    目录 免责声明 非越狱下的代码注入步骤 使用 ViewDebug 和导出的 Objective-C 类的头文件分析目标 App Objective-C 方法常见的 Hook 方式 免责声明 本文为一篇 ...

  6. iOS 分析一次有意思的需求——HTML代码注入

    级别: ★★☆☆☆ 标签:「HTML代码注入」「WKScriptMessageHandler」「iOS与JS交互」 作者: chouheiwa 审校: QiShare团队 有个朋友问了我一个问题: 他 ...

  7. iOS逆向(4)-代码注入,非越狱窃取微信密码

    利用LLDB对微信进行分析,然后利用分析的结果,再逐步讲解如何Hook微信的登录过程,截获微信密码. 在上一篇文章(APP重签名)中,已经介绍了如何对APP重签名,并且利用XCode将微信跑起来,既然 ...

  8. ios重签名shell脚本_iOS逆向——shell重签名及代码注入

    感谢hank老师 上一章我们讲了应用签名原理和重签名原理,不再赘述,没有看过的同学可以点这里-- 这章概述shell脚本重签名.可能有的同学认为有很多工具都能快速的帮助我们重签名实现需求,但我更希望在 ...

  9. sql 注入防护与xss攻击防护

    [sql注入防护] 1.过滤关键字 限制mysql关键字以输入的形式注入sql,防止恶意代码对数据库产生破坏 2.控制输入字符长度 防止输入以16进制码注入,以长度限制,补充过滤关键字的漏洞 3.关闭 ...

最新文章

  1. 入职地府后我成了人生赢家_【200811推文】闪闪而恋作者:钦点废柴+入职地府后我成了人生赢家作者:有只胖头鱼...
  2. Postgresql服务器配置-设置参数
  3. MyBatis之ResultMap标签
  4. JSP 中使用Struts2的值
  5. php网页生命周期函数,PHP的生命周期
  6. python爬虫框架--scrapy 基本使用
  7. 用jQuery实现一些导航条切换,显示隐藏
  8. gnome boxes_如何使用GNOME Boxes的快照功能
  9. android手势_Android手势检测器
  10. 深度学习入门:一句话告诉你什么是神经网络(CNN,RNN,DNN)
  11. CSS flex 布局 一些基本属性应用
  12. ASP.NET MVC+EF框架+EasyUI实现权限管理系列
  13. linux 系统启动级别,LINUX系统启动级别介绍与解释
  14. 计算机里的文件弄不到桌面怎么办,电脑文件夹在桌面不显示怎么办
  15. 什么是token/token如何使用
  16. Spring系列九:Spring 事务
  17. code换取微信openid_快速实现微信公众号支付功能
  18. Attention-guided Context Feature Pyramid Network for Object Detection
  19. iOS开发常用之博客
  20. 基于STM32-F401的平衡小车

热门文章

  1. Ogre学习笔记Basic Tutorial 前四课总结
  2. 2012 金华现场赛 A题
  3. ES6新特性_ES6的对象扩展方法---JavaScript_ECMAScript_ES6-ES11新特性工作笔记040
  4. JAVA线程池_并发队列工作笔记0001---认识阻塞队列_非阻塞队列
  5. 数据库工作笔记017---还记得Oracle悲观锁和乐观锁嘛?以及hibernate对乐观悲观锁的封装
  6. 二维码相关---java生成二维码名片,并且自动保存到手机通讯录中...
  7. SQLite 3 中的数据类型
  8. eclipse3.6_jee启动tomcat无法访问http://localhost:8080/的解决方案
  9. linux命令echo的实现,Linux echo命令的使用及三种实现方式
  10. 随想录(矩阵计算的几种方法)