前言

当你在钻研他人源码的时候,是不是冀望着他人代码没有进行任何的防护和混同。这时的你,是不是应该考虑一下本人代码的平安.本篇文章将通知你,如何应用ollvm来混同iOS端的代码【此文为入门贴,大佬请绕道】。

一、指标

编译ollvm工具,并在Xcode中来混同你的ipa或动静库,减少他人破解你源码的难度。

二、工具

ollvm:下载地址:https://github.com/heroims/ob...
Xcode13:iOS开发工具

三、步骤

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曾经被广泛应用于许多畛域,例如网络安全、游戏开发和金融等。

IR之间的pass,就是混同器工作的中央。相干代码位于obfuscator/llvm/lib/Transforms/Obfuscation/

2、编译ollvm

命令如下:

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

注:make -j8这命令编译的快慢,取决于你的硬件设施挨个执行以上命令后,ollvm就编译并装置实现,成果如下:

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_8  void *v4; // x0  __int64 v5; // ST68_8  void *v6; // x0  __int64 v7; // ST60_8  void *v8; // x0  __int64 v9; // ST58_8  void *v10; // x0  void *v11; // x0  void *v12; // ST20_8  int v13; // ST2C_4  __int64 result; // x0  int 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, (const char *)off_10000D290, 1LL);  v3 = objc_retainAutoreleasedReturnValue(v2);  v21 = v3;  v4 = objc_msgSend(off_10000D2D0, (const char *)off_10000D290, 3LL);  v5 = objc_retainAutoreleasedReturnValue(v4);  v22 = v5;  v6 = objc_msgSend(off_10000D2D0, (const char *)off_10000D290, 5LL);  v7 = objc_retainAutoreleasedReturnValue(v6);  v23 = v7;  v8 = objc_msgSend(off_10000D2D0, (const char *)off_10000D290, 18LL);  v9 = objc_retainAutoreleasedReturnValue(v8);  v24 = v9;  v10 = objc_msgSend(off_10000D2D8, (const char *)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, (const char *)off_10000D2A0); ++i )  {    v11 = objc_msgSend(v16, (const char *)off_10000D2A8, i);    v12 = (void *)objc_retainAutoreleasedReturnValue(v11);    v13 = (unsigned __int64)objc_msgSend(v12, (const char *)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混同:


混同参数:-mllvm -fla -mllvm -bcf -mllvm -sub -mllvm -split -mllvm -sobf混同后成果如下:

__int64 __fastcall -[ViewController testMethod](__int64 a1, __int64 a2){  void *v2; // x0  void *v3; // x0  __int64 v4; // ST58_8  void *v5; // x0  __int64 v6; // ST50_8  void *v7; // x0  __int64 v8; // ST48_8  void *v9; // x0  void *v10; // x0  signed int v11; // w8  BOOL v12; // w9  signed int v13; // w8  BOOL v14; // w9  signed int v15; // w8  BOOL v16; // w14  signed int v17; // w8  void *v18; // x0  void *v19; // ST20_8  int v20; // ST2C_4  BOOL v21; // w12  signed int v22; // w8  BOOL v23; // w9  signed int v24; // w8  BOOL v25; // w12  signed int v26; // w8  signed int v27; // w8  BOOL v28; // w9  signed int v29; // w8  BOOL v30; // w12  signed int v31; // w8  BOOL v32; // w14  signed int v33; // w8  BOOL v34; // w9  signed int v35; // w8  void *v37; // x0  void *v38; // ST08_8  int v39; // ST14_4  signed int 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]  const char *v50; // [xsp+D8h] [xbp-98h]  void *v51; // [xsp+E0h] [xbp-90h]  __int64 v52; // [xsp+E8h] [xbp-88h]  unsigned __int64 v53; // [xsp+F0h] [xbp-80h]  const char *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, (const char *)off_100011290, 1LL);  v48 = objc_retainAutoreleasedReturnValue(v2);  v63 = v48;  v49 = &v64;  v50 = (const char *)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 = (const char *)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, (const char *)off_100011290, 5LL);        v6 = objc_retainAutoreleasedReturnValue(v5);        v65 = v6;        v7 = objc_msgSend(off_1000112D0, (const char *)off_100011290, 18LL);        v8 = objc_retainAutoreleasedReturnValue(v7);        v66 = v8;        v9 = objc_msgSend(off_1000112D8, (const char *)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;      case 265667512:        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;      case 543048662:        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;      case 818848043:        v37 = objc_msgSend(v56, (const char *)off_1000112A8, v57);        v38 = (void *)objc_retainAutoreleasedReturnValue(v37);        v39 = (unsigned __int64)objc_msgSend(v38, (const char *)off_1000112B0);        objc_release(v38);        v41 = v39;        v40 = 1041770448;        break;      case 975706093:        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;      case 1041770448:        v18 = objc_msgSend(v56, (const char *)off_1000112A8, v57);        v19 = (void *)objc_retainAutoreleasedReturnValue(v18);        v20 = (unsigned __int64)objc_msgSend(v19, (const char *)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;      case 1042960370:        v40 = 265667512;        break;      case 1146841418:        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;      case 1380523063:        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;      case 1393219629:        NSLog(&stru_10000C0B8);        NSLog(&stru_10000C0D8);        v40 = 543048662;        break;      case 1801130365:        v62 = v45;        v40 = 1146841418;        break;      case 1916623537:        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;      case 1987329712:        v59 = &v45;        v40 = 2123926658;        break;      case 1998138173:        v40 = -1009849083;        break;      case 2069967268:        v40 = -1944675086;        break;      case 2123926658:        objc_storeStrong(v59);        v40 = -706815919;        break;    }  }  objc_storeStrong(&v43);  return objc_storeStrong(&v45);}

总结简略的入门文章,心愿能帮忙到你。提醒:浏览此文档的过程中遇到任何问题,请关住工众好【挪动端Android和iOS开发技术分享】或+99 君羊【812546729】