### Clone Repository and Install Dependencies Source: https://github.com/albertan017/llm4decompile/blob/main/train/llama_factory_llm4decompile/README.md Clone the example repository and LLaMA-Factory, then install necessary packages. Ensure LLaMA-Factory is cloned into the parent directory for a clean project structure. ```bash # Clone the example repository git clone http://github.com/7Sageer/llama-factory-example cd llama-factory-example # Clone LLaMA-Factory as a dependency # We place it in the parent directory to keep the project structure clean git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git ../LLaMA-Factory # Install the required packages pip install -r requirements.txt ``` -------------------------------- ### Setup VERL for RL Training Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/README.md Clone the VERL repository, checkout the specified version, and install it as an editable package. Additional Python packages are also installed. ```bash git clone https://github.com/volcengine/verl.git cd verl && git checkout v0.4.1 && pip install -e . pip install tree-sitter==0.24.0 tree-sitter-c==0.23.4 openai ``` -------------------------------- ### Install FlashAttention for Accelerated Training Source: https://github.com/albertan017/llm4decompile/blob/main/train/README.md Installs the FlashAttention library to speed up the training process. This is an optional step. ```bash pip install flash-attn ``` -------------------------------- ### Install Dependencies and Activate Environment Source: https://context7.com/albertan017/llm4decompile/llms.txt Installs project dependencies, including optional Flash-Attention for faster inference and required system libraries for evaluation. ```bash git clone https://github.com/albertan017/LLM4Decompile.git cd LLM4Decompile conda create -n llm4decompile python=3.9 -y conda activate llm4decompile pip install -r requirements.txt # Optional: Flash-Attention backend for faster inference pip install flash-attn # Required system libs for compilation-based evaluation apt-get install -y libboost-dev libssl-dev pip install editdistance ``` -------------------------------- ### Install Ghidra and Dependencies Source: https://github.com/albertan017/llm4decompile/blob/main/ghidra/README.md Commands to download and install Ghidra and Java SDK 17 on Ubuntu. ```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 ``` ```bash apt-get update apt-get upgrade apt install openjdk-17-jdk openjdk-17-jre ``` -------------------------------- ### Install VERL Framework Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/verl/SK2DECOMPILE/README.md Clone the VERL repository and checkout the recommended version v0.4.1 for reproducibility. Install it as an editable package. ```bash git clone https://github.com/volcengine/verl.git cd verl git checkout v0.4.1 # or the commit closest to v0.4.1 pip install -e . ``` -------------------------------- ### Install vllm and clang-format Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/README.md Install necessary dependencies for inference: vllm for LLM serving and clang-format for code formatting. ```bash pip install vllm apt install clang-format ``` -------------------------------- ### Quick Start: Reproduce Evaluation Step 5 Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/evaluation/bringupbench/README.md Instructions for reproducing only the evaluation step (Step 5) using pre-built data. Requires the Bringup-Bench source repository. ```bash # 1. Clone Bringup-Bench git clone https://github.com/toddmaustin/bringup-bench.git # 2. Configure paths cd bringupbench vim config.env # Set BENCH_REPO_ROOT to your bringup-bench path ``` -------------------------------- ### Install Required Libraries Source: https://github.com/albertan017/llm4decompile/blob/main/decompile-bench/readme.md Installs necessary libraries for compilation and edit distance calculation. Ensure these are installed before proceeding with compilation. ```bash apt-get update apt-get install -y libboost-dev libssl-dev pip install editdistance ``` -------------------------------- ### LLM4Decompile Training Command Example Source: https://github.com/albertan017/llm4decompile/blob/main/train/llama_factory_llm4decompile/README.md An example of a complete training command with modified parameters for batch size, epochs, output directory, and run name. Log paths are also adjusted. ```bash torchrun --nproc_per_node=8 --master_port=20001 /path/to/train.py \ --model_name_or_path "/path/to/your/model" \ --dataset "llm4binary_v1" \ --dataset_dir "data" \ --output_dir "output_models/deepseek-3-epochs" \ --run_name "deepseek-3-epochs" \ --per_device_train_batch_size 8 \ --gradient_accumulation_steps 16 \ --learning_rate "5e-6" \ --num_train_epochs 3.0 \ --cutoff_len 4096 \ --logging_steps 10 \ --save_steps 100 \ --save_total_limit 10 \ --flash_attn "fa2" \ --bf16 \ --hostfile "/path/to/hostfile" \ 2>&1 | tee "output_models/deepseek-3-epochs/train.log" ``` -------------------------------- ### BringUp-Bench Evaluation Prerequisites Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/evaluation/bringupbench/README.md List of dependencies required to reproduce the BringUp-Bench evaluation, including installation commands. ```markdown | Dependency | Purpose | Installation | |------------|---------|-------------| | [Bringup-Bench](https://github.com/toddmaustin/bringup-bench) | Upstream benchmark suite (90 C programs) | `git clone https://github.com/toddmaustin/bringup-bench.git` | | GCC | Compile benchmarks | `apt install gcc` | | IDA Pro + Hex-Rays | Decompile binaries to pseudocode | Commercial software | | objdump (binutils) | Disassemble binaries | `apt install binutils` | | clang-format | Pseudocode normalization | `apt install clang-format` | | Python >= 3.10 | Run evaluation scripts | `apt install python3` | ``` -------------------------------- ### Install Dependencies Source: https://github.com/albertan017/llm4decompile/blob/main/evaluation/README.md Install necessary Python packages for running the evaluation scripts. This is a prerequisite for all evaluation methods. ```bash pip install -r requirements.txt ``` -------------------------------- ### Docker Quickstart for LLM4Decompile Source: https://context7.com/albertan017/llm4decompile/llms.txt Builds and runs the full LLM4Decompile environment in Docker with GPU support. After running the container, navigate to the ghidra directory and execute the demo script. ```bash # Build image docker build -t llm4decompile . # Run container with all GPUs docker run --gpus all -it --name llm4decompile llm4decompile /bin/bash # Inside container: run the Ghidra + LLM4Decompile-Ref demo cd ghidra python demo.py ``` -------------------------------- ### Install LLM4Decompile Environment Source: https://github.com/albertan017/llm4decompile/blob/main/README.md Use this script to clone the repository, create and activate a conda environment, and install project dependencies. ```bash git clone https://github.com/albertan017/LLM4Decompile.git cd LLM4Decompile conda create -n 'llm4decompile' python=3.9 -y conda activate llm4decompile pip install -r requirements.txt ``` -------------------------------- ### Install SK2Decompile Repository Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/README.md Clone the SK2Decompile repository and navigate into the project directory. ```bash git clone https://github.com/yourusername/SK2Decompile.git cd SK2Decompile ``` -------------------------------- ### Run Evaluation with TGI Source: https://github.com/albertan017/llm4decompile/blob/main/evaluation/README.md Execute the evaluation script using the Text Generation Inference (TGI) backend. This method is known to be faster and supports multi-GPU/multi-process setups. Follow the TGI installation guide before running. ```bash git clone https://github.com/albertan017/LLM4Decompile.git cd LLM4Decompile pip install -r requirements.txt # Before running the evaluation script, please update the model_path to your local model path. bash ./scripts/run_evaluation_llm4decompile.sh ``` -------------------------------- ### Run LLaMA-Factory Training with DeepSpeed Source: https://github.com/albertan017/llm4decompile/blob/main/train/llama_factory_llm4decompile/README.md Execute the training script using DeepSpeed. Modify parameters like model paths, dataset names, and output directories to match your setup. Uncomment BF16 or hostfile options if needed. ```bash # Before executing, first create the model output directory manually # For example: mkdir -p output_models/my-first-experiment deepspeed --master_port=11000 \ ../LLaMA-Factory/src/train.py \ --deepspeed ../LLaMA-Factory/examples/deepspeed/ds_z3_config.json \ --stage sft \ --do_train \ --model_name_or_path models/llm4decompile-1.3b-v1.5 \ --dataset llm4binary_v1 \ --dataset_dir data \ --template empty \ --finetuning_type full \ --output_dir output_models/my-first-experiment \ --overwrite_cache \ --overwrite_output_dir \ --cutoff_len 4096 \ --preprocessing_num_workers 256 \ --per_device_train_batch_size 16 \ --gradient_accumulation_steps 16 \ --learning_rate 5e-6 \ --lr_scheduler_type "cosine" \ --max_grad_norm 1.0 \ --logging_steps 10 \ --save_steps 100 \ --warmup_ratio 0.025 \ --run_name "my-first-experiment" \ --save_total_limit 10 \ --gradient_checkpointing \ --flash_attn "fa2" \ --num_train_epochs 1.0 \ --plot_loss \ # --bf16 \ # If your hardware supports BF16 and you wish to enable it, uncomment this line # --hostfile /path/to/your/hostfile \ # For multi-node training, uncomment this line and provide the correct hostfile path | tee output_models/my-first-experiment/train.log 2>output_models/my-first-experiment/train.err ``` -------------------------------- ### Install Dependencies for Embedding-Based Rewards Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/verl/SK2DECOMPILE/README.md Install tree-sitter, tree-sitter-c, and openai for embedding-based rewards, typically used in Identifier Naming tasks. ```bash # For embedding-based rewards (Identifier Naming) pip install tree-sitter==0.24.0 tree-sitter-c==0.23.4 openai ``` -------------------------------- ### Start Embedding Server for Identifier Naming RL Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/verl/SK2DECOMPILE/README.md Before launching the Identifier Naming RL training, start the vLLM embedding server. Ensure it's running on the specified port and model. ```bash python -m vllm.entrypoints.openai.api_server \ --model Qwen3-Embedding-0.6B --port 8000 --dtype float16 ``` -------------------------------- ### Ghidra Pseudo-code Example Source: https://github.com/albertan017/llm4decompile/blob/main/ghidra/README.md An example of pseudo-code generated by Ghidra for a function. ```c 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 ); } ``` -------------------------------- ### Example Assembly Instruction Format Source: https://github.com/albertan017/llm4decompile/blob/main/README.md This shows the expected format for assembly instructions when providing input to the decompiler. It includes the function name followed by its operations. ```assembly : endbr64 lea (%rdi,%rsi,1),%eax retq ``` -------------------------------- ### Install Dependencies for Compiler-Based Rewards Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/verl/SK2DECOMPILE/README.md Install GCC and the psychec library for compiler-based rewards, primarily used in Structure Recovery tasks. You can also build psychec from its GitHub repository. ```bash # For compiler-based rewards (Structure Recovery) apt install gcc pip install psychec # or build from https://github.com/ltcmelo/psychec.git ``` -------------------------------- ### Decompile Binary to Pseudo-code with Ghidra and Refine with LLM4Decompile-Ref Source: https://context7.com/albertan017/llm4decompile/llms.txt This script first uses Ghidra's headless analyzer to decompile a binary to pseudo-code. It then refines this output using the LLM4Decompile-Ref (v2) model. Ensure Ghidra is installed and accessible. ```python # Step 1: Run Ghidra headless decompilation (requires ghidra_11.0.3_PUBLIC installed) import subprocess, tempfile, os ghidra_path = "./ghidra_11.0.3_PUBLIC/support/analyzeHeadless" postscript = "./ghidra/decompile.py" func_path = "samples/sample.c" project_name = "tmp_ghidra_proj" with tempfile.TemporaryDirectory() as temp_dir: pid = os.getpid() executable_path = os.path.join(temp_dir, f"{pid}_O0.o") output_path = os.path.join(temp_dir, f"{pid}_O0.c") subprocess.run( f'gcc -O0 -o {executable_path} {func_path} -lm'.split(), check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL ) subprocess.run([ ghidra_path, temp_dir, project_name, "-import", executable_path, "-postScript", postscript, output_path, "-deleteProject", ], check=True, capture_output=True, text=True) with open(output_path) as f: ghidra_output = f.read() # Extract function block for 'func0' c_func, flag = [], 0 for line in ghidra_output.split('\n'): if "Function: func0" in line: flag = 1 if flag: if '// Function:' in line and len(c_func) > 1: break c_func.append(line) pseudo_prompt = "# This is the assembly code:\n" + "\n".join(c_func).strip() + "\n# What is the source code?\n" # Step 2: Refine pseudo-code with LLM4Decompile-Ref 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() inputs = tokenizer(pseudo_prompt, return_tensors="pt").to(model.device) with torch.no_grad(): outputs = model.generate(**inputs, max_new_tokens=2048) refined_c = tokenizer.decode(outputs[0][len(inputs[0]):-1]) print(f"Refined C code:\n{refined_c}") ``` -------------------------------- ### SK²Decompile Reinforcement Learning Training Source: https://context7.com/albertan017/llm4decompile/llms.txt Applies GRPO reinforcement learning on top of SFT-initialized models using VERL. This involves installing VERL, training SFT models with LLaMA-Factory, and then running RL training scripts for structure recovery and identifier naming. ```bash # Install VERL git clone https://github.com/volcengine/verl.git cd verl && git checkout v0.4.1 && pip install -e . pip install tree-sitter==0.24.0 tree-sitter-c==0.23.4 openai # First train SFT models with LLaMA-Factory llamafactory-cli train sk2decompile/LLaMA-Factory/SK2DECOMPILE/train/pseudo2norm-example.yaml llamafactory-cli train sk2decompile/LLaMA-Factory/SK2DECOMPILE/train/norm2code-example.yaml # RL training for Structure Recovery phase bash sk2decompile/verl/SK2DECOMPILE/scripts/run_struct_rl.sh # RL training for Identifier Naming phase (needs embedding server) bash sk2decompile/verl/SK2DECOMPILE/scripts/run_ident_rl.sh ``` -------------------------------- ### Compile Benchmarks at O0-O3 Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/evaluation/bringupbench/README.md Build all Bringup-Bench programs at four optimization levels to produce binaries. ```bash scripts/build-host-opt-levels.sh ``` -------------------------------- ### Navigate to BringupBench Directory Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/evaluation/bringupbench/README.md Change the current directory to the bringupbench directory. Ensure BENCH_REPO_ROOT and IDA_BIN are set in config.env. ```bash cd bringupbench vim config.env # Set BENCH_REPO_ROOT and IDA_BIN ``` -------------------------------- ### Create Output Directory Source: https://github.com/albertan017/llm4decompile/blob/main/train/llama_factory_llm4decompile/README.md Before running the training command, ensure the specified output directory exists. This command creates the directory if it doesn't already exist. ```bash mkdir -p output_models/deepseek-3-epochs ``` -------------------------------- ### Train Skeleton Model with LLaMA-Factory Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/README.md Initiate the supervised fine-tuning (SFT) for the skeleton model (pseudo2norm) using a LLaMA-Factory configuration file. ```bash cd ../LLaMA-Factory # Follow installation instructions in LLaMA-Factory/README.md # Train Skeleton Model (pseudo2norm) llamafactory-cli train LLaMA-Factory/SK2DECOMPILE/train/pseudo2norm-example.yaml ``` -------------------------------- ### Decompile Assembly to Pseudo-C Source: https://github.com/albertan017/llm4decompile/blob/main/ghidra/README.md Reads an assembly file, tokenizes it, and uses a pre-trained model to generate decompiled pseudo-C code. Ensure the model and tokenizer are properly initialized and the device is set. ```python with open(fileName +'_' + OPT[0] +'.pseudo','r') as f:#optimization level O0 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)### max length to 4096, max new tokens should be below the range c_func_decompile = tokenizer.decode(outputs[0][len(inputs[0]):-1]) with open(fileName +'_' + OPT[0] +'.pseudo','r') as f:#original file func = f.read() print(f'pseudo function:\n{func}')# Note we only decompile one function, where the original file may contain multiple functions print(f'refined function:\n{c_func_decompile}') ``` -------------------------------- ### BringUpBench Directory Structure Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/evaluation/bringupbench/README.md Overview of the directory structure for the BringUpBench evaluation pipeline, including configuration, scripts, data, and reports. ```tree bringupbench/ ├── README.md # This file ├── config.env # Environment configuration (paths) ├── scripts/ │ ├── build-host-opt-levels.sh # Step 1: Compile benchmarks at O0-O3 │ ├── decompile-all-pseudo.sh # Step 2: IDA Pro batch decompilation │ ├── dump_pseudo.py # IDA headless decompilation helper │ ├── disasm-all-objdump.sh # Step 3: objdump batch disassembly │ ├── build-func-maps.py # Step 4: Build function-level mappings │ ├── clean-all-benchmarks.sh # Utility: clean all build artifacts │ └── eval_infer_out.py # Step 5: Automated evaluation ├── data/ │ ├── func_maps/ # Pre-built function mappings (JSONL) │ │ ├── merged.O0.func_map.jsonl # O0: 493 functions │ │ ├── merged.O1.func_map.jsonl # O1: 449 functions │ │ ├── merged.O2.func_map.jsonl # O2: 441 functions │ │ └── merged.O3.func_map.jsonl # O3: 439 functions │ └── infer_results/ # SK²Decompile inference results │ ├── merged.O0.func_map.infer.jsonl # O0: 382 evaluated functions │ ├── merged.O1.func_map.infer.jsonl # O1: 379 evaluated functions │ ├── merged.O2.func_map.infer.jsonl # O2: 368 evaluated functions │ └── merged.O3.func_map.infer.jsonl # O3: 359 evaluated functions └── reports/ # Evaluation result summaries ├── O0_results.md ├── O1_results.md ├── O2_results.md └── O3_results.md ``` -------------------------------- ### Prepare Pretrain Dataset Script Source: https://github.com/albertan017/llm4decompile/blob/main/train/colossalai_llm4decompile/README.md Command to transform raw data into the Colossal AI training format. Specify input directories, tokenizer, output directories, and dataset bin count. ```bash python prepare_pretrain_dataset.py \ --data_input_dirs "raw_data_dir" \ --tokenizer_dir "path/deepseek-coder-6.7b-base" \ --data_output_dirs "path_to_llm4decompile_data" \ --max_length 4096 \ --num_spliced_dataset_bins 1 ``` -------------------------------- ### Train Skin Model with LLaMA-Factory Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/README.md Initiate the supervised fine-tuning (SFT) for the skin model (norm2code) using a LLaMA-Factory configuration file. ```bash # Train Skin Model (norm2code) llamafactory-cli train LLaMA-Factory/SK2DECOMPILE/train/norm2code-example.yaml ``` -------------------------------- ### Launch Structure Recovery RL Training Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/verl/SK2DECOMPILE/README.md Execute the Structure Recovery Reinforcement Learning training script. Remember to edit the configuration variables in `scripts/run_struct_rl.sh` before launching. ```bash # Edit scripts/run_struct_rl.sh to set: # VERL_DIR, VENV_PATH, MODEL_PATH, TRAIN_DATA, VAL_DATA, WANDB_* bash scripts/run_struct_rl.sh ``` -------------------------------- ### Build Function Mappings Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/evaluation/bringupbench/README.md Generate function-level mappings by parsing source code, pseudocode, and assembly. ```bash # Build function-level mappings python3 scripts/build-func-maps.py ``` -------------------------------- ### Navigate to Evaluation Directory Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/README.md Change the current directory to the evaluation scripts. ```bash cd ../evaluation ``` -------------------------------- ### Run Structure Recovery RL Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/README.md Execute the script for structure recovery reinforcement learning. ```bash bash verl/SK2DECOMPILE/scripts/run_struct_rl.sh ``` -------------------------------- ### Baseline Extraction with IDA Pro Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/evaluation/bringupbench/README.md Use IDA Pro in headless mode to decompile binaries and generate pseudocode files. ```bash scripts/decompile-all-pseudo.sh ``` -------------------------------- ### Run Evaluation with vLLM Source: https://github.com/albertan017/llm4decompile/blob/main/evaluation/README.md Execute the evaluation script using the vLLM backend. Ensure the model_path and testset_path are updated to your local directories. This method is recommended for optimal performance. ```bash cd evaluation python run_evaluation_llm4decompile_vllm.py \ --model_path LLM4Binary/llm4decompile-6.7b-v1.5 \ --testset_path ../decompile-eval/decompile-eval-executable-gcc-obj.json \ --gpus 8 \ --max_total_tokens 8192 \ --max_new_tokens 512 \ --repeat 1 \ --num_workers 16 \ --gpu_memory_utilization 0.82 \ --temperature 0 ``` -------------------------------- ### Build and Run LLM4Decompile Docker Image Source: https://github.com/albertan017/llm4decompile/blob/main/README.md Commands to build the Docker image for LLM4Decompile and run it with GPU support. After running, you can execute demo.py within the container. ```bash # build docker docker build -t llm4decompile . # run docker with GPU docker run --gpus all -it --name llm4decompile llm4decompile /bin/bash # run demo.py (choose a model suitable for your resources before running) cd ghidra python demo.py ``` -------------------------------- ### Decompile Assembly to C using LLM4Decompile Source: https://github.com/albertan017/llm4decompile/blob/main/README.md This script loads the preprocessed assembly prompt and uses the LLM4Decompile model to generate C code. It then prints the original C function and the decompiled C function for comparison. Ensure the model path is correct for your chosen model version. ```python from transformers import AutoTokenizer, AutoModelForCausalLM import torch model_path = 'LLM4Binary/llm4decompile-6.7b-v1.5' # V1.5 Model tokenizer = AutoTokenizer.from_pretrained(model_path) model = AutoModelForCausalLM.from_pretrained(model_path,torch_dtype=torch.bfloat16).cuda() with open(fileName +'_' + OPT[0] +'.asm','r') as f:#optimization level O0 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)### max length to 4096, max new tokens should be below the range c_func_decompile = tokenizer.decode(outputs[0][len(inputs[0]):-1]) with open(fileName +'.c','r') as f:#original file func = f.read() print(f'original function:\n{func}')# Note we only decompile one function, where the original file may contain multiple functions print(f'decompiled function:\n{c_func_decompile}') ``` -------------------------------- ### Execute LLM4Decompile Training Source: https://github.com/albertan017/llm4decompile/blob/main/train/colossalai_llm4decompile/README.md Bash command to initiate the LLM4Decompile model training process after the environment is configured and data is prepared. ```bash bash run_llm4decompile_train.sh ``` -------------------------------- ### Format Source Code with clang-format Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/README.md Format the obfuscated IR using `clang-format` to ensure consistent code style. This is done via the `format.py` script. ```bash # Step 3: Format codes with clang-format python3 format.py --input exebench_norm_top0.json --output exebench_format_top0.json ``` -------------------------------- ### Run SK2Decompile Inference (Detailed) Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/README.md Detailed command for running SK2Decompile inference, specifying dataset and model paths. Uses bash for multi-line command execution. ```bash python normalize_pseudo.py --input_json reverse_sample.json --output_json reverse_sample.json python sk2decompile.py --dataset_path reverse_sample.json \ --model_path LLM4Binary/sk2decompile-struct-6.7b \ --recover_model_path LLM4Binary/sk2decompile-ident-6.7b ``` -------------------------------- ### Disassemble Binaries (Optional) Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/evaluation/bringupbench/README.md Disassemble binaries using objdump, which is optional but useful for assembly mapping. ```bash # Disassemble (optional, for assembly mapping) scripts/disasm-all-objdump.sh ``` -------------------------------- ### Run Evaluation on Single GPU (Legacy) Source: https://github.com/albertan017/llm4decompile/blob/main/evaluation/README.md This is a legacy script for running evaluation on a single GPU and single process. It is not actively updated. ```bash cd LLM4Decompile python ./evaluation/run_evaluation_llm4decompile_singleGPU.py ``` -------------------------------- ### Evaluate using GPT-Judge Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/README.md Evaluate decompilation results using GPT-Judge. Requires a JSON file, a list of decompilers, an optimization flag, and an OpenAI API key. ```bash python gpt_judge.py --json_file your_json_file_path --decompilers decompiler1,decompiler2,...,decompilerN --opt OPT --api_key your_openai_api_key ``` -------------------------------- ### Run Identifier Naming RL Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/README.md Execute the script for identifier naming reinforcement learning. Requires an embedding server. ```bash bash verl/SK2DECOMPILE/scripts/run_ident_rl.sh ``` -------------------------------- ### Decompile Binary with Ghidra Headless Source: https://github.com/albertan017/llm4decompile/blob/main/ghidra/README.md Python script to compile C code, run Ghidra headless for decompilation, and extract function pseudo-code. Ensure paths for Ghidra, postscript, and source files are correctly set. ```python import os import subprocess from tqdm import tqdm,trange import tempfile OPT = ["O0", "O1", "O2", "O3"] timeout_duration = 10 ghidra_path = "./ghidra_11.0.3_PUBLIC/support/analyzeHeadless"#path to the headless analyzer, change the path accordingly postscript = "./decompile.py"#path to the decompiler helper function, change the path accordingly project_path = "."#path to temp folder for analysis, change the path accordingly project_name = "tmp_ghidra_proj" func_path = "../samples/sample.c"#path to c code for compiling and decompiling, change the path accordingly 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, # Suppress stdout stderr=subprocess.DEVNULL, # Suppress stderr 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", # WARNING: This will delete the project after analysis ] 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:#**Replace** func0 with the function name you want to decompile. 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)):##########remove the comments 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"#prompt after = "\n# What is the source code?"#prompt input_asm_prompt = before+input_asm.strip()+after with open(fileName +'_' + opt +'.pseudo','w',encoding='utf-8') as f: f.write(input_asm_prompt) ``` -------------------------------- ### Fine-tuning with DeepSpeed Source: https://context7.com/albertan017/llm4decompile/llms.txt Fine-tuning is supported via DeepSpeed, enabling efficient training on a single GPU with low cost. This covers the initial stages of model development. ```Python # DeepSpeed fine-tuning configuration and scripts would be located here. # Example: deepspeed --num_gpus=1 train.py --deepspeed_config ds_config.json # This indicates support for DeepSpeed for single-GPU fine-tuning, costing around $20. pass ``` -------------------------------- ### Fine-tuning with LLaMA-Factory SFT Source: https://context7.com/albertan017/llm4decompile/llms.txt LLaMA-Factory SFT (Supervised Fine-Tuning) is supported for fine-tuning models. This provides a framework for adapting pre-trained models to specific decompilation tasks. ```Python # LLaMA-Factory SFT scripts and configurations would be used here. # This enables supervised fine-tuning of LLMs for decompilation tasks. pass ``` -------------------------------- ### Launch Identifier Naming RL Training Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/verl/SK2DECOMPILE/README.md Execute the Identifier Naming Reinforcement Learning training script. Ensure the embedding server is running and configure variables in `scripts/run_ident_rl.sh`. ```bash # 1. Start the embedding server python -m vllm.entrypoints.openai.api_server \ --model Qwen3-Embedding-0.6B --port 8000 --dtype float16 # 2. Edit scripts/run_ident_rl.sh to set: # VERL_DIR, VENV_PATH, MODEL_PATH, TRAIN_DATA, VAL_DATA, WANDB_* bash scripts/run_ident_rl.sh ``` -------------------------------- ### Compile AnghaBench Dataset Source: https://github.com/albertan017/llm4decompile/blob/main/train/README.md Compiles the AnghaBench dataset using a provided script. Specify the root path of AnghaBench and the desired output file name. ```bash python compile.py --root Anghabench_path --output AnghaBench_compile.jsonl ``` -------------------------------- ### Preprocess C Code to Assembly Prompt Source: https://github.com/albertan017/llm4decompile/blob/main/README.md This Python script compiles C code to binary and then disassembles it into assembly instructions. It extracts a specific function's assembly, cleans it, and formats it into a prompt for the LLM. Replace 'func0' with the target function name. ```python import subprocess import os func_name = 'func0' OPT = ["O0", "O1", "O2", "O3"] fileName = 'samples/sample' #'path/to/file' for opt_state in OPT: output_file = fileName +'_' + opt_state input_file = fileName+'.c' compile_command = f'gcc -o {output_file}.o {input_file} -{opt_state} -lm'#compile the code with GCC on Linux subprocess.run(compile_command, shell=True, check=True) compile_command = f'objdump -d {output_file}.o > {output_file}.s'#disassemble the binary file into assembly instructions subprocess.run(compile_command, shell=True, check=True) input_asm = '' with open(output_file+'.s') as f:#asm file asm= f.read() if '<'+func_name+'>:' not in asm: #IMPORTANT replace func0 with the function name raise ValueError("compile fails") asm = '<'+func_name+'>:' + asm.split('<'+func_name+'>:')[-1].split('\n\n')[0] #IMPORTANT replace func0 with the function name asm_clean = "" asm_sp = asm.split("\n") for tmp in asm_sp: if len(tmp.split("\t"))<3 and '00' in tmp: continue idx = min( len(tmp.split("\t")) - 1, 2 ) tmp_asm = "\t".join(tmp.split("\t")[idx:]) # remove the binary code tmp_asm = tmp_asm.split("#")[0].strip() # remove the comments asm_clean += tmp_asm + "\n" input_asm = asm_clean.strip() before = "# This is the assembly code:" after = "\n# What is the source code?" input_asm_prompt = before+input_asm.strip()+after with open(fileName +'_' + opt_state +'.asm','w',encoding='utf-8') as f: f.write(input_asm_prompt) ``` -------------------------------- ### SK²Decompile Reproduction Pipeline Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/evaluation/bringupbench/README.md Visual representation of the five-step evaluation pipeline for SK²Decompile, from source code to evaluation reports. ```text Source (.c) │ ▼ Step 1: Compilation Binary (.host.O0 ~ .host.O3) │ ├──▶ Step 2: Baseline Extraction (IDA Pro) ──▶ Pseudocode (.pseudo) │ ├──▶ Step 3: Ground Truth Mapping ──▶ Function Maps (.func_map.jsonl) │ ▼ Step 4: Decompilation (SK²Decompile) Inferred C code (.func_map.infer.jsonl) │ ▼ Step 5: Validation Evaluation Reports (reports/) ``` -------------------------------- ### Compile C to Binary and Disassemble to Assembly Source: https://context7.com/albertan017/llm4decompile/llms.txt Compiles a C source file with GCC at optimization levels O0-O3 and extracts a function's disassembly using objdump, preparing it as a clean ASM prompt for LLMs. Ensure the target function name exists in the C file. ```python import subprocess import os func_name = 'func0' # Replace with the target function name OPT = ["O0", "O1", "O2", "O3"] fileName = 'samples/sample' # Path without extension for opt_state in OPT: output_file = fileName + '_' + opt_state input_file = fileName + '.c' # Compile with GCC subprocess.run( f'gcc -o {output_file}.o {input_file} -{opt_state} -lm', shell=True, check=True ) # Disassemble to text subprocess.run( f'objdump -d {output_file}.o > {output_file}.s', shell=True, check=True ) with open(output_file + '.s') as f: asm = f.read() if f'<{func_name}>:' not in asm: raise ValueError(f"Function '{func_name}' not found after compilation") # Extract the target function block asm = f'<{func_name}>:' + asm.split(f'<{func_name}>:')[-1].split('\n\n')[0] asm_clean = "" for line in asm.split("\n"): if len(line.split("\t")) < 3 and '00' in line: continue idx = min(len(line.split("\t")) - 1, 2) tmp_asm = "\t".join(line.split("\t")[idx:]).split("#")[0].strip() asm_clean += tmp_asm + "\n" # Wrap in model prompt format prompt = "# This is the assembly code:\n" + asm_clean.strip() + "\n# What is the source code?\n" with open(fileName + '_' + opt_state + '.asm', 'w') as f: f.write(prompt) # Expected .asm file content: # # This is the assembly code: # : # endbr64 # lea (%rdi,%rsi,1),%eax # retq # # What is the source code? ``` -------------------------------- ### Check Results (O0) Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/evaluation/bringupbench/README.md View the evaluation results for the O0 optimization level. ```bash cat reports/O0_results.md ``` -------------------------------- ### Normalize Pseudo-code with Python Source: https://github.com/albertan017/llm4decompile/blob/main/sk2decompile/README.md Normalize raw pseudo-code into a standard representation using the `normalize_pseudo.py` script. Ensure the correct input and output JSON files and key name are specified. ```bash cd Preprocess # Requirements pip install tree-sitter==0.24.0 tree-sitter-c==0.23.4 tqdm # Step 1: Normalize pseudo-code according to R2I standard python3 normalize_pseudo.py --input_json exebench_c.json --output_json exebench_pseudonorm.json --key_name pseudo ```