{"id":14991192,"url":"https://github.com/lifting-bits/rellic","last_synced_at":"2025-04-07T16:17:40.927Z","repository":{"id":34841482,"uuid":"161553342","full_name":"lifting-bits/rellic","owner":"lifting-bits","description":"Rellic produces goto-free C output from LLVM bitcode","archived":false,"fork":false,"pushed_at":"2024-09-03T21:03:51.000Z","size":3445,"stargazers_count":554,"open_issues_count":37,"forks_count":42,"subscribers_count":29,"default_branch":"master","last_synced_at":"2025-03-31T15:17:42.374Z","etag":null,"topics":["c","decompiler","llvm","reverse-engineering"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lifting-bits.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-12-12T22:32:12.000Z","updated_at":"2025-03-20T07:57:23.000Z","dependencies_parsed_at":"2023-02-14T17:31:09.737Z","dependency_job_id":"804d06a4-5074-4d2c-b1ab-73a11f074cf9","html_url":"https://github.com/lifting-bits/rellic","commit_stats":{"total_commits":444,"total_committers":19,"mean_commits":23.36842105263158,"dds":0.5427927927927928,"last_synced_commit":"22f65d60996958f028620e3effac4bf79a375c12"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lifting-bits%2Frellic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lifting-bits%2Frellic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lifting-bits%2Frellic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lifting-bits%2Frellic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lifting-bits","download_url":"https://codeload.github.com/lifting-bits/rellic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247685628,"owners_count":20979085,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","decompiler","llvm","reverse-engineering"],"created_at":"2024-09-24T14:21:42.623Z","updated_at":"2025-04-07T16:17:40.905Z","avatar_url":"https://github.com/lifting-bits.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Rellic\n\nRellic is an implementation of the [pattern-independent structuring](https://github.com/lifting-bits/rellic/blob/master/docs/NoMoreGotos.pdf) algorithm to produce a goto-free C output from LLVM bitcode.\n\nThe design philosophy behind the project is to provide a relatively small and easily hackable codebase with great interoperability with other LLVM and [Remill](https://github.com/lifting-bits/remill) projects.\n\n## Examples\n\n\u003ctable\u003e\n\u003cthead\u003e\n  \u003ctd\u003eOriginal program\u003c/td\u003e\n  \u003ctd\u003eCompiled with \u003ccode\u003e-emit-llvm -O0\u003c/code\u003e and decompiled\u003c/td\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n```c\nint main() {\n  for(int i = 0; i \u003c 30; ++i) {\n    if(i % 3 == 0 \u0026\u0026 i % 5 == 0) {\n      printf(\"fizzbuzz\\n\");\n    } else if(i % 3 == 0) {\n      printf(\"fizz\\n\");\n    } else if(i % 5 == 0) {\n      printf(\"buzz\\n\");\n    } else {\n      printf(\"%d\\n\", i);\n    }\n  }\n}\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n```c\nint main() {\n  unsigned int var0;\n  unsigned int i;\n  var0 = 0U;\n  i = 0U;\n  while ((int)i \u003c 30) {\n    if ((int)i % 3 != 0U || !((int)i % 5 == 0U || (int)i % 3 != 0U)) {\n      if ((int)i % 3 != 0U) {\n        if ((int)i % 5 != 0U) {\n          printf(\"%d\\n\", i);\n        } else {\n          printf(\"buzz\\n\");\n        }\n      } else {\n        printf(\"fizz\\n\");\n      }\n    } else {\n      printf(\"fizzbuzz\\n\");\n    }\n    i = i + 1U;\n  }\n  return var0;\n}\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n```c\nint main() {\n  int i = 0;\n  start:\n  i++;\n  switch(i) {\n    case 1: printf(\"%d\\n\", i); goto start; break;\n    case 2: printf(\"%d\\n\", i); goto start; break;\n    case 3: printf(\"%d\\n\", i); break;\n  }\n}\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n```c\nint main() {\n  unsigned int var0;\n  unsigned int i;\n  var0 = 0U;\n  i = 0U;\n  do {\n    i = i + 1U;\n    if (!(i != 3U \u0026\u0026 i != 2U \u0026\u0026 i != 1U))\n      if (i == 3U) {\n        printf(\"%d\\n\", i);\n        break;\n      } else if (i == 2U) {\n        printf(\"%d\\n\", i);\n      } else {\n        printf(\"%d\\n\", i);\n      }\n  } while (!(i != 3U \u0026\u0026 i != 2U \u0026\u0026 i != 1U));\n  return var0;\n}\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n```c\nint main() {\n  int x = atoi(\"5\");\n  if(x \u003e 10) {\n    while(x \u003c 20) {\n      x = x + 1;\n      printf(\"loop1 x: %d\\n\", x);\n    }\n  }\n  while(x \u003c 20) {\n    x = x + 1;\n    printf(\"loop2 x: %d\\n\", x);\n  }\n}\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n```c\nint main() {\n  unsigned int var0;\n  unsigned int x;\n  unsigned int call2;\n  var0 = 0U;\n  call2 = atoi(\"5\");\n  x = call2;\n  if ((int)x \u003e 10) {\n    while ((int)x \u003c 20) {\n      x = x + 1U;\n      printf(\"loop1 x: %d\\n\", x);\n    }\n  }\n  if ((int)x \u003c= 10 || (int)x \u003e= 20) {\n    while ((int)x \u003c 20) {\n      x = x + 1U;\n      printf(\"loop2 x: %d\\n\", x);\n    }\n  }\n  if ((int)x \u003e= 20 \u0026\u0026 ((int)x \u003c= 10 || (int)x \u003e= 20)) {\n    return var0;\n  }\n}\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n## In the press\n\n[C your data structures with `rellic-headergen`](https://blog.trailofbits.com/2022/01/19/c-your-data-structures-with-rellic-headergen/)\n\n[Interactive decompilation with `rellic-xref`](https://blog.trailofbits.com/2022/05/17/interactive-decompilation-with-rellic-xref/)\n\n[Magnifier: an experiment with interactive decompilation](https://blog.trailofbits.com/2022/08/25/magnifier-an-experiment-with-interactive-decompilation/)\n\n## Build Status\n\n|       | master |\n| ----- | ------ |\n| Linux | [![Build Status](https://github.com/lifting-bits/rellic/workflows/CI/badge.svg)](https://github.com/lifting-bits/rellic/actions?query=workflow%3ACI)|\n\n## Getting Help\n\nIf you are experiencing undocumented problems with Rellic then ask for help in the `#binary-lifting` channel of the [Empire Hacking Slack](https://slack.empirehacking.nyc/).\n\n## Supported Platforms\n\nRellic is supported on Linux platforms and has been tested on Ubuntu 22.04.\n\n## Dependencies\n\nMost of Rellic's dependencies can be provided by the [cxx-common](https://github.com/lifting-bits/cxx-common) repository. Trail of Bits hosts downloadable, pre-built versions of cxx-common, which makes it substantially easier to get up and running with Rellic. Nonetheless, the following table represents most of Rellic's dependencies.\n\n| Name | Version |\n| ---- | ------- |\n| [Git](https://git-scm.com/) | Latest |\n| [CMake](https://cmake.org/) | 3.21+ |\n| [Google Flags](https://github.com/google/glog) | Latest |\n| [Google Log](https://github.com/google/glog) | Latest |\n| [LLVM](http://llvm.org/) | 16|\n| [Clang](http://clang.llvm.org/) | 16|\n| [Z3](https://github.com/Z3Prover/z3) | 4.7.1+ |\n\n## Pre-made Docker Images\n\nPre-built Docker images are available on [Docker Hub](https://hub.docker.com/repository/docker/lifting-bits/rellic) and the Github Package Registry.\n\n## Getting and Building the Code\n\n### On Linux\n\nFirst, update aptitude and get install the baseline dependencies.\n\n```shell\nsudo apt update\nsudo apt upgrade\n\nsudo apt install \\\n     git \\\n     python3 \\\n     wget \\\n     unzip \\\n     pixz \\\n     xz-utils \\\n     cmake \\\n     curl \\\n     build-essential \\\n     lsb-release \\\n     zlib1g-dev \\\n     libomp-dev \\\n     doctest-dev\n```\n\nIf the distribution you're on doesn't include a recent release of CMake (3.21 or later), you'll need to install it. For Ubuntu, see here \u003chttps://apt.kitware.com/\u003e.\n\nThe next step is to clone the Rellic repository.\n\n```shell\ngit clone --recurse-submodules https://github.com/lifting-bits/rellic.git\n```\n\nFinally, we build and package Rellic. This script will create another directory, `rellic-build`, in the current working directory. All remaining dependencies needed by Rellic will be downloaded and placed in the parent directory alongside the repo checkout in `lifting-bits-downloads` (see the script's `-h` option for more details). This script also creates installable deb, rpm, and tgz packages.\n\n```shell\ncd rellic\n./scripts/build.sh --llvm-version 16\n# to install the deb package, then do:\nsudo dpkg -i rellic-build/*.deb\n```\n\nTo try out Rellic you can do the following, given a LLVM bitcode file of your choice.\n\n```shell\n# Create some sample bitcode or your own\nclang-16 -emit-llvm -c ./tests/tools/decomp/issue_4.c -o ./tests/tools/decomp/issue_4.bc\n\n./rellic-build/tools/rellic-decomp --input ./tests/tools/decomp/issue_4.bc --output /dev/stdout\n```\n\n### On macOS\n\nMake sure to have the latest release of cxx-common for LLVM 16. Then, build with\n\n```shell\ncmake \\\n  -DCMAKE_BUILD_TYPE=RelWithDebInfo \\\n  -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake \\\n  -DVCPKG_TARGET_TRIPLET=x64-osx-rel \\\n  -DRELLIC_ENABLE_TESTING=OFF \\\n  -DCMAKE_C_COMPILER=`which clang` \\\n  -DCMAKE_CXX_COMPILER=`which clang++` \\\n  /path/to/rellic\n\nmake -j8\n```\n\n### Docker image\n\nThe Docker image should provide an environment which can set-up, build, and run rellic. The Docker images are parameterized by Ubuntu verison, LLVM version, and architecture.\n\nTo build the docker image using LLVM 16 for Ubuntu 22.04 you can run the following command:\n\n```sh\nUBUNTU=22.04; LLVM=16; docker build . \\\n  -t rellic:llvm${LLVM}-ubuntu${UBUNTU} \\\n  -f Dockerfile \\\n  --build-arg UBUNTU_VERSION=${UBUNTU} \\\n  --build-arg LLVM_VERSION=${LLVM}\n```\n\nTo run the decompiler, the entrypoint has already been set, but make sure the bitcode you are decompiling is the same LLVM version as the decompiler, and run:\n\n```sh\n# Get the bc file\nclang-16 -emit-llvm -c ./tests/tools/decomp/issue_4.c -o ./tests/tools/decomp/issue_4.bc\n\n# Decompile\ndocker run --rm -t -i \\\n  -v $(pwd):/test -w /test \\\n  -u $(id -u):$(id -g) \\\n  rellic:llvm16-ubuntu22.04 --input ./tests/tools/decomp/issue_4.bc --output /dev/stdout\n```\n\nTo explain the above command more:\n\n```sh\n# Mount current directory and change working directory\n-v $(pwd):/test -w /test\n```\n\nand\n\n```sh\n# Set the user to current user to ensure correct permissions\n-u $(id -u):$(id -g) \\\n```\n\n## Testing\n\nWe use several integration and unit tests to test rellic.\n\n*Roundtrip tests* will take C code, build it to LLVM IR, and then translate that IR back to C. The test then sees if the resulting C can be built and if the translated code does (roughly) the same thing as the original. To run these, use:\n\n```sh\ncd rellic-build #or your rellic build directory\nCTEST_OUTPUT_ON_FAILURE=1 cmake --build . --verbose --target test\n```\n\n*AnghaBench 1000* is a sample of 1000 files (x 4 architectures, so a total of 4000 tests) from the full million programs that come with AnghaBench. This test only checks whether the bitcode for these programs translates to C, not the prettiness or functionality of the resulting translation. To run this test, first install the required Python dependencies found in `scripts/requirements.txt` and then run:\n\n```sh\nscripts/test-angha-1k.sh --rellic-cmd \u003cpath_to_rellic_decompiler_exe\u003e\n```\n\n## Citing Rellic\n\nPlease use the following BibTeX snippet to cite Rellic:\n\n```tex\n@online{rellic,\n  title={Rellic},\n  author={Surovič, Marek and Bertolaccini, Francesco},\n  organization={Trail of Bits},\n  url={https://github.com/lifting-bits/rellic}\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flifting-bits%2Frellic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flifting-bits%2Frellic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flifting-bits%2Frellic/lists"}