技术解读

以下内容由 GitRead 中文社区 编辑团队基于项目 README 与官方资料整理, 结合中文开发者的常见使用场景补充技术选型建议。具体以项目官方文档为准。

JonathanSalwan/Tigress_protection 项目深度技术分析

项目背景与痛点

在软件保护领域,Tigress 是一种知名的软件保护技术,通过复杂的代码混淆手段来增加逆向工程的难度,从而保护企业的知识产权。JonathanSalwan/Tigress_protection 是一个开源项目,其目的不仅仅是对 Tigress 保护软件进行逆向分析,更是通过自动化去混淆来解决安全性与实用性之间的矛盾。该项目提供了自动化的去混淆工具,使用了符号执行(Symbolic Execution)、污点传播分析(Taint Analysis)以及 LLVM 等技术,显著提高了安全分析和逆向工程技术的效率。在当前复杂的网络安全环境下,具有重要的实践价值。

核心技术揭秘

该项目在技术上采用了多种高级分析手段,其核心技术主要包括符号执行、污点传播分析、LLVM 编译器基础设施等。项目通过这些技术的组合实现对被保护软件的自动化去混淆处理,以下是这个框架的一些核心组件说明:

  1. 符号执行:用于模拟程序的所有可能执行路径,并检查特定条件,有助于高效地探索和分析程序逻辑。

  2. 污点传播分析:通过跟踪数据流,从输入数据开始,确定哪些数据被污染,这有助于识别被保护软件中的关键逻辑。

  3. LLVM 编译器基础设施:利用 LLVM 的强大能力对已分析的源代码进行重新编译和进一步优化。

项目如何协调这些组件,如何流转数据,让我们通过一张架构图来更清晰地了解:

graph TD A[用户上传软件] --> B("符号执行工具") B --> C{"分析结果"} C -->|"成功"| D("污点传播分析") C -->|"失败"| E[返回错误] D --> F("LLVM 编译器") F --> G[去混淆后的输出] G --> H[验证与评估]

从架构图中可以看出用户上传软件后,符号执行工具首先开始模拟,若分析成功则将结果传递给污点传播分析。最终,LLVM 编译器完成去混淆和输出。

功能亮点与差异

该项目相比其他软件保护逆向分析工具,其亮点在于:

  • 自动化和高效性:通过自动化流程提高处理效率和精度。
  • 多层次分析:不仅局限于单一技术,而是结合符号执行、污点分析等进行多层次处理。
  • 灵活性和扩展性:基于 LLVM 的架构设计提供很强的扩展能力,便于添加新的支持。

应用场景与落地建议

Tigress_protection 适用于进行软件逆向工程分析的企业和个人,尤其在检测或恢复商业软件保护时。使用此工具请注意如下几点:

  • 输入程序的语言版本与 Libelf 的兼容性。
  • 符号执行部分可能会消耗大量内存和时间,需合理预估。
  • 建议在适当的安全环境中部署,避免对生产环境造成影响。

综合评价

总体而言,Tigress_protection 项目旨在简化复杂软件保护技术的分析步骤,提供了强大的反混淆工具,大大降低了逆向工程的难度。但是,自动化工具本身在处理完全未知的复杂保护技术时,可能会有局限。因此,项目依然有很大发展空间,尤其是适应性方面。

优点:

  • 优点明显在于自动化卸载繁杂的逆向工程任务。
  • 结合了多种分析技术,使得去混淆过程更加高效、准确。

缺点:

  • 某些高级保护机制可能无法直接解析。
  • 长度和复杂度较高,要求有一定的逆向工程经验。

关于

GitHub 原始描述(英文)

Playing with the Tigress software protection. Break some of its protections and solve their reverse engineering challenges. Automatic deobfuscation using symbolic execution, taint analysis and LLVM.

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

语言占比

C
C++
CMake
Dockerfile
LLVM
Perl
Python
Shell

README

Tigress Protections

Tigress is a diversifying virtualizer/obfuscator for the C language that supports many novel defenses against both static and dynamic reverse engineering and de-virtualization attacks. In particular, Tigress protects against static de-virtualization by generating virtual instruction sets of arbitrary complexity and diversity, by producing interpreters with multiple types of instruction dispatch, and by inserting code for anti alias analysis. Tigress protects against dynamic de-virtualization by merging the real code with bogus functions, by inserting implicit flow, and by creating slowly-executing reenetrant interpreters. Tigress implements its own version of code packing through the use of runtime code generation. Finally, Tigress’ dynamic transformation provides a generalized form of continous runtime code modification.

Tigress Challenge

Tigress team has provided some challenges where we can find different kind of protections

  • VM-0: One level of virtualization, random dispatch.
  • VM-1: One level of virtualization, superoperators, split instruction handlers.
  • VM-2: One level of virtualization, bogus functions, implicit flow.
  • VM-3: One level of virtualization, instruction handlers obfuscated with arithmetic encoding, virtualized function is split and the split parts merged.
  • VM-4: Two levels of virtualization, implicit flow.
  • VM-5: One level of virtualization, one level of jitting, implicit flow.
  • VM-6: Two levels of jitting, implicit flow.

Challenge Format

All challenges take as input a number and return a hash. Example:

$ ./obfuscated_binaries/tigress-2-challenge-2 1234
202180712448

$ ./obfuscated_binaries/tigress-2-challenge-2 823748
50564355584

$ ./obfuscated_binaries/tigress-2-challenge-2 2834723
50714072576

The hash computation function is obfuscated. Types of possible attacks:

  • In a source recovery attack the task is to identify the algorithm that computes SECRET.
  • In a data recovery attack the task is to extract a specific run-time or compile-time data item.
  • In a metadata recovery attack the task is to identify the sequence of transformations that resulted in SECRET, along with arguments to those transformations, such as the dispatch method used in a virtualization.
  • In a location attack the task is to identify the code bytes of the program that comprise the obfuscated SECRET function.

Automatic deobfuscation

Our goals were to:

  • Symbolically extract the hash algorithm
  • Simplify these symbolic expressions
  • Provide a new simplified version of the binary

And all of this with only one generic script :). To do so, we made in the following order:

  • Parse protected binaries with LIEF
  • Symbolically emulate the obfuscated binary with Triton
  • Concretize everything which are not related to the user input.
  • Convert Triton’s expressions to the Arybo’s expressions
  • Convert Arybo’s expressions to the LLVM-IR representation
  • Apply LLVM optimizations (O2)
  • Rebuild a simplified binary version

If you want more information, you can checkout our solve-vm.py script.

Deobfuscation Process

solve-vm.py

However, we already pushed all of our results in this repository but if you want to reproduce by yourself this analysis, you only have to do execute solve-vm.py like this:

$ ./solve-vm.py ./obfuscated_binaries/_binary_

Example:

$ ./solve-vm.py ./tigress-challenges/tigress-0-challenge-0
[+] Loading 0x400040 - 0x400238
[+] Loading 0x400238 - 0x400254
[+] Loading 0x400000 - 0x400f14
[+] Loading 0x601e28 - 0x602550
[+] Loading 0x601e50 - 0x601fe0
[+] Loading 0x400254 - 0x400298
[+] Loading 0x400dc4 - 0x400e08
[+] Loading 0x000000 - 0x000000
[+] Loading 0x601e28 - 0x602000
[+] Hooking printf
[+] Hooking __libc_start_main
[+] Hooking strtoul
[+] Starting emulation.
[+] __libc_start_main hooked
[+] argv[0] = ./tigress-challenges/tigress-0-challenge-0
[+] argv[1] = 1234
[+] strtoul hooked
[+] Symbolizing the strtoul return
[+] printf hooked
3035321144166078008
[+] Slicing end-point user expression
[-] Instruction not supported: 0x400539: hlt
[+] Instruction executed: 39816
[+] Unique instruction executed: 458
[+] PC len: 0
[+] Emulation done.
[+] Generating symbolic_expressions/tigress-0-challenge-0.py
[+] Converting symbolic expressions to an LLVM module...
[+] LLVM module wrote in llvm_expressions/tigress-0-challenge-0.ll
[+] Recompiling deobfuscated binary...
[+] Deobfuscated binary recompiled: deobfuscated_binaries/tigress-0-challenge-0.deobfuscated

Then, symbolic expressions can be found here, LLVM representations can be found here and recompiled binaries can be found here.

Using Docker:

$ git clone [email protected]:JonathanSalwan/Tigress_protection.git
$ cd /path/to/Tigress_protection
$ docker build -t image_tigress_protection . 
$ docker run -v /path/to/Tigress_protection:/root/Tigress_protection -ti --name=tigress_protection --ulimit='stack=-1:-1' image_tigress_protection

Test inside Docker container

# cd ~/Tigress_protection
# ./solve-vm.py tigress-challenges/tigress-0-challenge-0

Testing our simplified binaries

As we simplified and recompiled new binaries, we must provide the same behavior of the original binaries. So, to test our binary versions we use this script.

$ ./scripts/testing_equality.py ./tigress-challenges/tigress-0-challenge-0 ./deobfuscated_binaries/tigress-0-challenge-0.deobfuscated
[...]
[+] Success with 272966812638982633
[+] Success with 2304147855662358786
[+] Success with 15697842028176298504
[+] Success with 15273138908025273913
[+] Success with 17329851347176088980
[+] Success with 12160831137213706322
[+] Success with 3489058267725840982
[+] Success with 6474275930952607745
[+] Success with 7363567981237584398
[+] Success with 3685039181436704621
[+] Success: 100.00

Basically, this script runs the obfuscated and the deobfuscated binaries with random inputs and checks if they have the same output results.

Regarding the Tigress challenge, what are results?

Tigress results

Concerning the table of ratios, after solved Tigress challenges we asked to Christian Collberg the sources of its challenges in order to compare the size the original sources and our devirtualized versions. Note that at the request of Christian, we cannot provide sources of the Tigress challenges, if you want these sources please directly ask to him :).

Testing our approach on others binaries

We also pick up 20 hash algorithms (10 well-known, 10 from the Tigress challenge) and we protected each one of these algorithms using 46 different Tigress protections (see next section). At the end, we have a test bench of 920 protected binaries. Each one of these protected binaries has been successfully devirtualized using the solve-vm.py script. These hash algorithms can be found in the samples directory and their devirtualized versions into the deobfuscated_binaries directory. The following table is a summary of our results regarding our 920 samples.

Summary of results

Regarding Tigress protections, what did we break?

  • Anti Branch Analysis (options: goto2push, goto2call, branchFuns)
  • Max Merge Length (options: 0, 10, 20, 30)
  • Bogus Function (options: 0, 1, 2, 3)
  • Kind of Operands (options: stack, registers)
  • Opaque to VPC (options: true, false)
  • Bogus Loop Iterations (options: 0, 1, 2, 3)
  • Super Operator Ratio (options: 0, 0.2, 0.4, 0.6, 0.8, 1.0)
  • Random Opcodes (options: true, false)
  • Duplicate Opcodes (options: 0, 1, 2, 3)
  • Dispatcher (options: binary, direct, call, interpolation, indirect, switch, ifnest, linear)
  • Encode Byte Array (options: true, false)
  • Obfuscate Decoder (options: true, false)
  • Nested VMs (options: 1, 2, 3)

For more information about these options see pages 1 and 2.

Publication

Authors

Thanks to

评论

暂无评论