IOS逆向-LLVM、代码混淆

article/2025/10/17 0:22:47

LLVM、代码混淆

  • 1 LLVM
  • 1.1 传统编译架构
    • 1.2 LLVM的编译架构
    • 1.3 Clang
      • 1.3.1 什么是Clang
      • 1.3.2 Clang与LLVM
  • 2. OC源文件的编译过程
    • 2.1 编译过程和预编译
    • 2.2 词法分析
    • 2.3 语法树-AST
    • 2.4中间代码(LLVM IR)
  • 3. LLVM源码
    • 3.1 LLVM的源码下载
    • 3.2 源码编译
      • 3.2.1 ninja编译方式
      • 3.2.2
  • 4 应用和实践
  • 5 clang插件开发
    • 5.1 clang插件开发1 – 插件目录
    • 5.2 clang插件开发2 – 插件必要文件
    • 5.3 clang插件开发3 – 编写插件源码
    • 5.4 clang插件开发4 – 编译插件
    • 5.5 clang插件开发5 – 加载插件
    • 5.6 clang插件开发6 – Hack Xcode
    • 5.7 clang插件开发7 – 修改Xcode的编译器
    • 5.8 clang插件开发8 – 编译项目
    • 5.9 clang插件开发9 – 更多
    • 5.10 提示警告、错误信息
    • 5.11 推荐书籍
  • 6 代码混淆
    • 6.1 基本概念
    • 6.2 IOS中代码混淆
      • 6.2.1 基本介绍
      • 6.2.2 源码的混淆 - 通过宏定义混淆方法名、类名
      • 6.2.3 iOS-class-guard
      • 6.2.4

1 LLVM

  • 什么是LLVM
    • 官网https://llvm.org
    • LLVM项目是模块化,可重用的编译器以及工具链技术的集合,LLVM不是首字母的缩写,它是项目名称

1.1 传统编译架构

在这里插入图片描述

  • Frontend:词法分析、语法分析、语义分析、生成中间代码
  • Optimizer:优化器(中间代码)
  • Backend:后端,生成机器码

1.2 LLVM的编译架构

  • 不同的前端后端使用统一的中间代码LLVM Intermediate Representation(LLVM IR)
  • 如果需要支持一种新的编程语言,那么只需要实现一个新的前端
  • 如果需要支持一种新的硬件设备,那么只需要实现一个新的 后端
  • 优化阶段是一个通用的阶段,它针对的是统一的LLVM IR,不论是支持新的变成语言,还是支持新的硬件设备,都不需要对优化阶段做修改
  • 相比之下,GCC的全段和后端没分的太开,前端和后端耦合在一起,所以GCC为了支持一门新的语言,或则为了支持一个新的目标平台,就变的特别困难
  • LLVM现在被作为实现各种金泰和运行编译语言的通用基础(GCC家族、Java、.NET、Python、Ruby、Scheme、Haskell、D等)
    在这里插入图片描述

1.3 Clang

1.3.1 什么是Clang

  • 什么是Clang?
    • LLVM项目的一个子项目
    • 基于LLVM架构的C/C++/Objective-C编译器前端
    • 官网:http://clang.llvm.org/
  • 相比于GCC,Clang具有如下优点:
    • 编译速度快:在某些平台上,Clang的编译速度显著的快过GCC(Debug模式下编译OC速度比GGC快3倍)
    • 占用内存小:Clang生成的AST所占用的内存是GCC的五分之一左右
    • 模块化设计:Clang采用基于库的模块化设计,易于 IDE 集成及其他用途的重用
    • 诊断信息可读性强:在编译过程中,Clang 创建并保留了大量详细的元数据 (metadata),有利于调试和错误报告
    • 设计清晰简单,容易理解,易于扩展增强

1.3.2 Clang与LLVM

  • 广义上的LLVM: 整个LLVM架构
  • 狭义的LLVM:LLVM后端(代码优化、目标代码生成等)

在这里插入图片描述
在这里插入图片描述

2. OC源文件的编译过程

2.1 编译过程和预编译

#include <stdio.h>#define AGE 40
int main(int argc, const char * argv[]) {int a = 10;int b = 20;int c = a + b + AGE;return 0;
}
  • 命令行查看编译的过程:clang -ccc-print-phases main.m
    在这里插入图片描述

  • 查看preprocessor(预处理)的结果: clang -E main.m
    在这里插入图片描述

我们可以看到预编译做了很多事情,然后宏定义在预编译期就被替换了

2.2 词法分析

  • 词法分析,生成Token: clang -fmodules -E -Xclang -dump-tokens main.m
void test(int a, int b) {int c = a + b - 3;
}

在这里插入图片描述

2.3 语法树-AST

  • 语法分析,生成语法树(AST,Abstract Syntax Tree): clang -fmodules -fsyntax-only -Xclang -ast-dump main.m
    在这里插入图片描述
    在这里插入图片描述

2.4中间代码(LLVM IR)

  • LLVM IR有3种表示形式(但本质是等价的,就好比水可以有气体、液体、固体3种形态)
  • text:便于阅读的文本格式,类似于汇编语言,拓展名.ll, clang -S -emit-llvm main.m
  • memory:内存格式
  • bitcode:二进制格式,拓展名.bc, clang -c -emit-llvm main.m

main.ll的代码:
在这里插入图片描述

  • IR基本语法:
    • 注释以分号 ; 开头
    • 全局标识符以@开头,局部标识符以%开头
    • alloca,在当前函数栈帧中分配内存
    • i32,32bit,4个字节的意思
    • align,内存对齐
    • store,写入数据
    • load,读取数据
  • 官方语法参考:https://llvm.org/docs/LangRef.html

3. LLVM源码

3.1 LLVM的源码下载

  • 下载LLVM: git clone https://git.llvm.org/git/llvm.git/
  • 下载clang:cd llvm/tools (需要进入LLVM的源码目录下的Tools文件夹,然后下载clang源码),然后执行:git clone https://git.llvm.org/git/clang.git/
  • clang编译器其实Xcode是带有的,我们可以查看下:
    在这里插入图片描述

3.2 源码编译

3.2.1 ninja编译方式

  • 安装cmake和ninja(先安装brew,https://brew.sh/)
    • brew install cmake
    • brew install ninja
  • ninja如果安装失败,可以直接从github获取release版放入【/usr/local/bin】
    • https://github.com/ninja-build/ninja/releases
  • 在LLVM源码同级目录下新建一个【llvm_build】目录(最终会在【llvm_build】目录下生成【build.ninja】,表示成功)
    • cd llvm_build
    • cmake -G Ninja ../llvm -DCMAKE_INSTALL_PREFIX=LLVM的安装路径:编译Ninja模板
    • 更多cmake相关选项,可以参考:https://llvm.org/docs/CMake.html
  • 依次执行编译、安装指令
    • ninja
    • 编译完毕后, 【llvm_build】目录大概 21.05 G(仅供参考)
    • ninja install
    • 安装完毕后,安装目录大概 11.92 G(仅供参考)
      在这里插入图片描述

3.2.2

  • 也可以生成Xcode项目再进行编译,但是速度很慢(可能需要1个多小时)
  • 在llvm同级目录下新建一个【llvm_xcode】目录
  • cd llvm_xcode
  • cmake -G Xcode ../llvm

生成xcode项目在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4 应用和实践

  • libclang、libTooling
    • 官方参考:https://clang.llvm.org/docs/Tooling.html
    • 应用:语法树分析、语言转换等
  • Clang插件开发
    • 官方参考:
      • https://clang.llvm.org/docs/ClangPlugins.html
      • https://clang.llvm.org/docs/ExternalClangExamples.html
      • https://clang.llvm.org/docs/RAVFrontendAction.html
      • 应用:代码检查(命名规范、代码规范)
  • Pass开发
    • 官方参考: https://llvm.org/docs/WritingAnLLVMPass.html
      • 应用:代码优化、代码混淆
  • 开发新的编程语言
    • https://llvm-tutorial-cn.readthedocs.io/en/latest/index.html
    • https://kaleidoscope-llvm-tutorial-zh-cn.readthedocs.io/zh_CN/latest/

5 clang插件开发

5.1 clang插件开发1 – 插件目录

  • 【clang/tools】源码目录下新建一个插件目录,假设叫做【mj-plugin】

在这里插入图片描述

  • 在【clang/tools/CMakeLists.txt】最后加入内容: add_clang_subdirectory(mj-plugin),小括号里是插件目录名

在这里插入图片描述

5.2 clang插件开发2 – 插件必要文件

  • 在【mj-plugin】目录下新建一个【CMakeLists.txt】,文件内容是:add_llvm_loadable_module(MJPlugin MJPlugin.cpp)
    • MJPlugin是插件名,MJPlugin.cpp是源代码文件

在这里插入图片描述
在这里插入图片描述

5.3 clang插件开发3 – 编写插件源码

  • 【MJPlugin.cpp】参考

在这里插入图片描述

5.4 clang插件开发4 – 编译插件

  • 利用cmake生成的Xcode项目来编译插件(第一次编写完插件,需要利用cmake重新生成一下Xcode项目)
    • 插件源代码在【Sources/Loadable modules】目录下可以找到,这样就可以直接在Xcode里编写插件代码
    • 选择MJPlugin这个target进行编译,编译完会生成一个动态库文件

在这里插入图片描述

5.5 clang插件开发5 – 加载插件

  • 在Xcode项目中指定加载插件动态库:Build Settings > OTHER_CFLAGS
  • -Xclang -load -Xclang 动态库路径 -Xclang -add-plugin -Xclang 插件名称

在这里插入图片描述

5.6 clang插件开发6 – Hack Xcode

  • 首先要对Xcode进行Hack,才能修改默认的编译器
    • 下载【XcodeHacking.zip】,解压,修改【HackedClang.xcplugin/Contents/Resources/HackedClang.xcspec】的内容,设
      置一下自己编译好的clang的路径

在这里插入图片描述

  • 然后在XcodeHacking目录下进行命令行,将XcodeHacking的内容剪切到Xcode内部
    • sudo mv HackedClang.xcpluginxcode-select-printpath/../PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins
    • sudo mv HackedBuildSystem.xcspecxcode-select-printpath/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Specifications

5.7 clang插件开发7 – 修改Xcode的编译器

在这里插入图片描述

5.8 clang插件开发8 – 编译项目

  • 编译项目后,会在编译日志看到MJPlugin插件的打印信息(如果插件更新了,最好先Clean一下项目)

在这里插入图片描述

5.9 clang插件开发9 – 更多

  • 想要实现更复杂的插件功能,就需要利用clang的API针对语法树(AST)进行相应的分析和处理
  • 关于AST的资料
    • https://clang.llvm.org/doxygen/namespaceclang.html
    • https://clang.llvm.org/doxygen/classclang_1_1Decl.html
    • https://clang.llvm.org/doxygen/classclang_1_1Stmt.html

5.10 提示警告、错误信息

在这里插入图片描述

5.11 推荐书籍

在这里插入图片描述

6 代码混淆

6.1 基本概念

  • 什么是加固: 加固是为了增加应用的安全性,防止应用被破解、盗版、二次打包、注入、反编译等
  • 常见的加固方式有
    • 数据加密(字符串、网络数据、敏感数据等)
    • 应用加壳(二进制加密)
    • 代码混淆(类名、方法名、代码逻辑等)
    • …(不同平台还有不同的做法)

6.2 IOS中代码混淆

6.2.1 基本介绍

  • iOS程序可以通过class-dump、Hopper、IDA等获取类名、方法名、以及分析程序的执行逻辑
    • 如果进行代码混淆,可以加大别人的分析难度
  • iOS的代码混淆方案
    • 源码的混淆
      • 类名
      • 方法名
      • 协议名
    • LLVM中间代码IR的混淆(容易产生BUG)
      • 自己编写Pass
      • ollvm:https://github.com/obfuscator-llvm/obfuscator

6.2.2 源码的混淆 - 通过宏定义混淆方法名、类名

  • 使用pch文件中定义的宏定义来混淆代码,但是pch文件中是不会替换xib、storyboard中的 名称的,需要手动修改
    在这里插入图片描述

  • 注意点

    • 不能混淆系统方法
    • 不能混淆init开头的等初始化方法
    • 混淆属性时需要额外注意set方法
    • 如果xib、storyboard中用到了混淆的内容,需要手动修正
    • 可以考虑把需要混淆的符号都加上前缀,跟系统自带的符号进行区分
    • 混淆过多可能会被AppStore拒绝上架,需要说明用途
  • 建议

    • 给需要混淆的符号加上了一个特定的前缀
  • 小工具参考:https://github.com/CoderMJLee/MJCodeObfuscation

6.2.3 iOS-class-guard

  • 第三方工具
    • 下载链接: https://github.com/Polidea/ios-class-guard
    • 它是基于class-dump的扩展
    • 用class-dump扫描出可执行文件中的类名、方法名、属性名等并做替换,会更新xib和storyboard的名字等等
  • 用法
    • brew install ios-class-guard
    • ios-class-guard [options]
  • 常用参数
    • --sdk-root <path>:用于指定SDK路径,如果是模拟器SDK,一般路径就是/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk
    • --sdk-ios:相当于指定SDK路径为真机设备SDK
    • -X <path>:用于指定xib、storyboard所在目录,它会递归搜索
    • -O <path>:生成的混淆头文件路径
    • -m <path>: 符号映射表(默认是symbols.json)

6.2.4

  • 很多时候,可执行文件中的字符串信息,对破解者来说,非常关键,是破解的捷径之一
  • 为了加大破解、逆向难度,可以考虑对字符串进行加密
  • 字符串的加密技术有很多种,可以根据自己的需要自行制定算法
  • 这里举一个简单的例子
    • 对每个字符进行异或(^)处理
    • 需要使用字符串时,对异或()过的字符再进行一次异或(),就可以获得原字符

http://chatgpt.dhexx.cn/article/Xi4ZioPL.shtml

相关文章

【iOS逆向与安全】frida-trace入门

前言 frida-trace是一个用于动态跟踪函数调用的工具。支持android和ios。安装教程请参考官网。工欲善其事必先利其器。本文将以某App为示范&#xff0c;演示frida-trace的各种方法在iOS中的应用。 一、目标 让看文章的你在使用frida-trace时更得心应手。 二、工具 mac系统f…

iOS逆向之某茅台App抓包

阅读此文档的过程中遇到任何问题&#xff0c;请关注公众号移动端Android和iOS开发技术分享或加QQ群309580013 1.目标 由于某茅台App有抓包检测&#xff0c;无法直接使用charles等工具抓包。本文的目的自然就是如何修改源码并抓任意接口 2.依赖环境 frida-ios-dump&#xff1…

【iOS逆向与安全】iOS插件开发入门

前言 经过之前的学习&#xff0c;相信你已经能熟练的使用Frida-trace、IDA Pro等逆向工具。不过&#xff0c;仅仅到这肯定是不够的。接下来&#xff0c;学会把你逆向的结果打包成插件并运行&#xff0c;那iOS逆向&#xff0c;你也就真正的入门了。 一、目标 把逆向的结果制作成…

iOS逆向工程开发技巧

1. 将xib文件转成nib文件 ibtool --errors --warnings --output-format human-readable-text --compile ~/Desktop/001.nib ~/Desktop/HWTipsView.xib 2. 给framework添加指令集合并 lipo -create [地址&#xff1a;name1.framework/name1] [地址&#xff1a;name2.framewor…

iOS逆向动态调试

1.拷贝越狱手机/Developer/usr/bin目录下的debugserver到Mac电脑&#xff0c;在mac端输入 scp -P 2222 rootlocalhost:/Developer/usr/bin/debugserver ~/debugserver2.对debugserver进行瘦身(iOS11可以不用瘦身,因为只支持64位构架的程序)&#xff0c;在debugserver所在目录输…

ios逆向学习环境安装(一)

1、Xcode 历届版本&#xff1a;https://developer.apple.com/documentation/xcode-release-notes AppStore中搜并安装XCode & 在网页下载https://developer.apple.com/xcode 2、class-dump class-dump&#xff0c;是可以把Objective-C运行时的声明的信息导出来的工具。其实…

ios android 逆向 对比,iOS逆向开发--APP重签名

签名原理 在非越狱手机上要调试一个三方的APP&#xff0c;我们首先要对其重签名&#xff0c;跑在我们的手机上&#xff0c;我们才能对其进行进一步的动态和静态调试 要对一个APP包进行重签名&#xff0c;要有一个越狱的APP包&#xff0c;这个可以去PP助手上下载&#xff0c;也可…

IOS逆向-抓帧分析

背景 分析图形学、游戏等的时候&#xff0c;很多时候需要抓帧分析 步骤 动态调试APP点击 点击FPS&#xff0c;触发渲染&#xff0c;查看面板是否有数据点击&#x1f4f7;按钮&#xff0c;触发渲染再次点击&#x1f4f7;按钮&#xff0c;结束抓帧 问题 FPS数据面板没有数据…

IOS逆向-动态调试

文章目录 LLDBXcode重新签名版本调试(手动) ✅重新签名版本调试(自动)不重新签名版本调试 LLDB Xcode -> Attach -> 点击 || 按钮 -> 使用lldb终端 手机/Developer/usr/bin/debugserver localhost:2233 /var/containers/Bundle/Application/*/*/xxxx电脑 lldb -> …

IOS逆向初探

前言 这些文章用于记录学习路上的点点滴滴&#xff0c;也希望能给到刚入门的小伙伴们一点帮助。爱而所向&#xff0c;不负所心。 环境 iphone 6 MacOS Monterey 12.3.1 一、IOS开发语言 Objective-C Objective-C是iOS操作系统运用的软件开发语言。Objective-C的流行完全是因…

移动App入侵与逆向破解技术-iOS篇

如果您有耐心看完这篇文章,您将懂得如何着手进行app的分析、追踪、注入等实用的破解技术,另外,通过“入侵”,将帮助您理解如何规避常见的安全漏洞,文章大纲: 简单介绍ios二进制文件结构与入侵的原理介绍入侵常用的工具和方法,包括pc端和手机端讲解黑客技术中的静态分析和…

C#应用程序与MATLAB联合编程

本文主要结合C#编写应用程序方便强大和MATLAB在工业科学界的广泛应用&#xff0c;结合两者的优点&#xff0c;利用C#编写的windows桌面应用程序作为UI交互接收用户配置&#xff0c;并根据用户在前端应用界面的操作自动控制MATLAB运行&#xff0c;并将MATLAB计算的结果返回桌面应…

编程输出中文变问号的解决办法

问题是出现在windows的dos显示设置上。 如何解决这个问题&#xff1f; 1.打开运行&#xff0c;输入cmd&#xff1b; 2.界面顶部右键&#xff0c;option中选择默认值&#xff1b; 3.将437&#xff08;OEM-美国&#xff09;改为936&#xff08;ANSI/OEM-简体中文GBK&#xff09; …

Python入门(二)-编程环境

本章重点介绍 Python 编程环境的搭建&#xff0c;包括各个平台下 Python 的下载和安装&#xff0c;常见 IDE 的使用&#xff0c;如何运行 Python 程序等。我还会亲自带着大家编写并运行第一个 Python 程序&#xff0c;让大家认识一下最简单的 Python 代码。 本章的后半部分还介…

数模混合信号建模语言Verilog-AMS

混合信号建模语言Verilog-AMS 很多人做模拟电路的朋友&#xff0c;都希望有一款“模拟FPGA”&#xff0c;希望有一个“模拟的Verilog”&#xff0c;但现实是没有“模拟的Verilog”只有混合信号建模语言-Verilog-AMS&#xff0c;今天就简单介绍一下-Verilog-AMS。 为了便于物理系…

Java入门-Java语言概述

1、Java语言基本概述 1.1、什么是计算机编程语言 人与人之间是如何沟通的呢&#xff1f;从小父母就教会我们说话&#xff0c;在长期的熏陶和自我学习中&#xff0c;我们就学会了普通话&#xff0c;学会了表达自己的需求&#xff0c;父母收到我们的信号或者听到我们的要求也会尽…

Python 批量下载BiliBili视频 打包成软件

文章目录 一、项目概述1.项目背景2.环境配置下载ffmpeg设置环境变量 二、项目实施1.导入需要的库2.设置请求参数3.基本处理4.下载视频5.视频和音频合并成完整的视频6.3种下载方式的分别实现7.主函数 三、项目分析和说明1.结果测试改进说明2.软件打包3.改进分析4.合法性说明 如有…

Java 之父 James Gosling 最新访谈:JIT 很好,但不适合所有语言

计算机编程确实是一门艺术。 James Gosling&#xff0c;“Java 之父”, 完成了 Java 的原始设计&#xff0c;并实现了 Java 最初版本的编译器和虚拟机。 90年代初&#xff0c;James Gosling和一群技术人员合作“绿色计划”&#xff0c;创建了一个名为Oak的项目&#xff0c;旨在…

Python语言概述及其运行机制详解

即日起&#xff0c;我们将打开一个新的编程世界的大门——Python语言。Python是一种跨平台的计算机程序设计语言。是一种面向对象的动态类型语言&#xff0c;最初被设计用于编写自动化脚本(shell)&#xff0c;随着版本的不断更新和语言新功能的添加&#xff0c;越来越多被用于独…

go语言开发环境搭建

Go 是一个开源的编程语言&#xff0c;它能让构造简单、可靠且高效的软件变得容易。 Go语言专门针对多处理器系统应用程序的编程进行了优化&#xff0c;使用Go编译的程序可以媲美C或C代码的速度&#xff0c;而且更加安全、支持并行进程。 学习Go一部分是兴趣&#xff0c;一部分是…