Library for lifting of x86, amd64, and aarch64 machine code to LLVM bitcode
Remill is a static binary translator that translates machine code instructions into LLVM bitcode. It translates AArch64 (64-bit ARMv8), SPARC32 (SPARCv8), SPARC64 (SPARCv9), x86 and amd64 machine code (including AVX and AVX512) into LLVM bitcode. AArch32 (32-bit ARMv8 / ARMv7) support is underway.
Remill focuses on accurately lifting instructions. It is meant to be used as a library for other tools, e.g. McSema.
If you are experiencing undocumented problems with Remill then ask for help in the
#binary-liftingchannel of the Empire Hacking Slack.
Remill is supported on Linux platforms and has been tested on Ubuntu 14.04, 16.04, and 18.04. Remill also works on macOS, and has experimental support for Windows.
Remill's Linux version can also be built via Docker for quicker testing.
Most of Remill's dependencies can be provided by the 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 Remill. Nonetheless, the following table represents most of Remill's dependencies.
| Name | Version | | ---- | ------- | | Git | Latest | | CMake | 3.14+ | | Google Flags | Latest | | Google Log | Latest | | Google Test | Latest | | LLVM | 12 | | Clang | 12 | | Intel XED | Latest | | Python | 2.7 | | Unzip | Latest | | ccache | Latest |
Remill now comes with a Dockerfile for easier testing. This Dockerfile references the cxx-common container to have all pre-requisite libraries available.
The Dockerfile allows for quick builds of multiple supported LLVM, architecture, and Linux configurations.
Quickstart (builds Remill against LLVM 12 on Ubuntu 18.04 for AMD64):
Clone Remill: ```shell
git clone https://github.com/lifting-bits/remill.git cd remill ```
Build Remill Docker container: ```shell
docker build . -t remill \ -f Dockerfile \ --build-arg UBUNTUVERSION=18.04 \ --build-arg ARCH=amd64 \ --build-arg LLVMVERSION=12 ```
Ensure remill works: ```shell
docker run --rm -it remill \ --arch amd64 --ir_out /dev/stdout --bytes c704ba01000000
docker run --rm -it remill \ --arch aarch64 --address 0x400544 --ir_out /dev/stdout \ --bytes FD7BBFA90000009000601891FD030091B7FFFF97E0031F2AFD7BC1A8C0035FD6 ```
First, update aptitude and get install the baseline dependencies.
sudo dpkg --add-architecture i386 sudo apt-get update sudo apt-get upgrade
sudo apt-get install
Next, clone the repository. This will clone the code into the
git clone https://github.com/lifting-bits/remill.git
Next, we build Remill. This script will create another directory,
remill-build, in the current working directory. All remaining dependencies needed by Remill will be built in the
Next, we can install Remill. Remill itself is a library, and so there is no real way to try it. However, you can head on over to the McSema repository, which uses Remill for lifting instructions.
cd ./remill-build sudo make install
We can also build and run Remill's test suite.
cd ./remill-build make test_dependencies make test
Sometimes, you want to build everything from source, including the cxx-common libraries remill depends on. To build against a custom cxx-common location, you can use the following
mkdir build cd build cmake \ -DCMAKE_INSTALL_PREFIX="" \ -DVCPKG_ROOT="/vcpkg" \ -G Ninja \ .. cmake --build . cmake --build . --target install
The output may produce some CMake warnings about policy CMP0003. These warnings are safe to ignore.
If you see errors similar to the following:
fatal error: 'bits/c++config.h' file not found
Then you need to install 32-bit libstdc++ headers and libraries. On a Debian/Ubuntu based distribution, You would want to do something like this:
sudo dpkg --add-architecture i386 sudo apt-get update sudo apt-get install libc6-dev:i386 libstdc++-10-dev:i386 g++-multilib
This error happens because the SPARC32 runtime semantics (the bitcode library which lives in
/share/remill//semantics/sparc32.bc) are built as 32-bit code, but 32-bit development libraries are not installed by default.
A similar situation occurs when building remill on arm64 Linux. In that case, you want to follow a similar workflow, except the architecture used in
apt-getcommands would be
Another alternative is to disable SPARC32 runtime semantics. To do that, use the
-DREMILL_BUILD_SPARC32_RUNTIME=Falseoption when invoking