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

1、介绍
在应用开发过程中,我们需要考虑到应用安全的问题。而应用安全的问题涉及到很多方面的内容,随着iOS系统的不断更新,我们需要在防护的手段上发生一些改变。
如下所示:
【1】防止静态分析:代码混淆、逻辑混淆
【2】防止重签名:应用ID 检测、代码的HASH检测

2、代码的注入方式
代码的注入的方式大致分为两类:
【1】越狱注入:通过修改DYLD_INSERT_LIBRARIES环境变量的值,来插入动态库并执行
【2】非越狱注入:直接将自定义的Framework库或者dylib/tbd库打包进入App并重新签名,或者利用yololib修改MachO文件,添加库路径,在应用启动时,dyld会加载并执行。

3、早期的防护方式
在工程中的编译设置中添加字段,其操作的作用是在可执行文件中添加一个Section,当MachO文件中拥有这个字段,那么我们通过越狱环境插入动态库的方式就会失效,起到防护的作用,其原理在DYLD源码中可以分析到。
使用MachOView分析如下:
Project —> Targets —> BuildSetting —> Other Linker Flags —> -Wl,-sectcreate,__RESTRICT,__raestrict,/dev/null

4、dyld源码分析
我们可以通过检索DYLD_INSERT_LIBRARIES定位到_main函数加载插入动态库的代码,如下所示:
// 加载时,插入库
        if  ( 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 moved
        setContext(mainExecutableMH, argc, argv, envp, apple);
    }

// 如果判断出进程是restricted!也就是当前进程是限制插入动态库的!就会调用pruneEnvironmentVariables函数移除相关的环境变量。那么我们的processIsRestricted值什么时候为true呢? 继续分析源码可以发现两个关键函数影响其值.其中 hasRestrictedSegment 函数专门检测RESTRICT段
// any processes with setuid or setgid bit set or with __RESTRICT segment is restricted
    if ( 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 = §ionsStart[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开始,这种防护手段已失效。

5、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

6、白名单检测
那么上面的检测只可以检测越狱环境中的代码注入,在非越狱环境中,逆向工程师可以利用yololib工具注入动态库.所以我们可以检索一下自己的应用程序所加载的动态库是否是我们源程序所有。其中libraries变量是“白名单”。
如下所示:
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;
}

原文地址:https://www.cnblogs.com/yuhao309/p/10281454.html

时间: 2024-08-25 10:41:41

iOS开发技术之应用代码注入防护的相关文章

iOS开发UI篇—从代码的逐步优化看MVC

iOS开发UI篇—从代码的逐步优化看MVC 一.要求 要求完成下面一个小的应用程序. 二.一步步对代码进行优化 注意:在开发过程中,优化的过程是一步一步进行的.(如果一个人要吃五个包子才能吃饱,那么他是否直接吃第五个,前面四个不用吃就饱了?) 1.完成基本要求的代码(使用了字典转模型和xib连线) (1)文件结构 (2)主要代码 字典转模型部分: YYappInfo.h头文件 // // YYappInfo.h // 12-视图改进(1) // // Created by apple on 14

文顶顶 iOS开发UI篇—从代码的逐步优化看MVC

iOS开发UI篇—从代码的逐步优化看MVC 一.要求 要求完成下面一个小的应用程序. 二.一步步对代码进行优化 注意:在开发过程中,优化的过程是一步一步进行的.(如果一个人要吃五个包子才能吃饱,那么他是否直接吃第五个,前面四个不用吃就饱了?) 1.完成基本要求的代码(使用了字典转模型和xib连线) (1)文件结构 (2)主要代码 字典转模型部分: YYappInfo.h头文件 1 // 2 // YYappInfo.h 3 // 12-视图改进(1) 4 // 5 // Created by a

干货!总结19个提升iOS开发技术的必看教程!

又到了ibnShawari一周一篇技术推送的时间了,今天我为大家带来了iOS开发篇,绝对实用,绝对简单!!! 注意!!本课程采用了一种系统且全面的方式学习:赶快来学习,体验这种方法的魔力吧!! 干货!总结19个提升iOS开发技术的必看教程!        本系列教程采用了最新的IOS开发技术进行讲解,视频中所有的例子都在最新的编译器中调试通过.理论上所有的例子都可以在成功运行.本路线图提供的视频课程是全网最深入,最全.通过对本路线图的学习,学员可以充分掌握IOS的开发过程,并具有一定的项目实战经

iOS开发UI基础—从代码的逐步优化看MVC

iOS开发UI基础-从代码的逐步优化看MVC 一.要求 要求完成下面一个小的应用程序. 二.一步步对代码进行优化 注意:在开发过程中,优化的过程是一步一步进行的.(如果一个人要吃五个包子才能吃饱,那么他是否直接吃第五个,前面四个不用吃就饱了?) 1.完成基本要求的代码(使用了字典转模型和xib连线) (1)文件结构 (2)主要代码 字典转模型部分: YYappInfo.h头文件 1 // 2 // YYappInfo.h 3 // 12-视图改进(1) 4 // 5 // Created by

iOS开发数据库篇—SQL代码应用示例

iOS开发数据库篇—SQL代码应用示例 一.使用代码的方式批量添加(导入)数据到数据库中 1.执行SQL语句在数据库中添加一条信息 插入一条数据的sql语句: 点击run执行语句之后,刷新数据 2.在ios项目中使用代码批量添加多行数据示例 代码示例: 1 // 2 // main.m 3 // 01-为数据库添加多行数据 4 // 5 // Created by apple on 14-7-26. 6 // Copyright (c) 2014年 wendingding. All rights

iOS开发——技术精华Swift篇&amp;Swift 2.0和Objective-C2.0混编之第三方框架的使用

Swift 2.0和Objective-C2.0混编之第三方框架的使用 swift 语言是苹果公司在2014年的WWDC大会上发布的全新的编程语言.Swift语言继承了C语言以及Objective-C的特性,且克服了C语言的兼容性问题.Swift语言采用安全编程模式,且引入了多种新功能,使得编程工作更加简便,灵活! 2015年6月9日苹果又一次给所有开发之者带来了一个惊喜,那就是今年年底swift讲开源,者队iOS开发着来说无疑是一个值得兴奋的消息,可是就在这短短的几个月里面swift吸引了越来

iOS开发——OC篇&amp;纯代码退出键盘

关于iOS开发中键盘的退出,其实方法有很多中,而且我也学会了不少,包括各种非纯代码界面的退出. 其实这里纯代码界面推出如果用到Xib何Storyboard上面去还是一样的思路操作,只不过笔者在开发的时候是在纯代码界面遇到的问题,所以久以此命名. 下面大家介绍怎么在纯代码的情况下,退出(隐藏)键盘,Xib和StoryBoard情况下这里就不解释了(照此思路). 一:UITextField 关于UITextFiel个人感觉又很多中方法,但是最近开发中我用的最多的也就是这两种,根据和已经在公司上班的同

iOS 开发技术牛人博客

dark_gmn 的博客   http://blog.csdn.net/dark_gmn?viewmode=contents Tel_小超 的博客  http://blog.csdn.net/qq_26544491?viewmode=contents youxianming的博客 http://www.cnblogs.com/YouXianMing/tag/ uXianMing 念茜的博客(一个支付宝的妹子)http://nianxi.net 唐巧http://www.devtang.com/b

iOS开发技术之银联支付

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px "PingFang SC"; color: #333333 } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 14.0px "PingFang SC"; color: #000000 } p.p3 { margin: 0.0px 0.0px 10.0px 0.0px; lin