Skip to content
/ NotDec Public

a webassembly wasm decompiler and Static Analysis Framework based on llvm IR. (Work In Progress)

Notifications You must be signed in to change notification settings

NotDec/NotDec

Repository files navigation

NotDec: WebAssembly Decompiler and Static Analysis Framework

Website

中文

NotDec is

  1. A project that aims to demystify the internal of decompiler.
  2. A webassembly decompiler that can experiment with new decompiler techniques.
    • Variable Recovery
    • Structual Analysis

Keywords: Reverse LLVM, LLVM C Backend / llvm-cbe.

Development - Linux

Based on Ubuntu 22.04

  1. Install dependencies
    • Use apt
      sudo apt install wabt python-is-python3 clang-14 cmake zlib1g-dev g++ ninja-build
      
    • Install wasi-sdk to /opt
      wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz -P /tmp
      sudo tar xf /tmp/wasi-sdk-20.0-linux.tar.gz -C /opt
      
  2. clone this repo
  3. Install LLVM 14
    • Execute scripts/build-debug-llvm.sh to download and build LLVM. You may encounter errors about no memory during linking, just decrease the parallel number to 1.
  4. Install Souffle
  5. cmake build

中文

文档站

NotDec: 反编译器原理分析

本项目旨在:

  1. 学习现有反编译器的原理,系统地总结现有反编译器的工作,算法
  2. 选择合适的算法,尝试实现自己的反编译器

资料收集

学习阶段:

  1. LLVM IR基础:只要达到能手写LLVM IR的程度就行。即主要理解各种语言特性对应的是什么样的LLVM IR代码。同时理解带alloca的半SSA形式,即alloca里的变量是非SSA,外面的是SSA。

    • llvm-tutor
    • ollvm源码
  2. SSA与编译优化基础

    关于SSA的实验

    其他不错的资料:

  3. 反编译

资料

现有的反编译器和资料

规划:基于LLVM IR的反编译

为什么要使用LLVM IR?

  1. 之后可以直接对接SVF,得到较好的指针分析结果。

优先实现wasm的反编译。

  1. Wasm转LLVM IR
    1. WAVM是一个基于LLVM的wasm的JIT,有部分逻辑是WASM转 LLVM IR
      1. 生成的IR不够简洁,有很多为了编译到汇编的冗余的内容
  2. TODO

规划:反编译阶段

反编译的各个阶段

图片来自Static Single Assignment for Decompilation

反编译中的关键算法: Type Recovery(通过指令约束推导类型) Structual Analysis(恢复控制流)

  1. 前端:将字节码转为LLVM IR
  2. 中端:优化与分析
    1. 分析函数参数、分析callee saved register (wasm可以跳过这个阶段)
    2. SSA构建:使得前端可以有些冗余的alloca,由SSA构建来将相关alloca消除。 (编译原理相关)
    3. GVNGCM:Global Value Numbering and Global Code Motion 优化算法,有强大的优化能力,有助于反混淆等。(编译原理相关)
    4. 内存分析:将各种通过内存访问的变量显式地恢复出来。可能要用到指针分析算法,类型恢复等。关键词:Memory SSA。
  3. 后端:高层控制流恢复,将字节码转为AST,打印为高级语言的形式。

项目架构与工具

由于基于LLVM IR,因此语言采用C++。

开发环境:VSCode + CMake。将Wabt,LLVM等作为CMake的外部依赖。

开发环境搭建 - DevContainer

2023年9月7日注:由于对LLVM的调试需求越来越多,项目转为使用本地源码编译的LLVM(RelWithDebInfo或Debug build),且编译得到的二进制文件过大,因此不再推荐使用DevContainer。

VSCode DevContainer。出于性能考虑,在clone时可以直接clone到wsl的ext4文件系统里。

  1. 安装Docker Desktop on Windows: https://docs.docker.com/desktop/install/windows-install/ (无论是家庭版还是专业版均可)
    1. 其他系统直接安装docker
  2. 用vscode打开代码,安装Dev Containers插件,按Ctrl-Shift-P 然后输入查找 Remote-Containers: Rebuild and Reopen in container.
  3. 等待构建,构建完成后会直接进入开发环境中。
  4. 安装CMake相关插件,toolkit选clang。

如果出现了无法使用windows侧的ssh-agent提供的ssh key的forward功能: https://stackoverflow.com/questions/72293035/error-communication-with-agent-failed-when-ssh-auth-sock-is-set-but-ssh-agent

代码调试

直接使用自带的C/C++调试,不知道为什么会非常慢,gdb执行backtrace要卡3秒,各种step命令要卡5-6秒。因此安装使用vscode的CodeLLDB插件。

代码补全使用clangd插件。根据提示禁用Intellisense,然后根据插件提示确认下载clangd。

提交代码前

  1. 写好commit message,简要概况所有的修改。
  2. 检查添加的代码的注释和文档是否充足。

TODO

  1. 反编译器自身:能够对“内存”中的变量也构建SSA进行优化。

  2. 最终的结果能够很好地重编译。

  3. 反编译器实现过程尽量记录完善的文档,未来考虑整理扩写为系列教程。

  4. 将wasm lift到LLVM IR

    • 支持将wasm内存直接映射到某个基地址,从而直接支持运行,以及memory grow相关指令。
    • 支持DWARF调试信息,从而映射回原wat,wasm
  5. 设计一个映射,将lift之后的IR反向转回wasm

About

a webassembly wasm decompiler and Static Analysis Framework based on llvm IR. (Work In Progress)

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published