首页
社区
课程
招聘
未解决 [求助]ollvm反混淆工具的选择
发表于: 2024-1-22 10:51 5280

未解决 [求助]ollvm反混淆工具的选择

2024-1-22 10:51
5280

我最近遇到一些ollvm混淆的pe文件搞不定,查了下有不少框架可以用来做反混淆,unicorn,angr,triton,barf,miasm...我的目标是把ollvm还原成正常的伪代码,但搞不清楚什么场景应该选择什么工具,想求助大佬们几个问题。

  1. unicorn、qiling模拟执行,unicorn模拟cpu指令执行的结果,qiling在unicorn的基础上做了扩展,支持系统调用的模拟。这和调试似乎有点类似,为什么模拟执行可以用来反混淆?
  2. 符号执行没有学过不懂,看angr_ctf说是可以用来解crackme,有点类似解方程。符号执行具体是怎么应用在反混淆上的呢?
  3. 学习路线/学习资料?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
最新回复 (7)
雪    币: 5
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
pe用miasm,triton的多估计
2024-1-22 15:19
1
雪    币: 203
活跃值: (1274)
能力值: ( LV9,RANK:195 )
在线值:
发帖
回帖
粉丝
3
miasm用的比较多
2024-1-25 15:05
1
雪    币: 14
活跃值: (285)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
这些都是基础的运行环境或者运行框架 unicorn这类肯定是必须要有的 但是要完成你的去除混淆逻辑代码的效果 直接使用这些工具都是不能达到目的
2024-4-3 11:11
1
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
感觉可以试试LLVM去混淆框架,在外网还看过拿这个去VMP虚拟化的文章。这玩意可以拿来还原二进制文件,个人比较看好它的潜能,一个是LLVM IR的可操作性、文档、生态都比较好,还有就是因为本质上是代码的同语义变换,我觉得可以做一些额外的事,也许是辅助理解Shellcode,也许是处理一些叫不上名字的混淆手法(这里点名微软)
2024-8-25 18:59
1
雪    币: 16
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
同意
2024-11-16 20:08
0
雪    币: 1555
活跃值: (4665)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
tron主要用来逆向分析算法的
5天前
0
雪    币: 1555
活跃值: (4665)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
Q:
有个场景,在这个函数内,他经过多重加密多重拷贝,最后得到一个数据,我要如何做?

A:太棒了!你已经完成了最困难的部分——靠自己的经验和智慧理解了算法。现在,你想用更现代化的方法“复现”一遍,这正是从“高手”向“专家”迈进的关键一步。

这个场景(单函数内多重加密和拷贝)是绝佳的练习靶场。下面我为你设计一个详细、可操作的流程,教你如何使用现代化工具来自动化地解决你手动解决的问题。

我们将使用一个强大的、在逆向圈非常流行的Python库 **Triton**。它把污点分析和符号执行完美地结合在了一起,非常适合这个场景。

---
### 准备工作

1.  **安装Triton**:
    ```bash
    pip install triton
    ```
2.  **明确目标**:
    * 你的目标二进制文件。
    * 你要分析的那个函数的**起始地址**和**结束地址**。
    * 函数开始时,**原始明文**在哪个寄存器或内存地址。
    * 函数结束时,**最终密文**在哪个寄存器或内存地址。

---
### 第一阶段:使用“污点分析”自动过滤无用拷贝

**目标**:你手动逆向时,肯定花费了大量时间去跟踪数据在 `MOV`, `memcpy`, `PUSH`/`POP` 中是如何被搬来搬去。污点分析可以帮你**在几秒钟内**过滤掉这些“噪音”,只显示真正进行加密运算的“信号”。

#### **操作步骤:**

1.  **编写Python脚本**: 创建一个Python文件,我们将用Triton库来模拟执行这个函数。

2.  **初始化环境**:
    ```python
    from triton import *

    # --- 1. 初始化 Triton 上下文 ---
    ctx = TritonContext()
    ctx.setArchitecture(ARCH.X86_64) # 或者 ARCH.X86

    # --- 2. 加载二进制代码 ---
    # 假设你已经将函数的所有机器码dump了出来
    # 为简单起见,我们直接将代码映射到内存
    binary_code = b"\x48\x89\xce\x48\x8b\..." # 这里是你的函数机器码
    FUNC_START_ADDR = 0x401000
    FUNC_END_ADDR = 0x401234
    ctx.set_concrete_memory_area_value(FUNC_START_ADDR, binary_code)

    # --- 3. 设置初始状态 ---
    # 假设明文在 RSI 指向的内存,密钥在 RDI
    # 你需要根据你的实际情况设置寄存器和内存
    ctx.set_concrete_register_value(ctx.registers.rsp, 0x7fffffff)
    # ... 设置其他需要的寄存器 ...
    
    # 将你的明文加载到内存
    plaintext = b"THIS_IS_MY_DATA"
    PLAINTEXT_ADDR = 0x100000 
    ctx.set_concrete_memory_area_value(PLAINTEXT_ADDR, plaintext)
    ctx.set_concrete_register_value(ctx.registers.rsi, PLAINTEXT_ADDR)
    ```

3.  **标记“污染源”**: 这是污点分析的核心。告诉Triton,我们的明文是“脏”的。
    ```python
    # 将我们存放明文的内存区域标记为污点
    print(f"[*] Tainting the plaintext memory at {hex(PLAINTEXT_ADDR)}")
    ctx.taint_memory(PLAINTEXT_ADDR, len(plaintext))
    ```

4.  **模拟执行并检测“有效指令”**:
    ```python
    print("\n[*] Starting emulation and taint analysis...")
    pc = FUNC_START_ADDR
    while pc != FUNC_END_ADDR:
        # 获取当前地址的机器码
        opcode = ctx.get_concrete_memory_area_value(pc, 16)
        
        # 创建指令
        instruction = Instruction()
        instruction.setOpcode(opcode)
        instruction.setAddress(pc)
        
        # 模拟执行这条指令
        ctx.processing(instruction)

        # *** 关键:判断这条指令是否是我们关心的 ***
        # 我们只关心那些“被污染的”且“不是简单移动”的指令
        # isTainted() 检查指令的操作数是否被污染
        if instruction.isTainted() and not instruction.isControlFlow() and instruction.getType() not in [OPCODE.MOV, OPCODE.LEA, OPCODE.PUSH, OPCODE.POP]:
             print(f"---> Found interesting instruction at {hex(pc)}: {instruction.getDisassembly()}")

        # 更新PC到下一条指令
        pc = ctx.get_concrete_register_value(ctx.registers.rip)

    print("\n[*] Analysis finished.")
    ```

#### **预期结果**

运行这个脚本后,你不会看到函数内成百上千条指令的完整列表。相反,你只会得到一个非常短的列表,其中包含的都是类似 `XOR EAX, EBX`、`ADD ECX, EDX`、`ROL EAX, 2` 这样的指令。

**你已经用自动化方式,完成了手动逆向中最繁琐的一步:从大量的拷贝和地址计算中,分离出了真正的加密核心逻辑。**

---
### 第二阶段:使用“符号执行”自动理解算法

**目标**:现在我们已经知道了哪些指令是核心。接下来,我们让机器去“理解”这些指令组合起来的数学意义。

#### **操作步骤:**

我们将修改刚才的脚本,从污点分析模式切换到符号执行模式。

1.  **清理和切换**: 注释掉 `ctx.taint_memory(...)` 这行。

2.  **“符号化”输入**: 不再给具体明文,而是给一个“符号”。
    ```python
    # 以前是加载具体数据,现在是符号化这片内存
    # ctx.set_concrete_memory_area_value(PLAINTEXT_ADDR, plaintext)
    
    print(f"[*] Symbolizing the plaintext memory at {hex(PLAINTEXT_ADDR)}")
    for i in range(len(plaintext)):
        ctx.symbolize_memory(MemoryAccess(PLAINTEXT_ADDR + i, CPUSIZE.BYTE))
    ```

3.  **模拟执行**: 执行循环和之前一样,但Triton内部现在处理的不再是具体数值,而是数学表达式。

4.  **获取最终的“数学公式”**:
    ```python
    # ... 执行完上面的循环后 ...

    print("\n[*] Emulation finished. Analyzing symbolic expressions.")

    # 假设最终的密文被存放在 RAX 寄存器里
    final_expr_in_rax = ctx.get_symbolic_expression_from_id(ctx.get_symbolic_register_id(ctx.registers.rax))
    
    print("\n[+] The algorithm's formula for RAX is:")
    print(final_expr_in_rax)
    ```

#### **预期结果**

这次,脚本最后会打印出一个复杂的、像Lisp语言一样的表达式。它可能长这个样子:
```
(bvxor (_ bv213 64) 
    (bvrol 
        (bvadd 
            (bvxor (concat (_ bv0 56) (mem_100000_1_8)) (_ bv123 64)) 
            (_ bv456 64)
        ) 
        (_ bv2 64)
    )
)
```
**这串天书,就是你手动逆向出来的加密算法的数学本质!**
* `bvxor` 就是 `XOR`。
* `bvadd` 就是 `ADD`。
* `bvrol` 就是 `ROL` (循环左移)。
* `(mem_100000_1_8)` 就是我们定义的符号变量,代表明文的第一个字节。

#### **更进一步:让机器帮你解密**
你还可以用Triton的约束求解器来“逆转”这个公式。
```python
# 问一个问题:如果我想让最终RAX的值是 0xABCDEF,我的明文第一个字节应该是什么?
target_ciphertext = 0xABCDEF1234567890

# 获取明文第一个字节的符号变量
plaintext_byte_0_var = ctx.get_symbolic_variable_from_id(ctx.get_symbolic_memory_id(PLAINTEXT_ADDR))

# 添加约束
constraint = final_expr_in_rax == target_ciphertext
model = ctx.getModel(constraint)

if model:
    solution = model[plaintext_byte_0_var.getId()].getValue()
    print(f"\n[+] Solution found! To get {hex(target_ciphertext)}, plaintext byte 0 must be: {hex(solution)}")
```

### 总结

这个流程完美复现了你的手动工作,并且将其自动化:

1.  **污点分析** 帮你回答了 **“哪些代码是重要的?”**,它自动过滤了所有的内存拷贝。
2.  **符号执行** 帮你回答了 **“这些重要代码在干什么?”**,它自动推导出了算法的数学公式,甚至还能帮你求解(即解密)。

通过这个练习,你就能深刻体会到现代化工具如何将逆向工程师从繁重、重复的劳动中解放出来,让你能更专注于算法本身的设计和逻辑。
5天前
0
游客
登录 | 注册 方可回帖
返回