From 8263147956f5872f26255d763b61d2d8cc0aad55 Mon Sep 17 00:00:00 2001 From: Ryan Stortz Date: Sat, 28 Nov 2015 20:26:37 -0500 Subject: [PATCH 1/3] Saving work adding OS X support. I think the llvm+clang download has rtti off but this project requires it to be on. We might need to build llvm and clang each time. :( --- CMakeLists.txt | 23 ++++--- scripts/bootstrap.sh | 2 +- scripts/bootstrap_osx.sh | 135 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 10 deletions(-) create mode 100755 scripts/bootstrap_osx.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a1dcbcd..689a5cbb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,17 +6,24 @@ cmake_minimum_required (VERSION 2.8) set(CMAKE_C_COMPILER "${MCSEMA_DIR}/third_party/llvm/build/bin/clang") set(CMAKE_CXX_COMPILER "${MCSEMA_DIR}/third_party/llvm/build/bin/clang") -list(APPEND CMAKE_MODULE_PATH "${MCSEMA_DIR}/third_party/llvm/build/share/llvm/cmake") +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${MCSEMA_DIR}/third_party/llvm/build/share/llvm/cmake/) + +set(LLVM_INSTALL_PREFIX ${MCSEMA_DIR}/third_party/llvm/build) +set(_LLVM_CMAKE_DIR ${MCSEMA_DIR}/third_party/llvm/build/share/llvm/cmake) +set(_LLVM_LIBRARY_DIR "${LLVM_INSTALL_PREFIX}/lib") # Find LLVM. -include(LLVMConfig) -include(AddLLVM) +find_package(LLVM REQUIRED Config) +#include(LLVMConfig) +#include(AddLLVM) # Add LLVM includes. -link_directories(${MCSEMA_DIR}/third_party/llvm/build/lib) add_definitions(${LLVM_DEFINITIONS}) include_directories(${LLVM_INCLUDE_DIRS}) +link_directories(${MCSEMA_DIR}/third_party/llvm/build/lib) +set(LLVM_LIBRARY_DIRS ${MCSEMA_DIR}/third_party/llvm/build/lib) + # Find Protocol Buffers. find_package(Protobuf REQUIRED) include_directories(${PROTOBUF_INCLUDE_DIRS}) @@ -56,6 +63,8 @@ add_executable(cfg_to_bc ${MCSEMA_DIR}/mcsema/Translate.cpp ${MCSEMA_SOURCE_FILES} ) + +llvm_map_components_to_libnames(llvm_libs x86desc x86info x86utils irreader bitreader bitwriter transformutils scalaropts ipo) target_link_libraries(cfg_to_bc xed @@ -63,11 +72,7 @@ target_link_libraries(cfg_to_bc glog gflags stdc++ - LLVMX86Desc LLVMX86Info LLVMX86Utils - LLVMIRReader LLVMBitReader LLVMBitWriter - LLVMTransformUtils - LLVMScalarOpts - LLVMipo + ${llvm_libs} ) target_compile_options(cfg_to_bc PRIVATE diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh index 46ef75f6..a8f87007 100755 --- a/scripts/bootstrap.sh +++ b/scripts/bootstrap.sh @@ -7,7 +7,7 @@ if [[ "$OSTYPE" == "linux-gnu" ]]; then exec $SCRIPTS_DIR/bootstrap_linux.sh elif [[ "$OSTYPE" == "darwin"* ]]; then - echo "Mac OS X isn't yet supported! You should add it ;-)" + exec $SCRIPTS_DIR/bootstrap_osx.sh else echo "Unsupported platform: $OSTYPE" diff --git a/scripts/bootstrap_osx.sh b/scripts/bootstrap_osx.sh new file mode 100755 index 00000000..76df02f8 --- /dev/null +++ b/scripts/bootstrap_osx.sh @@ -0,0 +1,135 @@ +#!/usr/bin/env bash +# Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved. + +LLVM_VERSION=3.7.0 +PIN_VERSION=2.14-71313-clang.5.1-mac + +PIN_URL=http://software.intel.com/sites/landingpage/pintool/downloads/pin-${PIN_VERSION}.tar.gz +LLVM_URL=http://llvm.org/releases/${LLVM_VERSION}/clang+llvm-${LLVM_VERSION}-x86_64-apple-darwin.tar.xz + +# Directory in which the script dir resides (i.e. McSema root dir). +DIR=$(dirname $( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )) + +RED=`tput setaf 1` +GREEN=`tput setaf 2` +YELLOW=`tput setaf 3` +RESET=`tput sgr0` + + +function download_and_install_llvm() +{ + echo "${YELLOW}Downloading LLVM and clang ${LLVM_VERSION}.${RESET}" + + # Create third_party directory if it doesn't exist + mkdir -p $DIR/third_party + pushd $DIR/third_party + + # Download a pre-built clang+llvm to it. OS X doesn't have wget by default. :( + curl -O ${LLVM_URL} + + # Extract it to the path expected by compile_semantics.sh + mkdir -p $DIR/third_party/llvm/build + tar zxf clang+llvm-${LLVM_VERSION}-x86_64-apple-darwin.tar.xz -C llvm/build/ --strip-components=1 + + popd +} + +function download_and_install_glog() +{ + echo "${YELLOW}Downloading and installing glog.${RESET}" + + pushd $DIR/third_party + + #git clone https://github.com/google/glog.git -t v0.3.4 + curl -L -O https://github.com/google/glog/archive/v0.3.4.tar.gz + + mkdir -p $DIR/third_party/glog + tar zxf v0.3.4.tar.gz -C glog/ --strip-components=1 + + popd + + pushd $DIR/third_party/glog + ./configure --prefix=/usr/local + make + make install + popd + +} + +function download_and_extract_pin() +{ + echo "${YELLOW}Downloading and installing pin.${RESET}" + + pushd $DIR/third_party + + curl -L -O ${PIN_URL} + + mkdir -p $DIR/third_party/pin + tar zxf pin-${PIN_VERSION}.tar.gz -C pin/ --strip-components=1 + + popd +} + +# Fetch all dependencies. +echo "${GREEN}Checking dependencies.${RESET}" + +# Check for llvm ${LLVM_VERSION} +if [[ -e $DIR/third_party/llvm/build/bin/clang++ ]]; then + echo "${GREEN}LLVM and clang FOUND!${RESET}" +else + download_and_install_llvm +fi; + +if [[ -e /usr/local/include/glog ]]; then + echo "${GREEN}glog FOUND!${RESET}" +else + download_and_install_glog +fi; + + +if [[ -e $DIR/third_party/pin/pin ]]; then + echo "${GREEN}pin FOUND!${RESET}" +else + download_and_extract_pin +fi; + +# Create the generated files directories. +echo "${GREEN}Creating aut-generated files.${RESET}" +cd $DIR +mkdir -p $DIR/generated +mkdir -p $DIR/generated/Arch +mkdir -p $DIR/generated/CFG + + +# Generate 32- and 64-bit x86 machine state modules for importing by +# `cfg_to_bc`. +echo "${YELLOW}Generating architecture-specific state files.${RESET}" +$DIR/scripts/compile_semantics.sh + + +# Generate the protocol buffer file for the CFG definition. The lifter will +# read in CFG protobuf files and output LLVM bitcode files. +echo "${YELLOW}Generating protocol buffers.${RESET}" +cd $DIR/generated/CFG +cp $DIR/mcsema/CFG/CFG.proto $DIR/generated/CFG +protoc --cpp_out=. CFG.proto +protoc --python_out=. CFG.proto + + +# Build McSema. McSema will be built with the above version of Clang. +echo "${GREEN}Compiling McSema.${RESET}" +cd $DIR +mkdir -p $DIR/build +cd $DIR/build +cmake -G "Unix Makefiles" -DMCSEMA_DIR=$DIR -DCMAKE_PREFIX_PATH=$DIR/third_party/llvm/build/share/llvm .. +make all + + +# Find IDA. + +#echo "${GREEN}Finding IDA.${RESET}" +#IDA=`locate idal64 | head -n 1` +#if [ ! -e $IDA ] ; then +# echo "${RED}Error: Could not find IDA." +#fi + From 0f05671a0b55b99c73e5a5a27db6a04373268189 Mon Sep 17 00:00:00 2001 From: Ryan Stortz Date: Sat, 28 Nov 2015 20:39:01 -0500 Subject: [PATCH 2/3] Disable RTTI. Build works on OS X now! :) --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4897ecba..0c313aba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,7 @@ add_compile_options(-Wall) add_compile_options(-Werror) add_compile_options(-pedantic) add_compile_options(-DMCSEMA_DIR="${MCSEMA_DIR}") +add_compile_options(-DGOOGLE_PROTOBUF_NO_RTTI) add_executable(cfg_to_bc ${MCSEMA_DIR}/mcsema/Translate.cpp @@ -78,7 +79,7 @@ target_link_libraries(cfg_to_bc target_compile_options(cfg_to_bc PRIVATE -std=gnu++11 - -frtti + -fno-rtti -g3 -m64 ) From c559dfd15d2f6f9ab9cad6a8e45a8841883db790 Mon Sep 17 00:00:00 2001 From: Ryan Stortz Date: Sat, 28 Nov 2015 21:19:18 -0500 Subject: [PATCH 3/3] os x support for ida_get_cfg....with a dirty hack :-x --- scripts/ida_get_cfg.py | 3 ++- scripts/ida_get_cfg.sh | 13 ++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/scripts/ida_get_cfg.py b/scripts/ida_get_cfg.py index 5a02d3d2..02d521b4 100644 --- a/scripts/ida_get_cfg.py +++ b/scripts/ida_get_cfg.py @@ -16,6 +16,7 @@ GENERATED_DIR = os.path.join(MCSEMA_DIR, "generated") CFG_DIR = os.path.join(GENERATED_DIR, "CFG") sys.path.append('/usr/lib/python2.7/dist-packages') +sys.path.append('/usr/local/lib/python2.7/site-packages/protobuf-2.6.1-py2.7.egg') sys.path.append(CFG_DIR) import CFG_pb2 @@ -506,4 +507,4 @@ if "__main__" == __name__: default=None, help="The output control flow graph recovered from this file") - main(parser.parse_args(args=idc.ARGV[1:])) \ No newline at end of file + main(parser.parse_args(args=idc.ARGV[1:])) diff --git a/scripts/ida_get_cfg.sh b/scripts/ida_get_cfg.sh index 8f35ab16..83b32284 100755 --- a/scripts/ida_get_cfg.sh +++ b/scripts/ida_get_cfg.sh @@ -2,8 +2,15 @@ # Directory in which this script resides (i.e. McSema scripts dir). SCRIPTS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) -IDA=`locate idal64` -BIN=`mktemp --tmpdir=/tmp mcsema2_XXXXXXXXXX` + +if [[ "$OSTYPE" == "linux-gnu" ]]; then + IDA=`locate idal64` + BIN=`mktemp --tmpdir=/tmp mcsema2_XXXXXXXXXX` +elif [[ "$OSTYPE" == "darwin"* ]]; then + IDA="/Applications/IDA Pro 6.8/IDA binaries/idal64" + BIN=`mktemp -t mcsema2_XXXXXXXXXX` +fi + cp $1 $BIN -$IDA -B -S"${SCRIPTS_DIR}/ida_get_cfg.py --output=${BIN}.cfg" $BIN +"$IDA" -B -S"${SCRIPTS_DIR}/ida_get_cfg.py --output=${BIN}.cfg" $BIN echo "Saved CFG to ${BIN}.cfg"