3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Rustのコンパイラを改造して難読化機能を追加

Last updated at Posted at 2024-08-31

経緯

リバースエンジニアリングがむずい最強バイナリをつくりたいよね。
obfuscator-llvmが難読化手法としてあるがRustには対応していない。でもRustのコンパイルの仕組み的には途中にLLVM-IRを挟むので行けそう...?

ということでやってみた
パッチあてる作業がかなり面倒なのであてたものがこちらです。

手順

  1. LLVMにパッチをあてる
  2. config.tomlを編集しRustをソースコードからビルドする

今回こちらを参考に1.76.0のバージョンに対応させました。

リポジトリのクローン

Hikari-LLVM15にはLLVMバージョン17.0.6と18.0.8がある。記事作成時点では18.0.8を使っているRustバージョンがなかったので17.0.6を使うことに。
Rustが使用しているLLVMの情報の調べ方

$ ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc --version --verbose
rustc 1.77.0 (aedd173a2 2024-03-17)
binary: rustc
commit-hash: aedd173a2c086e558c2b66d3743b344f977621a7
commit-date: 2024-03-17
host: x86_64-unknown-linux-gnu
release: 1.77.0
LLVM version: 17.0.6

今回使用するRustのバージョンを1.76.0にした。Rustのソースコード,Rust用LLVMのソースコード,差分を取るためにHikari-LLVMをクローンする

git clone --single-branch --branch 1.76.0 --depth 1 https://github.com/rust-lang/rust rust-1.76.0
git clone --single-branch --branch rustc-1.76.0 --depth 1 https://github.com/rust-lang/llvm-project llvm-17.6
git clone --single-branch --branch llvm-17.6.0rel --recursive --depth 1 https://github.com/61bcdefg/Hikari-LLVM15 ollvm-17.6

LLVMの修正・ビルド

差分を取る

patchをあてるために差分を取る。

git diff llvm-17.6/llvm ollvm-17.6/llvm/ > llvm.patch

権限変更に関する情報が多かったので魔法の呪文を唱えて再度差分をとった。

chmod 777 *

不要そうなtestなどの変更を削除しvimで%s/llvm-17.6///gと%s/ollvm-17.6///gでパスを修正しパッチをあてられるようにする。ここら辺のどれを削除したとかあまり記憶にない(うごいたからよし!状態)なのでこちらのファイルを参照してください。

パッチをあてる

cd llvm-17.6
git apply --reject --ignore-whitespace ../llvm.patch

ビルド

clangなどを用意する。バージョンは17。他にはcmakeとninjaが必要だったけどバージョンはそんなに重要ではない。

wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 17
mkdir build && cd build
cmake -G "Ninja" ../llvm -DCMAKE_INSTALL_PREFIX="./llvm_x64" \
  -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang;lld;" -DLLVM_TARGETS_TO_BUILD="X86" \
  -DBUILD_SHARED_LIBS=ON -DLLVM_INSTALL_UTILS=ON -DLLVM_INCLUDE_TESTS=OFF -DLLVM_BUILD_TESTS=OFF \
  -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_BUILD_BENCHMARKS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF \
  -DLLVM_ENABLE_BACKTRACES=OFF -DLLVM_BUILD_DOCS=OFF  -DBUILD_SHARED_LIBS=OFF \
  -DCMAKE_CXX_COMPILER=clang++-17 -DCMAKE_C_COMPILER=clang-17

問題が起きなければ引き続き...jに続く数字はお好みで

cmake --build . -j16
cmake --install .

Rustのビルド

cd rust-1.76.0
cp config.example.toml config.toml

config.example.tomlがあるのでコピーしてconfig.tomlを作成。

  1. [rust]セクション内 debug=false
  2. [rust]セクション内 channel = "nightly"
  3. [target.x86_64-unknown-linux-gnu]セクション内 llvm-config = "/home/user/.../llvm-17.6/build/bin/llvm-config" 先ほどコンパイルした際に生成されたllvm-configのパスを指定する。

設定が終わったら

python3 ./x.py build
python3 ./x.py build --stage 2 rustc
python3 ./x.py build cargo
python3 ./x.py build --stage 2 cargo

でコンパイルされることを祈りましょう。

$ ls rust-1.76.0/build/x86_64-unknown-linux-gnu
doc/              stage0-codegen/   stage0-sysroot/   stage1/           stage1-tools/     stage2-std/
md-doc/           stage0-rustc/     stage0-tools/     stage1-rustc/     stage1-tools-bin/ stage2-tools/
stage0/           stage0-std/       stage0-tools-bin/ stage1-std/       stage2/           stage2-tools-bin

stage0→stage1→stage2の順でコンパイルされていきます。数字が大きいほうがいいと思ってくれれば大丈夫です。コンパイラのビルドプロセスを参考にしてください。

ということでstage2にはrustcがstage2-tools-binにはcargoが入っていると思います。

実験

適当なプログラムをコンパイルしてみる

fn main() {
    println!("Hello, world!");
}

-Cllvm-argsで難読化オプションを指定する。指定できるオプションはこちら

$ ./rust-1.76.0/build/x86_64-unknown-linux-gnu/stage2/bin/rustc -Cllvm-args=-enable-allobf hello.rs

解析

とりあえずstripせずに解析
スクリーンショット 2024-08-31 230425.png
main関数ですが不明なスタック変数が大量にあり更にジャンプ先がわかりません。アセンブリを見たところjmp raxとなっていました。println!におそらく使われるstd :: io :: stdio :: _printのxrefを見ましたがなにもありませんでした。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?