LLM4Decompile - Công nghệ decompile mã nhị phân bằng LLM
(github.com/albertan017)- LLM4Decompile là một dự án mô hình ngôn ngữ lớn mã nguồn mở nhằm khôi phục các binary Linux x86_64 thành mã nguồn C mà con người có thể đọc được, ở các mức tối ưu hóa GCC từ O0 đến O3
- Cách tiếp cận là chuyển binary thành assembly bằng Objdump, sau đó để LLM decompile thành mã C; dự án cũng cung cấp nhánh LLM4Decompile-Ref để tinh chỉnh pseudocode đầu ra của Ghidra
- Các mô hình được công bố có quy mô từ 1.3B đến 22B, và llm4decompile-9b-v2 đạt tỷ lệ tái thực thi 64,9% trên benchmark Decompile
- Chỉ số đánh giá là tỷ lệ tái thực thi, xem mã đã decompile có vượt qua các bài kiểm thử định nghĩa sẵn và chạy đúng hay không; 164 hàm C trong HumanEval-Decompile và 2.621 hàm trong ExeBench được dùng làm benchmark
- Năm 2025, dự án đã công bố decompile-bench và SK²Decompile, đồng thời đang mở rộng với mục tiêu hỗ trợ thêm nhiều kiến trúc, thiết lập và tích hợp công cụ decompile hơn
Mục tiêu và phạm vi hỗ trợ của LLM4Decompile
- LLM4Decompile là một dự án mô hình ngôn ngữ lớn mã nguồn mở chuyên biệt cho decompile
- Phiên bản hiện tại decompile binary Linux x86_64 ở các mức tối ưu hóa GCC O0~O3 thành mã nguồn C mà con người có thể đọc được
- Dự án đang được mở rộng để hỗ trợ phạm vi kiến trúc và thiết lập rộng hơn
- Có hai cách sử dụng chính
- LLM4Decompile-End: nhánh mô hình decompile trực tiếp binary
- LLM4Decompile-Ref: nhánh mô hình dùng LLM để tinh chỉnh pseudocode do Ghidra decompile
Luồng huấn luyện và đánh giá decompile
- Quá trình biên dịch bắt đầu từ mã nguồn C, trải qua tiền xử lý, biên dịch, assembly và liên kết để tạo file thực thi
- Decompile đi ngược lại quá trình này, chuyển mã nhị phân trở lại file nguồn
- Vì LLM không thể xử lý trực tiếp dữ liệu nhị phân, trước tiên binary phải được disassemble thành ngôn ngữ assembly bằng Objdump
- README giải thích rằng binary và ASM đã disassemble có thể chuyển đổi qua lại, nên được xem là tương đương
- Trong huấn luyện, hệ thống tính loss giữa mã đã decompile và mã nguồn gốc; trong đánh giá, chức năng được kiểm tra bằng việc mã có vượt qua các assertion kiểm thử hay không
Chỉ số đánh giá và benchmark
- Chỉ số cốt lõi là Re-executability
- Kiểm tra mã đã decompile có chạy đúng hay không
- Đánh giá xem mã có vượt qua tất cả test case định nghĩa sẵn hay không
- HumanEval-Decompile là tập gồm 164 hàm C chỉ phụ thuộc vào thư viện C chuẩn
- ExeBench là tập gồm 2.621 hàm lấy từ các dự án thực tế
- Bao gồm hàm do người dùng định nghĩa, struct và macro
Các mô hình công bố và hiệu năng
- LLM4Decompile bao gồm các mô hình có quy mô tham số từ 1.3B đến 33B, được công bố trên Hugging Face
- Tỷ lệ tái thực thi của các mô hình chính như sau
- llm4decompile-1.3b-v1.5: 1.3B, 27,3%
- llm4decompile-6.7b-v1.5: 6.7B, 45,4%
- llm4decompile-1.3b-v2: 1.3B, 46,0%
- llm4decompile-6.7b-v2: 6.7B, 52,7%
- llm4decompile-9b-v2: 9B, 64,9%
- llm4decompile-22b-v2: 22B, 63,6%
- Nhánh V1.5 được huấn luyện trên dataset lớn hơn gồm 15B token với độ dài token tối đa 4.096, và được cho biết là cải thiện hiệu năng hơn 100% so với mô hình trước đó
- Nhánh V2 dựa trên Ghidra, được huấn luyện với 2B token để tinh chỉnh pseudocode decompile do Ghidra tạo ra
- 22B-V2 được cho biết đạt hiệu năng cao hơn thêm 40,1% so với 6.7B-V1.5
Các hạng mục công bố gần đây
- Ngày 4/10/2025, SK²Decompile được công bố
- Giai đoạn 1 Structure Recovery, tức Skeleton, chuyển binary hoặc pseudocode thành biểu diễn trung gian đã được làm rối
- Giai đoạn 2 Identifier Naming, tức Skin, tạo mã nguồn con người có thể đọc được với các định danh có ý nghĩa
- Liên kết mô hình: sk2decompile-struct-6.7b, sk2decompile-ident-6.7
- Ngày 20/5/2025, decompile-bench được công bố
- Bao gồm 2 triệu cặp hàm binary-nguồn dùng cho huấn luyện
- Bao gồm 70.000 cặp hàm dùng cho đánh giá
- Chi tiết có trong thư mục decompile-bench
- Ngày 17/10/2024, decompile-ghidra-100k được công bố
- Bao gồm tổng cộng 100.000 mẫu huấn luyện, mỗi mức tối ưu hóa 25.000 mẫu
- Cung cấp script huấn luyện chạy trong khoảng 3,5 giờ trên một GPU A100 40G đơn
- Chi phí tái hiện nhanh tổng cộng dưới 20 USD và đạt tỷ lệ tái thực thi 0,26
- Ngày 23/9/2024, LLM4Decompile-9B-v2 được công bố
- Được fine-tune dựa trên Yi-Coder-9B
- Đạt tỷ lệ tái thực thi 0,6494 trên benchmark Decompile
Luồng sử dụng
- Bắt đầu nhanh gồm clone repository, tạo môi trường Conda và cài đặt
requirements.txt - Bước tiền xử lý biên dịch mã C thành binary bằng GCC, rồi trích xuất lệnh assembly bằng
objdump -d - Tên hàm cần được thay bằng tên hàm muốn decompile, thay cho
func0trong ví dụ - Assembly đầu vào được kỳ vọng có dạng sau
<FUNCTION_NAME>:- Nhiều dòng lệnh assembly tiếp theo
- Bước decompile tải mô hình Hugging Face bằng
AutoTokenizervàAutoModelForCausalLMcủatransformers, rồi sinh mã C từ prompt assembly - Cũng có thể dùng Docker
- Sau khi build image, chạy container với tùy chọn GPU
- Cung cấp luồng chạy
demo.pytrong thư mụcghidra
Định dạng dữ liệu HumanEval-Decompile
- Dữ liệu HumanEval-Decompile được lưu dưới dạng danh sách JSON tại
llm4decompile/decompile-eval/decompile-eval-executable-gcc-obj.json - Số mẫu là 164*4, tức 164 hàm nhân với các mức tối ưu hóa O0, O1, O2, O3
- Mỗi mẫu có 5 khóa
task_id: ID bài toántype: mức tối ưu hóa, một trong O0, O1, O2, O3c_func: lời giải C của bài HumanEvalc_test: assertion kiểm thử Cinput_asm_prompt: lệnh assembly và prompt
- Script đánh giá nằm trong thư mục evaluation
Các hạng mục đang triển khai và giấy phép
- Các hạng mục đang triển khai bao gồm dataset huấn luyện lớn hơn và quy trình dọn dẹp, hỗ trợ các ngôn ngữ, nền tảng và thiết lập phổ biến, hỗ trợ file thực thi, tích hợp công cụ decompile như Ghidra và Rizin
- Dataset huấn luyện lớn hơn và hỗ trợ file thực thi được đánh dấu là các hạng mục đã hoàn tất vào ngày 13/5/2024
- Kho mã được cấp phép theo MIT License và DeepSeek License
- Bài báo nằm tại arXiv:2403.05286, và dự án cũng cung cấp tài liệu Colab cùng YouTube
1 bình luận
Các ý kiến trên Hacker News
Ý tưởng thú vị, nhưng tôi thắc mắc liệu kết quả có đáng tin cậy hay không
Khi biên dịch lại có thể tạo ra mã máy khác, nên khó nhận diện hiện tượng ảo giác, và tôi lo rằng nó sẽ âm thầm thất bại, nhất là ở những cấu trúc mới có thể là phần cốt lõi của mã
Tôi cũng muốn biết liệu khi chạy theo cách sinh mã, LLM có cách nào báo kèm mức độ chắc chắn của từng đoạn hay không; rốt cuộc có lẽ vẫn cần con người kiểm tra
Sau khi dịch ngược nhị phân thành mã nguồn rồi biên dịch lại thành nhị phân, kết quả phải khớp với nhị phân ban đầu; chỉ cần lặp lại cho đến khi mức mất mát giảm xuống ngưỡng chấp nhận được
Học tăng cường rất phù hợp với những bài toán như thế này, và trên thực tế được biết là hiệu quả bất thường trong kiểu bài toán này
Đây có thể là một thử nghiệm để khám phá meme phổ biến hiện nay kiểu “cứ dùng LLM đi”, nhưng phản biện lớn hơn là các decompiler hiện có đã làm tốt hơn với lượng tính toán ít hơn rất nhiều
Sau đó có thể dùng công cụ kiểm chứng để xác nhận kết quả có đúng theo chứng minh mà LLM cung cấp hay không
Dĩ nhiên, xây dựng và huấn luyện một LLM có thể tạo được những chứng minh như vậy là bài toán còn khó hơn, nhưng đó có thể là cách bắt ảo giác một cách an toàn
Vì vậy chỉ cần biên dịch lại vài hàm đó
Nếu biết nhà phát triển đã tạo ứng dụng, sẽ rất thú vị nếu có thể dùng mã trước đây của họ làm dữ liệu huấn luyện để huấn luyện một mô-đun dịch ngược
Ví dụ Super Mario 64 và Zelda 64 đã được dịch ngược hoàn toàn, các game N64 khác cũng đang được thực hiện, nên tôi tò mò liệu có thể lập bản đồ các nhà phát triển tham gia hai game đó, thậm chí suy đoán ai đã làm mô-đun nào, rồi tận dụng để dịch ngược các game khác hay không
Nếu việc này thật sự trở nên rất tốt, ta còn có thể mơ đến cuộc sống giải mã mọi blob nhị phân trong PC, mở driver ra công khai và mở toang cả hệ điều hành
Cũng có thể tưởng tượng việc không hài lòng với Linux mà hồi sinh Windows XP, backport bảo mật hiện đại và khả năng tương thích ứng dụng, rồi cứ để Windows 11 của Microsoft nguyên như vậy
Nếu LLM có thể làm cùng việc như decompiler hiện có, luật sư nhiều khả năng sẽ xem đó là quy trình tương đương
Vấn đề cốt lõi không phải kỹ thuật mà là pháp lý và chính trị
Tôi không rõ có trường hợp nào được dùng hữu ích trong thực tế hay chưa, nhưng thật thú vị khi phong cách lập trình cá nhân vẫn còn sót lại sau quá trình biên dịch, đủ để phân biệt các chương trình đã biên dịch của nhau
Kết quả sẽ rất giống bản gốc, nhưng nhiều yếu tố phong cách mã sẽ biến mất, và cả những phong cách có vẻ còn sót lại cũng phần lớn sẽ gần với ảo giác
Vì dễ tạo một tập dữ liệu lớn gồm các cặp đầu vào/đầu ra từ mã C công khai, đây là một trường hợp sử dụng rất tốt cho tinh chỉnh LLM
Thông thường chất lượng dữ liệu huấn luyện tổng hợp là mối lo lớn, nhưng ở đây điểm then chốt là mã có biên dịch được hay không
Nếu tôi đọc đúng con số về khả năng chạy lại trong hình kết quả, ý tưởng thì tuyệt vời nhưng trên thực tế có vẻ không hoạt động tốt
https://raw.githubusercontent.com/albertan017/LLM4Decompile/...
Bổ sung thêm, khả năng chạy lại là thước đo cốt lõi để đo độ chính xác ngữ nghĩa
Kết quả dịch ngược được biên dịch lại và chạy các ca kiểm thử để đánh giá xem logic và hành vi của chương trình có được bảo toàn hay không; khả năng biên dịch lại và khả năng chạy lại lần lượt thể hiện việc khôi phục cú pháp và bảo toàn ngữ nghĩa
Bài toán này thú vị ở ít nhất hai khía cạnh
Thứ nhất, một decompiler lý tưởng có thể làm suy yếu ý nghĩa của mã nguồn độc quyền
Thứ hai, mã C công khai rất phong phú nên có thể dễ dàng tạo tập dữ liệu cặp assembly và mã nguồn, với nhiều mức tối ưu hóa, trình biên dịch và nền tảng khác nhau
Tuy nhiên tôi thắc mắc vì sao các tác giả lại tinh chỉnh DeepSeek-Coder
Tôi cũng muốn biết liệu có thể huấn luyện LLM từ đầu bằng tập dữ liệu tương tự hay không, cần quy mô cỡ nào, và có thể chạy cục bộ hay không
Dù tác vụ mong muốn không thật gần với mô hình ban đầu, gần như luôn tốt hơn khi bắt đầu từ mô hình đã tiền huấn luyện thay vì khởi tạo ngẫu nhiên
Vì trình biên dịch làm mất thông tin, theo một nghĩa nào đó nó không bao giờ có thể tồn tại; ngay cả nếu nhìn theo góc độ rộng rãi là “hiểu mã kết quả ở mức cao”, đây vẫn là bài toán tầm AGI trong lĩnh vực an ninh máy tính
Chưa ai tiến gần đến mức đó
Llama2 được phát triển với 2 nghìn tỷ token, trong khi tập dữ liệu này chỉ ở mức khoảng 4 tỷ token
Kích thước mô hình phù hợp cũng không dễ xác định đơn giản; trong thí nghiệm, mô hình 7 tỷ tham số đạt 21% khả năng thực thi, còn mô hình 1 tỷ tham số chỉ đạt 10%
Tuy vậy khả năng biên dịch lại của hai mô hình khá tương đồng
Mô hình 1 tỷ tham số cần tối thiểu 2GB bộ nhớ GPU nên chạy được trên đa số GPU, còn mô hình 7 tỷ cần 14GB nên phù hợp với dòng 3090/4090
Với mô hình 33 tỷ, lựa chọn cho một card đơn là A100 80GB; về mặt kỹ thuật có thể chạy trên MacBook, nhưng có lẽ bạn sẽ không thật sự muốn dùng như vậy
Cũng có thể đó là điểm xuất phát để kiểm chứng ý tưởng
Đang xây dựng một trình dịch ngược dựa trên LLM cho bytecode Python https://github.com/kukas/deepcompyle
Có vẻ không nhiều người làm theo hướng nghiên cứu này, nhưng tôi nghĩ nó có thể khá thú vị, nhất là lúc này khi ngữ cảnh chú ý dài đang trở nên khả thi
Nếu ai biết nhóm nào đang làm lĩnh vực này thì tôi muốn hợp tác
Theo kinh nghiệm, bytecode Python đủ mức cao để có thể chuyển trực tiếp thành mã nguồn
Python có hệ sinh thái thư viện mã nguồn mở quy mô lớn, nhưng tôi không cho rằng nó được dùng nhiều trong phần mềm phân phối dưới dạng nhị phân
Cũng không chắc liệu nó có dựa trên LLM hay không
Dường như không có nhiều dự án Python được biên dịch thành nhị phân
Tôi từng lên kế hoạch thử làm thứ như thế này
Một ngày nào đó sẽ có ai đó thông được pipeline đầu vào nhị phân → đầu ra mã nguồn tốt, nhưng có lẽ vẫn còn mất vài năm nữa
Tôi nghĩ vậy vì có vẻ không có một núi tiền lớn nằm ở cuối bài toán này, nhưng tôi cũng có thể sai
Một cách tiếp cận tạm thời tốt là tạo pipeline dịch ngược chạy Ghidra ở chế độ headless, kết hợp độ chính xác cú pháp nghiêm ngặt của trình dịch ngược với năng lực trực giác của LLM
Giống AlphaGeometry, trình dịch ngược và LLM cần bù trừ điểm yếu cho nhau: https://deepmind.google/discover/blog/alphageometry-an-olymp...
Ngoài ra cần một cách dùng thứ như AICI làm keo kết dính để điều phối việc sinh mã nguồn C: https://github.com/microsoft/aici
Thay vì dùng trọng số của LLM để sinh mã nguồn C đúng ngữ pháp, tốt hơn là để nó suy nghĩ về tên biến, mẫu snippet và lựa chọn kiến trúc, còn các công cụ như Ghidra hay LLVM xử lý phần còn lại
Đây hơi giống một bình luận “vung tay” từ ghế bành của một cựu nghiên cứu sinh, nhưng việc các nhà nghiên cứu này lao vào là rất đáng nể, và việc các tác giả nhắc đến tích hợp Ghidra trong công việc tương lai cho thấy hướng đi có vẻ đúng
Điểm thú vị là mô hình 6 tỷ lại làm tốt hơn mô hình 33 tỷ
Tôi tò mò liệu điều đó có nghĩa là mô hình 33 tỷ cần nhiều dữ liệu huấn luyện hơn không
Nếu so sánh việc được tiền huấn luyện trên khoảng 1 triệu chương trình C với DeepSeek-Coder được huấn luyện ở quy mô hàng nghìn tỷ token, thì lượng dữ liệu chênh nhau vài bậc độ lớn
Tôi cũng tò mò kết quả sẽ thế nào nếu so với các giải pháp không phải LLM
Phần lớn LLM bị huấn luyện thiếu khá nhiều, còn mô hình 7 tỷ là một trong những mô hình phổ biến ít bị huấn luyện thiếu hơn, nên đã lan truyền rộng trong cộng đồng tinh chỉnh LLM
Trong kiểu tinh chỉnh ngây thơ chỉ đơn giản tinh chỉnh theo đúng phương pháp tiêu chuẩn, việc huấn luyện mô hình lớn khá khó; không chỉ lượng dữ liệu mà mọi yếu tố như làm sạch dữ liệu, learning rate, decay đều ảnh hưởng đến hiệu năng cuối cùng
Muốn thế phải giả định kích thước trung bình của các chương trình C đó nhỏ hơn 2 triệu token vài bậc độ lớn; thực tế có thể như vậy, nhưng nghe như một giả định khá lạc quan
Tôi tò mò nếu thành công thì liệu có phải là sao chép 1:1 mã máy của trình biên dịch không
Nếu vậy, điều đó có nghĩa là mã hoàn chỉnh có thể tồn tại như một phân phối xác suất trong không gian tiềm ẩn
Hoặc, có khả năng cao hơn, đó có thể là dạng chỉ sao chép logic rồi dịch sang ngôn ngữ đích
Những binary cần đầu vào bất định khi biên dịch, chẳng hạn khóa hay hash, có lẽ sẽ bị phá vỡ
Thật sự thú vị
Thật ngạc nhiên là GPT-4 vẫn làm khá tốt trong phần so sánh
Nó tạo mã có thể biên dịch tốt hơn nhiều so với mô hình này, nhưng độ chính xác khi tái tạo mã có hành vi đúng thì thấp hơn
Dù vậy vẫn khá ấn tượng
Chúng tôi đang cải thiện mô hình, nên hãy tiếp tục theo dõi các bản cập nhật