🚀 LLM4Decompile項目
LLM4Decompile旨在將x86彙編指令反編譯為C語言代碼。新發布的V2系列使用更大的數據集(2B標記)進行訓練,最大標記長度為4096,與之前的模型相比,性能有顯著提升(最高可達100%)。
🚀 快速開始
項目倉庫
✨ 主要特性
LLM4Decompile的主要特性在於其強大的反編譯能力,尤其是新發布的V2系列,通過使用更大的數據集和更長的最大標記長度,在將x86彙編指令反編譯為C語言代碼方面表現出色,相比之前的模型有顯著的性能提升。
📦 安裝指南
1. 安裝Ghidra
下載 Ghidra 到當前文件夾。你也可以查看 此頁面 獲取其他版本。將壓縮包解壓到當前文件夾。
在bash中,你可以使用以下命令:
cd LLM4Decompile/ghidra
wget https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_11.0.3_build/ghidra_11.0.3_PUBLIC_20240410.zip
unzip ghidra_11.0.3_PUBLIC_20240410.zip
2. 安裝Java-SDK-17
Ghidra 11依賴於Java-SDK-17,在Ubuntu上安裝SDK的簡單方法如下:
apt-get update
apt-get upgrade
apt install openjdk-17-jdk openjdk-17-jre
請查看 Ghidra安裝指南 以獲取其他平臺的安裝方法。
💻 使用示例
基礎用法
3. 使用Ghidra Headless反編譯二進制文件(demo.py)
注意:將 func0 替換為你要反編譯的函數名。
預處理:將C代碼編譯為二進制文件,並將二進制文件反彙編為彙編指令。
import os
import subprocess
from tqdm import tqdm,trange
OPT = ["O0", "O1", "O2", "O3"]
timeout_duration = 10
ghidra_path = "./ghidra_11.0.3_PUBLIC/support/analyzeHeadless"
postscript = "./decompile.py"
project_path = "."
project_name = "tmp_ghidra_proj"
func_path = "../samples/sample.c"
fileName = "sample"
with tempfile.TemporaryDirectory() as temp_dir:
pid = os.getpid()
asm_all = {}
for opt in [OPT[0]]:
executable_path = os.path.join(temp_dir, f"{pid}_{opt}.o")
cmd = f'gcc -{opt} -o {executable_path} {func_path} -lm'
subprocess.run(
cmd.split(' '),
check=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
timeout=timeout_duration,
)
output_path = os.path.join(temp_dir, f"{pid}_{opt}.c")
command = [
ghidra_path,
temp_dir,
project_name,
"-import", executable_path,
"-postScript", postscript, output_path,
"-deleteProject",
]
result = subprocess.run(command, text=True, capture_output=True, check=True)
with open(output_path,'r') as f:
c_decompile = f.read()
c_func = []
flag = 0
for line in c_decompile.split('\n'):
if "Function: func0" in line:
flag = 1
c_func.append(line)
continue
if flag:
if '// Function:' in line:
if len(c_func) > 1:
break
c_func.append(line)
if flag == 0:
raise ValueError('bad case no function found')
for idx_tmp in range(1,len(c_func)):
if 'func0' in c_func[idx_tmp]:
break
c_func = c_func[idx_tmp:]
input_asm = '\n'.join(c_func).strip()
before = f"# This is the assembly code:\n"
after = "\n# What is the source code?\n"
input_asm_prompt = before+input_asm.strip()+after
with open(fileName +'_' + opt +'.pseudo','w',encoding='utf-8') as f:
f.write(input_asm_prompt)
Ghidra偽代碼可能如下所示:
undefined4 func0(float param_1,long param_2,int param_3)
{
int local_28;
int local_24;
local_24 = 0;
do {
local_28 = local_24;
if (param_3 <= local_24) {
return 0;
}
while (local_28 = local_28 + 1, local_28 < param_3) {
if ((double)((ulong)(double)(*(float *)(param_2 + (long)local_24 * 4) -
*(float *)(param_2 + (long)local_28 * 4)) &
SUB168(_DAT_00402010,0)) < (double)param_1) {
return 1;
}
}
local_24 = local_24 + 1;
} while( true );
}
4. 使用LLM4Decompile優化偽代碼(demo.py)
反編譯:使用LLM4Decompile-Ref將Ghidra偽代碼優化為C語言代碼:
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
model_path = 'LLM4Binary/llm4decompile-6.7b-v2'
tokenizer = AutoTokenizer.from_pretrained(model_path)
model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype=torch.bfloat16).cuda()
with open(fileName +'_' + OPT[0] +'.pseudo','r') as f:
asm_func = f.read()
inputs = tokenizer(asm_func, return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model.generate(**inputs, max_new_tokens=2048)
c_func_decompile = tokenizer.decode(outputs[0][len(inputs[0]):-1])
with open(fileName +'_' + OPT[0] +'.pseudo','r') as f:
func = f.read()
print(f'pseudo function:\n{func}')
print(f'refined function:\n{c_func_decompile}')
📚 詳細文檔
評估結果
指標 |
可重新執行率 |
|
|
|
|
編輯相似度 |
|
|
|
|
優化級別 |
O0 |
O1 |
O2 |
O3 |
平均值 |
O0 |
O1 |
O2 |
O3 |
平均值 |
LLM4Decompile-End-6.7B |
0.6805 |
0.3951 |
0.3671 |
0.3720 |
0.4537 |
0.1557 |
0.1292 |
0.1293 |
0.1269 |
0.1353 |
Ghidra |
0.3476 |
0.1646 |
0.1524 |
0.1402 |
0.2012 |
0.0699 |
0.0613 |
0.0619 |
0.0547 |
0.0620 |
+GPT-4o |
0.4695 |
0.3415 |
0.2866 |
0.3110 |
0.3522 |
0.0660 |
0.0563 |
0.0567 |
0.0499 |
0.0572 |
+LLM4Decompile-Ref-1.3B |
0.6890 |
0.3720 |
0.4085 |
0.3720 |
0.4604 |
0.1517 |
0.1325 |
0.1292 |
0.1267 |
0.1350 |
+LLM4Decompile-Ref-6.7B |
0.7439 |
0.4695 |
0.4756 |
0.4207 |
0.5274 |
0.1559 |
0.1353 |
0.1342 |
0.1273 |
0.1382 |
+LLM4Decompile-Ref-33B |
0.7073 |
0.4756 |
0.4390 |
0.4146 |
0.5091 |
0.1540 |
0.1379 |
0.1363 |
0.1307 |
0.1397 |
📄 許可證
本代碼倉庫遵循MIT許可證。
📞 聯繫我們
如果您有任何問題,請提交一個issue。