0


【iOS逆向与安全】使用ollvm混淆你的源码

前言

当你在研究别人源码的时候,是不是期望着别人代码没有进行任何的防护和混淆。这时的你,是不是应该考虑一下自己代码的安全.本篇文章将告诉你,如何使用ollvm来混淆iOS端的代码【此文为入门贴,大佬请绕道】。


一、目标

编译ollvm工具,并在Xcode中来混淆你的ipa或动态库,增加别人破解你源码的难度。

二、工具

三、步骤

1、基础知识

LLVM

LLVM(Low Level Virtual Machine)是一个开源的编译器基础架构,它包含了一组模块化、可重用的编译器和工具,支持多种编程语言和目标架构,包括x86、ARM和MIPS等。LLVM最初由美国伊利诺伊大学香槟分校(University of Illinois at Urbana–Champaign)的Chris Lattner教授开发,现在由LLVM社区进行维护和发展。

LLVM的核心思想是将编译器分为前端和后端两个部分,前端负责将源代码转换为中间表示(IR),后端负责将中间表示转换为目标机器的汇编代码。这种设计使得LLVM可以支持多种编程语言,因为只需要为每种语言编写一个前端,就可以利用后端的通用性支持多种目标架构。

除了编译器之外,LLVM还包括了一些工具,例如优化器、调试器、汇编器和反汇编器等,这些工具可以帮助开发者更好地分析和调试程序,提高代码的性能和可靠性。

LLVM已经成为了广泛使用的编译器基础架构,许多编程语言和工具链都采用了LLVM作为后端,例如C、C++、Objective-C、Swift、Rust、Go等。LLVM还被广泛应用于计算机体系结构研究、代码安全性分析、机器学习等领域。

Clang

Clang是基于LLVM框架的C、C++、Objective-C和Objective-C++编译器,它是一个开源项目,由LLVM社区进行开发和维护。Clang的设计目标是提供高质量的诊断、快速的编译速度、低内存占用和良好的可移植性。

Clang的编译器前端使用了现代的编译器架构,包括基于词法分析器和语法分析器的语法分析,生成抽象语法树(AST)并进行类型检查和语义分析等步骤。这些步骤的优化和并行化使得Clang能够快速地进行编译,同时提供了更好的错误和警告信息,有助于开发者更快地发现和修复代码中的问题。

除了作为独立的编译器之外,Clang还可以作为其他工具的库使用,例如静态分析工具、编辑器插件和代码重构工具等。Clang的模块化设计和良好的API使得它可以轻松地被集成到其他工具中,从而提供更好的编程体验。

由于Clang的优秀性能和良好的设计,它已经成为了许多项目的首选编译器,例如LLVM自身、macOS和iOS的默认编译器等。同时,许多开发者和组织也在积极地开发和贡献Clang的代码,使得它在未来仍有广阔的发展空间。

OLLVM

OLLVM(Obfuscator-LLVM)是基于LLVM框架的混淆器,它可以对程序进行混淆以提高程序的安全性。OLLVM的设计目标是提供一种灵活的、可定制的混淆方案,使得攻击者更难理解和分析程序的行为。

OLLVM通过对程序进行多种混淆操作来实现混淆效果,例如代码替换、函数内联、控制流平坦化、加密等。这些混淆操作可以改变程序的控制流图和数据流图,使得程序更难以被理解和逆向分析。同时,OLLVM还提供了一些额外的安全机制,例如加密程序的字符串、使用栈保护和位置无关代码等,以增加程序的安全性。

由于OLLVM是基于LLVM框架开发的,它可以与现有的LLVM工具和编译器集成,例如Clang和LLDB等。这使得开发者可以轻松地在现有的开发环境中使用OLLVM,并且可以使用现有的工具对混淆后的程序进行调试和分析。

尽管OLLVM的主要目的是提高程序的安全性,但它也可以用于其他领域,例如代码保护、代码压缩和代码优化等。由于其灵活性和可定制性,OLLVM已经被广泛应用于许多领域,例如网络安全、游戏开发和金融等。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kzBIkEp9-1677487692623)(null)]

IR之间的pass,就是混淆器工作的地方。相关代码位于

obfuscator/llvm/lib/Transforms/Obfuscation/

2、编译ollvm

命令如下:

witchan@witchandeMacBook-Air ~ % git clone -b llvm-13.x https://github.com/heroims/obfuscator.git
witchan@witchandeMacBook-Air ~ % $cd obfuscator
witchan@witchandeMacBook-Air ~ % mkdir build
witchan@witchandeMacBook-Air ~ % cd build
witchan@witchandeMacBook-Air ~ % cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_CREATE_XCODE_TOOLCHAIN=ON -DLLVM_ENABLE_PROJECTS="clang;libcxx;libcxxabi"-DLLVM_ENABLE_NEW_PASS_MANAGER=OFF ../llvm
witchan@witchandeMacBook-Air ~ % make-j8
witchan@witchandeMacBook-Air ~ % sudomake install-xcode-toolchain
witchan@witchandeMacBook-Air ~ % mv /usr/local/Toolchains  /Library/Developer/

注:

make -j8

这命令编译的快慢,取决于你的硬件设备

挨个执行以上命令后,ollvm就编译并安装完成,效果如下:

image-20230225211909806

3、混淆命令及效果对比

混淆命令简介

  • fla:该选项使用函数级别的混淆来隐藏程序的结构。这通过随机重命名函数、添加不必要的控制流和删除调用的函数来实现。这增加了反编译和分析代码的难度。
  • bcf:该选项使用基本块级别的混淆来隐藏代码的结构。这通过改变基本块之间的控制流、添加不必要的基本块和移除基本块之间的条件分支来实现。
  • -sub:该选项使用字符串混淆来隐藏代码中的常量字符串。这通过将字符串分成几个小块、将其存储在数组中并在运行时重新组合来实现。这使得分析代码和查找敏感信息更加困难。
  • split:该选项使用控制流混淆来增加程序的复杂性。这通过将函数分成几个基本块、添加随机的跳转指令和在运行时随机重组这些基本块来实现。这使得代码的流程更难以跟踪,从而增加了破解和反编译的难度。
  • sobf:该选项使用源代码混淆技术来隐藏代码的逻辑和结构。这通过使用类似加密的方式对代码进行变换,使其难以理解和分析。这可以通过运行时解密来执行,从而隐藏代码的真实功能。

示例代码如下:

-(void)testMethod {
    NSString *name =@"wit";int age =18;
    
    NSArray *list =@[@1,@3,@5,@18];for(int i=0; i<list.count; i++){int value =[list[i] intValue];if(value == age){
            age +=10;
            name =@"chan";}}NSLog(@"name = %@", name);NSLog(@"age = %d", age);}

未使用混淆:

__int64 __fastcall -[ViewController testMethod](__int64 a1, __int64 a2){void*v2;// x0
  __int64 v3;// ST70_8void*v4;// x0
  __int64 v5;// ST68_8void*v6;// x0
  __int64 v7;// ST60_8void*v8;// x0
  __int64 v9;// ST58_8void*v10;// x0void*v11;// x0void*v12;// ST20_8int v13;// ST2C_4
  __int64 result;// x0int i;// [xsp+7Ch] [xbp-54h]void*v16;// [xsp+80h] [xbp-50h]int v17;// [xsp+8Ch] [xbp-44h]
  __int64 v18;// [xsp+90h] [xbp-40h]
  __int64 v19;// [xsp+98h] [xbp-38h]
  __int64 v20;// [xsp+A0h] [xbp-30h]
  __int64 v21;// [xsp+A8h] [xbp-28h]
  __int64 v22;// [xsp+B0h] [xbp-20h]
  __int64 v23;// [xsp+B8h] [xbp-18h]
  __int64 v24;// [xsp+C0h] [xbp-10h]
  __int64 v25;// [xsp+C8h] [xbp-8h]

  v25 =*(_QWORD *)__stack_chk_guard_ptr;
  v20 = a1;
  v19 = a2;
  v18 =objc_retain(&stru_100008078);
  v17 =18;
  v2 =objc_msgSend(off_10000D2D0,(constchar*)off_10000D290,1LL);
  v3 =objc_retainAutoreleasedReturnValue(v2);
  v21 = v3;
  v4 =objc_msgSend(off_10000D2D0,(constchar*)off_10000D290,3LL);
  v5 =objc_retainAutoreleasedReturnValue(v4);
  v22 = v5;
  v6 =objc_msgSend(off_10000D2D0,(constchar*)off_10000D290,5LL);
  v7 =objc_retainAutoreleasedReturnValue(v6);
  v23 = v7;
  v8 =objc_msgSend(off_10000D2D0,(constchar*)off_10000D290,18LL);
  v9 =objc_retainAutoreleasedReturnValue(v8);
  v24 = v9;
  v10 =objc_msgSend(off_10000D2D8,(constchar*)off_10000D298,&v21,4LL);
  v16 =(void*)objc_retainAutoreleasedReturnValue(v10);objc_release(v9);objc_release(v7);objc_release(v5);objc_release(v3);for( i =0; i <(unsigned __int64)objc_msgSend(v16,(constchar*)off_10000D2A0);++i ){
    v11 =objc_msgSend(v16,(constchar*)off_10000D2A8, i);
    v12 =(void*)objc_retainAutoreleasedReturnValue(v11);
    v13 =(unsigned __int64)objc_msgSend(v12,(constchar*)off_10000D2B0);objc_release(v12);if( v13 == v17 ){
      v17 +=10;objc_storeStrong(&v18);}}NSLog(&stru_1000080B8);NSLog(&stru_1000080D8);objc_storeStrong(&v16);
  result =objc_storeStrong(&v18);*(_QWORD *)__stack_chk_guard_ptr;return result;}

开启ollvm混淆:

image-20230225230816138

image-20230225230917524

image-20230225230955135

image-20230225231054363

image-20230225231343858

混淆参数:-mllvm -fla -mllvm -bcf -mllvm -sub -mllvm -split -mllvm -sobf

混淆后效果如下:

__int64 __fastcall -[ViewController testMethod](__int64 a1, __int64 a2){void*v2;// x0void*v3;// x0
  __int64 v4;// ST58_8void*v5;// x0
  __int64 v6;// ST50_8void*v7;// x0
  __int64 v8;// ST48_8void*v9;// x0void*v10;// x0signedint v11;// w8
  BOOL v12;// w9signedint v13;// w8
  BOOL v14;// w9signedint v15;// w8
  BOOL v16;// w14signedint v17;// w8void*v18;// x0void*v19;// ST20_8int v20;// ST2C_4
  BOOL v21;// w12signedint v22;// w8
  BOOL v23;// w9signedint v24;// w8
  BOOL v25;// w12signedint v26;// w8signedint v27;// w8
  BOOL v28;// w9signedint v29;// w8
  BOOL v30;// w12signedint v31;// w8
  BOOL v32;// w14signedint v33;// w8
  BOOL v34;// w9signedint v35;// w8void*v37;// x0void*v38;// ST08_8int v39;// ST14_4signedint v40;// [xsp+94h] [xbp-DCh]int v41;// [xsp+98h] [xbp-D8h]int v42;// [xsp+9Ch] [xbp-D4h]void*v43;// [xsp+A0h] [xbp-D0h]int v44;// [xsp+ACh] [xbp-C4h]
  __int64 v45;// [xsp+B0h] [xbp-C0h]
  __int64 v46;// [xsp+B8h] [xbp-B8h]
  __int64 v47;// [xsp+C0h] [xbp-B0h]
  __int64 v48;// [xsp+C8h] [xbp-A8h]
  __int64 *v49;// [xsp+D0h] [xbp-A0h]constchar*v50;// [xsp+D8h] [xbp-98h]void*v51;// [xsp+E0h] [xbp-90h]
  __int64 v52;// [xsp+E8h] [xbp-88h]unsigned __int64 v53;// [xsp+F0h] [xbp-80h]constchar*v54;// [xsp+F8h] [xbp-78h]void*v55;// [xsp+100h] [xbp-70h]void*v56;// [xsp+108h] [xbp-68h]
  __int64 v57;// [xsp+110h] [xbp-60h]
  bool v58;// [xsp+11Fh] [xbp-51h]
  __int64 *v59;// [xsp+120h] [xbp-50h]int v60;// [xsp+128h] [xbp-48h]int v61;// [xsp+12Ch] [xbp-44h]
  __int64 v62;// [xsp+130h] [xbp-40h]
  __int64 v63;// [xsp+138h] [xbp-38h]
  __int64 v64;// [xsp+140h] [xbp-30h]
  __int64 v65;// [xsp+148h] [xbp-28h]
  __int64 v66;// [xsp+150h] [xbp-20h]
  __int64 v67;// [xsp+158h] [xbp-18h]

  v67 =*(_QWORD *)__stack_chk_guard_ptr;
  v47 = a1;
  v46 = a2;
  v45 =objc_retain(&stru_10000C078);
  v44 =18;
  v2 =objc_msgSend(off_1000112D0,(constchar*)off_100011290,1LL);
  v48 =objc_retainAutoreleasedReturnValue(v2);
  v63 = v48;
  v49 =&v64;
  v50 =(constchar*)off_100011290;
  v51 = off_1000112D0;
  v40 =-1933834049;while(1){while(1){while(1){while(1){while(1){while(1){while(1){while( v40 ==-1944675086){
                  v23 = x_24 *(x_24 -1)%2u==0;if(((unsigned __int8)v23 &(y_25 <10)| v23 ^(y_25 <10))&1)
                    v24 =-484710506;else
                    v24 =-757913245;
                  v40 = v24;}if( v40 !=-1933834049)break;
                v3 =objc_msgSend(v51, v50,3LL);
                v52 =objc_retainAutoreleasedReturnValue(v3);
                v40 =-1240448313;}if( v40 !=-1917278325)break;
              v40 =1916623537;}if( v40 !=-1863636706)break;if( v58 )
              v27 =-1295475565;else
              v27 =-706815919;
            v40 = v27;}if( v40 !=-1847141909)break;
          v10 =objc_msgSend(v55, v54);if( v53 >=(unsigned __int64)v10 )
            v11 =1801130365;else
            v11 =1380523063;
          v40 = v11;}if( v40 !=-1846767803)break;
        v40 =-267481379;}if( v40 !=-1502917571)break;
      v54 =(constchar*)off_1000112A0;
      v55 = v43;
      v40 =-1847141909;}if( v40 ==-1361227290)break;switch( v40 ){case-1295475565:
        v44 +=10;
        v40 =1987329712;break;case-1240448313:
        v4 = v52;*v49 = v52;
        v5 =objc_msgSend(off_1000112D0,(constchar*)off_100011290,5LL);
        v6 =objc_retainAutoreleasedReturnValue(v5);
        v65 = v6;
        v7 =objc_msgSend(off_1000112D0,(constchar*)off_100011290,18LL);
        v8 =objc_retainAutoreleasedReturnValue(v7);
        v66 = v8;
        v9 =objc_msgSend(off_1000112D8,(constchar*)off_100011298,&v63,4LL);
        v43 =(void*)objc_retainAutoreleasedReturnValue(v9);objc_release(v8);objc_release(v6);objc_release(v4);objc_release(v48);
        v42 =0;
        v40 =-381231803;break;case-1088106110:
        v40 =-1361227290;break;case-1009849083:
        v61 = v60 +1;
        v40 =-792637388;break;case-792637388:
        v42 = v61;
        v40 =-381231803;break;case-757913245:
        v40 =-484710506;break;case-706815919:
        v40 =975706093;break;case-484710506:
        v58 = v41 == v44;
        v25 = x_24 *(x_24 -1)%2u==0;if((!v25 ^(y_25 >=10)|(v25 && y_25 <10))&1)
          v26 =-1863636706;else
          v26 =-757913245;
        v40 = v26;break;case-381231803:
        v53 = v42;
        v40 =-1502917571;break;case-267481379:
        v56 = v43;
        v57 = v42;
        v14 = x_24 *(x_24 -1)%2u==0;if(((unsigned __int8)v14 &(y_25 <10)| v14 ^(y_25 <10))&1)
          v15 =-1917278325;else
          v15 =-1846767803;
        v40 = v15;break;case265667512:
        v60 = v42;
        v30 = x_24 *(x_24 -1)%2u==0;if((!v30 ^(y_25 >=10)|(v30 && y_25 <10))&1)
          v31 =1998138173;else
          v31 =1042960370;
        v40 = v31;break;case543048662:NSLog(&stru_10000C0B8);NSLog(&stru_10000C0D8);
        v34 = x_24 *(x_24 -1)%2u==0;if(((unsigned __int8)v34 &(y_25 <10)| v34 ^(y_25 <10))&1)
          v35 =-1088106110;else
          v35 =1393219629;
        v40 = v35;break;case818848043:
        v37 =objc_msgSend(v56,(constchar*)off_1000112A8, v57);
        v38 =(void*)objc_retainAutoreleasedReturnValue(v37);
        v39 =(unsigned __int64)objc_msgSend(v38,(constchar*)off_1000112B0);objc_release(v38);
        v41 = v39;
        v40 =1041770448;break;case975706093:
        v28 = x_24 *(x_24 -1)%2u==0;if(((unsigned __int8)v28 &(y_25 <10)| v28 ^(y_25 <10))&1)
          v29 =265667512;else
          v29 =1042960370;
        v40 = v29;break;case1041770448:
        v18 =objc_msgSend(v56,(constchar*)off_1000112A8, v57);
        v19 =(void*)objc_retainAutoreleasedReturnValue(v18);
        v20 =(unsigned __int64)objc_msgSend(v19,(constchar*)off_1000112B0);objc_release(v19);
        v41 = v20;
        v21 = x_24 *(x_24 -1)%2u==0;if((!v21 ^(y_25 >=10)|(v21 && y_25 <10))&1)
          v22 =2069967268;else
          v22 =818848043;
        v40 = v22;break;case1042960370:
        v40 =265667512;break;case1146841418:
        v32 = x_24 *(x_24 -1)%2u==0;if((v32 ^(y_25 <10)|(v32 && y_25 <10))&1)
          v33 =543048662;else
          v33 =1393219629;
        v40 = v33;break;case1380523063:
        v12 = x_24 *(x_24 -1)%2u==0;if(((unsigned __int8)v12 &(y_25 <10)| v12 ^(y_25 <10))&1)
          v13 =-267481379;else
          v13 =-1846767803;
        v40 = v13;break;case1393219629:NSLog(&stru_10000C0B8);NSLog(&stru_10000C0D8);
        v40 =543048662;break;case1801130365:
        v62 = v45;
        v40 =1146841418;break;case1916623537:
        v16 = x_24 *(x_24 -1)%2u==0;if((v16 ^(y_25 <10)|(v16 && y_25 <10))&1)
          v17 =1041770448;else
          v17 =818848043;
        v40 = v17;break;case1987329712:
        v59 =&v45;
        v40 =2123926658;break;case1998138173:
        v40 =-1009849083;break;case2069967268:
        v40 =-1944675086;break;case2123926658:objc_storeStrong(v59);
        v40 =-706815919;break;}}objc_storeStrong(&v43);returnobjc_storeStrong(&v45);}

总结

简单的入门文章,希望能帮助到你。

提示:阅读此文档的过程中遇到任何问题,请关住工众好【*

移动端Android和iOS开发技术分享

】或+99 君羊【

812546729

*】

image-20230225231548837

标签: ios 安全

本文转载自: https://blog.csdn.net/a3221002/article/details/129245112
版权归原作者 移动端小陈 所有, 如有侵权,请联系我们删除。

“【iOS逆向与安全】使用ollvm混淆你的源码”的评论:

还没有评论