Skip to content

Commit

Permalink
test: refactor decompilation script testing framework and use lit runner
Browse files Browse the repository at this point in the history
  • Loading branch information
kumarak committed Aug 27, 2024
1 parent c3493f7 commit c947fd3
Show file tree
Hide file tree
Showing 50 changed files with 344 additions and 230 deletions.
34 changes: 3 additions & 31 deletions scripts/ghidra/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
# Decompilation and Testing Framework
# Decompilation Framework

The directory includes a decompilation script that runs Ghidra in headless mode
to extract pcode for specific functions from binary files. It also features a
testing framework that compiles the source files, generates the corresponding
pcode for the specified function, and validates the output using the FileCheck
verifier.
The directory includes a decompilation script that runs Ghidra in headless mode to extract pcode for specific functions from binary files.

We support two decompilation modes:

Expand All @@ -16,12 +12,8 @@ We support two decompilation modes:
Before running the scripts, make sure you have the following installed:

- **Docker**: The scripts use a Docker container to run Ghidra in headless mode.
- **FileCheck**: The `FileCheck` tool is installed and available in your PATH. It is typically part of LLVM suite.


## Usage

### Run Headless Decompilation Script
## Running Headless Decompilation Script

To decompile and extract pcode for a specific function from a binary file, use
the `decompile-headless.sh` script. This script extracts the pcode for the
Expand All @@ -30,26 +22,6 @@ in the output directory.

```bash ./decompile-headless.sh <binary> <function-name> <output-file> ```

### Testing the Output

#### Using Test Script

You can run all the tests using `decompile-headless-test.sh` script:

```
./decompile-headless-test.sh
```

#### Testing with CMake

Alternatively, you can use CMake to configure, build, and run the tests.

```
cmake -B /path/to/build -S /path/to/test
cmake --build /path/to/build
ctest --test-dir /path/to/build
```

## Running Patchestry via Ghidra GUI

1. Ensure Patchestry is available via PATH:
Expand Down
18 changes: 0 additions & 18 deletions scripts/ghidra/decompile-headless-test.sh

This file was deleted.

12 changes: 5 additions & 7 deletions scripts/ghidra/decompile-headless.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ fi
INPUT_PATH=$1
FUNCTION_NAME=$2
OUTPUT_PATH=$3
TMP_OUTPUT_PATH="/tmp/patchestry.out.json"

# Create docker container and run the decompilation
docker build \
Expand All @@ -30,14 +29,13 @@ if [ $? -ne 0 ]; then
fi

# Make sure $TMP_OUTPUT_PATH exists so that it gets properly mounted
touch $TMP_OUTPUT_PATH
if [ ! -f $OUTPUT_PATH ]; then
touch $OUTPUT_PATH
fi
truncate -s 0 $OUTPUT_PATH

docker run --rm \
-v $INPUT_PATH:/input \
-v $TMP_OUTPUT_PATH:/output \
-v $OUTPUT_PATH:/output \
trailofbits/patchestry-decompilation:latest \
/input $FUNCTION_NAME /output

if [ $(dirname $TMP_OUTPUT_PATH) != $OUTPUT_PATH ]; then
mv $TMP_OUTPUT_PATH $OUTPUT_PATH
fi
32 changes: 0 additions & 32 deletions scripts/ghidra/test/CMakeLists.txt

This file was deleted.

19 changes: 0 additions & 19 deletions scripts/ghidra/test/run-test.sh

This file was deleted.

8 changes: 0 additions & 8 deletions scripts/ghidra/test/src/argc.c

This file was deleted.

1 change: 0 additions & 1 deletion scripts/ghidra/test/src/argc.function

This file was deleted.

1 change: 0 additions & 1 deletion scripts/ghidra/test/src/array.function

This file was deleted.

1 change: 0 additions & 1 deletion scripts/ghidra/test/src/concat.function

This file was deleted.

14 changes: 0 additions & 14 deletions scripts/ghidra/test/src/fib.c

This file was deleted.

1 change: 0 additions & 1 deletion scripts/ghidra/test/src/fib.function

This file was deleted.

1 change: 0 additions & 1 deletion scripts/ghidra/test/src/fread.function

This file was deleted.

1 change: 0 additions & 1 deletion scripts/ghidra/test/src/fwrite.function

This file was deleted.

1 change: 0 additions & 1 deletion scripts/ghidra/test/src/insert.function

This file was deleted.

1 change: 0 additions & 1 deletion scripts/ghidra/test/src/list.function

This file was deleted.

1 change: 0 additions & 1 deletion scripts/ghidra/test/src/matrix.function

This file was deleted.

1 change: 0 additions & 1 deletion scripts/ghidra/test/src/prime.function

This file was deleted.

1 change: 0 additions & 1 deletion scripts/ghidra/test/src/queue.function

This file was deleted.

1 change: 0 additions & 1 deletion scripts/ghidra/test/src/reverse.function

This file was deleted.

1 change: 0 additions & 1 deletion scripts/ghidra/test/src/sort.function

This file was deleted.

15 changes: 0 additions & 15 deletions scripts/ghidra/test/src/struct.c

This file was deleted.

1 change: 0 additions & 1 deletion scripts/ghidra/test/src/struct.function

This file was deleted.

19 changes: 0 additions & 19 deletions scripts/ghidra/test/src/structb.c

This file was deleted.

1 change: 0 additions & 1 deletion scripts/ghidra/test/src/structb.function

This file was deleted.

7 changes: 0 additions & 7 deletions scripts/ghidra/test/src/sub.c

This file was deleted.

1 change: 0 additions & 1 deletion scripts/ghidra/test/src/sub.function

This file was deleted.

19 changes: 0 additions & 19 deletions scripts/ghidra/test/src/union.c

This file was deleted.

1 change: 0 additions & 1 deletion scripts/ghidra/test/src/union.function

This file was deleted.

33 changes: 27 additions & 6 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
# Copyright (c) 2024, Trail of Bits, Inc. All rights reserved. This source code
# is licensed in accordance with the terms specified in the LICENSE file found
# in the root directory of this source tree.

cmake_minimum_required(VERSION 3.25)

include(CTest)

add_executable(patchestry_test ghidra.cpp)
target_link_libraries(patchestry_test
PRIVATE
patchestry_ghidra
patchestry_settings
# Configure the lit site configuration file
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py
MAIN_CONFIG
${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py
)

# Define test dependencies
set(TEST_DEPS
FileCheck
)

# Add a lit test suite named "PatchestryTest"
add_lit_testsuite(PatchestryTest "Running Patchestry tests"
${CMAKE_CURRENT_SOURCE_DIR}/ghidra
DEPENDS ${TEST_DEPS}
)

add_test(NAME patchestry_test COMMAND patchestry_test)
# Add a CTest test that runs the lit test suite
add_test(NAME lit
COMMAND lit -v "${CMAKE_CURRENT_BINARY_DIR}/ghidra"
--param BUILD_TYPE=$<CONFIG>)
8 changes: 0 additions & 8 deletions test/ghidra.cpp

This file was deleted.

14 changes: 14 additions & 0 deletions test/ghidra/argc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// UNSUPPORTED: system-windows
// RUN: %cc %s -o %t
// RUN %t; if [ "$(uname)" = "Linux" ]; then %decompile-headless %t argc %t1 fi
// RUN %t; if [ "$(uname)" = "Darwin" ]; then %decompile-headless %t _argc %t1 fi
// RUN %t1; %file-check %s --input-file %t1
// CHECK: {{...}}

int argc(int argc, char **argv) {
return argc;
}
int main(int a, char **argv)
{
return argc(a, argv);
}
7 changes: 7 additions & 0 deletions scripts/ghidra/test/src/array.c → test/ghidra/array.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
// UNSUPPORTED: system-windows
// RUN: %cc %s -o %t
// RUN %t; if [ "$(uname)" = "Linux" ]; then %decompile-headless %t main %t1 fi
// RUN %t; if [ "$(uname)" = "Darwin" ]; then %decompile-headless %t _main %t1 fi
// RUN %t1; %file-check %s --input-file %t1
// CHECK: {{...}}

#include <stdio.h>
#include <stdlib.h>

Expand Down
8 changes: 7 additions & 1 deletion scripts/ghidra/test/src/concat.c → test/ghidra/concat.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
// UNSUPPORTED: system-windows
// RUN: %cc %s -o %t
// RUN %t; if [ "$(uname)" = "Linux" ]; then %decompile-headless %t string_concat %t1 fi
// RUN %t; if [ "$(uname)" = "Darwin" ]; then %decompile-headless %t _string_concat %t1 fi
// RUN %t1; %file-check %s --input-file %t1
// CHECK: {{...}}

#include <stdio.h>
#include <string.h>

// CHECK: {{...}}
char* string_concat(char* dest, const char* src) {
strcat(dest, src);
return dest;
Expand Down
20 changes: 20 additions & 0 deletions test/ghidra/fib.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// UNSUPPORTED: system-windows
// RUN: %cc %s -o %t
// RUN %t; if [ "$(uname)" = "Linux" ]; then %decompile-headless %t fibonacci %t1 fi
// RUN %t; if [ "$(uname)" = "Darwin" ]; then %decompile-headless %t _fibonacci %t1 fi
// RUN %t1; %file-check %s --input-file %t1
// CHECK: {{...}}

#include <stdio.h>

int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}

int main() {
int n = 10;
printf("%d: %d\n", n, fibonacci(n));
return 0;
}

8 changes: 7 additions & 1 deletion scripts/ghidra/test/src/fread.c → test/ghidra/fread.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// UNSUPPORTED: system-windows
// RUN: %cc %s -o %t
// RUN %t; if [ "$(uname)" = "Linux" ]; then %decompile-headless %t main %t1 fi
// RUN %t; if [ "$(uname)" = "Darwin" ]; then %decompile-headless %t _main %t1 fi
// RUN %t1; %file-check %s --input-file %t1
// CHECK: {{...}}

#include <stdio.h>

//CHECK: {{...}}
int main(void) {
FILE *file = fopen("example.txt", "r");
if (!file) {
Expand Down
Loading

0 comments on commit c947fd3

Please sign in to comment.