Commit 31e01908 authored by Richard Bonichon's avatar Richard Bonichon
Browse files

Release BINSEC 0.3

parent 0f738968
* 0.3
** Features
- New architecture support : RISC-V 32 bits
- Support for DWARF-4 debug instruction format
- Support to import IDA control-flow graph
- Add documented plugin creation example : mnemonic count [mcount]
- New Makefile 'library' to ease plugin creation
** Fixes
- Fix (vectorized instructions) x86 decoder
** Misc
- Detach PINSEC to own repository (support to be deprecated in later version)
* 0.2 [2018-10-01 Mon]
- New symbolic execution engine
......
##########################################################################
# This file is part of BINSEC. #
# #
# Copyright (C) 2016-2018 #
# Copyright (C) 2016-2019 #
# CEA (Commissariat à l'énergie atomique et aux énergies #
# alternatives) #
# #
......
##########################################################################
# This file is part of BINSEC. #
# #
# Copyright (C) 2016-2018 #
# Copyright (C) 2016-2019 #
# CEA (Commissariat à l'énergie atomique et aux énergies #
# alternatives) #
# #
......
##########################################################################
# This file is part of BINSEC. #
# #
# Copyright (C) 2016-2018 #
# Copyright (C) 2016-2019 #
# CEA (Commissariat à l'énergie atomique et aux énergies #
# alternatives) #
# #
......@@ -19,29 +19,11 @@
# #
##########################################################################
all : binsec pinsec
all : binsec
# The order of includes is important
# Piqi.mk depends on values set from Config.mk
include Config.mk
include Piqi.mk
PINSEC_DIR = pinsec
PINSEC_BUILD_DIR = $(PINSEC_DIR)/build
CMAKE = cmake
PIN_ROOT_DIR ?= pin-2.14-71313-gcc.4.4.7-linux
pinsec: protoc
$(MKDIR_P) $(PINSEC_BUILD_DIR)
$(PP) "Using PIN from $(PIN_ROOT_DIR)"
($(CD) $(PINSEC_BUILD_DIR); \
$(CMAKE) -DPIN_ROOT_DIR=$(PIN_ROOT_DIR) ..)
$(PP) "Finish the build with cd $(PINSEC_BUILD_DIR); make"
.PHONY: pinsec-clean pinsec
pinsec-clean:
$(RRM) $(PINSEC_BUILD_DIR)
BINSEC_DIR = src
binsec:
......@@ -53,20 +35,12 @@ endif
binsec-clean:
$(MAKE) -C $(BINSEC_DIR) clean
clean:: binsec-clean pinsec-clean
clean:: binsec-clean
clean-configure:
$(RRM) autom4te.cache config.status configure
veryclean: clean clean-configure
.PHONY: tests
tests:
$(MAKE) -C tests
install:
$(MAKE) -C src install
include $(PINSEC_DIR)/Targets.mk
include $(BINSEC_DIR)/Targets.mk
##########################################################################
# This file is part of BINSEC. #
# #
# Copyright (C) 2016-2018 #
# Copyright (C) 2016-2019 #
# CEA (Commissariat à l'énergie atomique et aux énergies #
# alternatives) #
# #
......@@ -19,7 +19,7 @@
# #
##########################################################################
.SUFFIXES: .piqi .proto .pb.cc
.SUFFIXES: .piqi .proto
%_piqi.ml %_ext.ml: %.piqi
$(PP) 'PIQIML $@'
......@@ -30,29 +30,6 @@ $(PIQI_DIR)/%.piqi: $(PROTO_DIR)/%.proto
$(PP) 'PIQI $@'
$(PIQI) $(PIQI_FLAGS) -o $@ $<
CPP_PROTOBUF_DIR = $(PINSEC_DIR)/$(PINSEC_TYPES_DIR)/protobuf
.PHONY: pre-protoc
pre-protoc:
$(MKDIR_P) $(CPP_PROTOBUF_DIR)
%.pb.cc: src/proto/%.proto
$(PP) 'PROTOC $@'
$(PROTOC) $(PROTOC_FLAGS) $<
PROTOC_FILES = $(PROTO_SRC_FILES:%=$(CPP_PROTOBUF_DIR)/%.pb.cc)
$(PROTOC_FILES) : pre-protoc
PROTO_LSRC_FILES = $(PROTO_FILES:%=$(BINSEC_DIR)/%)
protoc: pre-protoc $(PROTO_LSRC_FILES)
$(PROTOC) $(PROTOC_FLAGS) $(PROTO_LSRC_FILES)
clean::
$(RRM) $(CPP_PROTOBUF_DIR)
$(PIQI_ML_FILES): $(PIQI_FILES)
piqi-ml : $(PIQI_ML_FILES)
......
......@@ -7,23 +7,11 @@ The following usual steps should do the trick:
```
% autoconf
% ./configure
% make binsec
% make
% make install
```
## PINSEC
```
% ./configure
% make pinsec
```
Then, go to the directory pinsec/build, and configure your build.
The build needs `CMake`.
# Help
```
......
0.2
\ No newline at end of file
0.3
\ No newline at end of file
opam-version: "1.2"
opam-version: "2.0"
name: "binsec"
version: "0.2"
maintainer: "richard.bonichon@cea.fr"
synopsis: "Semantic analysis of binary executables"
version: "0.3"
description: "
BINSEC aims at developing an open-source platform filling the gap between formal
methods over executable code and binary-level security analyses currently used
in the security industry.
The project targets the following applicative domains:
vulnerability analyses
malware comprehension
code protection
binary-level verification
BINSEC is developed at CEA List in scientfic collaboration with Verimag and LORIA.
An overview of some BINSEC features can be found in our SSPREW'17 tutorial."
maintainer: "BINSEC <binsec@saxifrage.saclay.cea.fr>"
authors: [
"Adel Djoudi"
"Benjamin Farinier"
......@@ -20,7 +36,7 @@ authors: [
homepage: "https://binsec.github.io"
license: "GNU Lesser General Public License version 2.1"
doc: ["http://binsec.github.io/apiref/index.html"]
bug-reports: "mailto:binsec _at_ saxifrage.saclay.cea.fr"
bug-reports: "https://github.com/binsec/binsec/issues"
tags: [
"binary code analysis"
"symbolic execution"
......@@ -36,34 +52,37 @@ tags: [
]
build: [
["sh" "-eux" "./run_autoconf_if_needed.sh"] # when used in pinned mode,
# the configure *cannot* yet be
# generated
["sh" "-eux" "./run_configure.sh" "--prefix" prefix]
["autoconf"] {pinned}
["./configure" "--prefix" prefix]
[make "-C" "src" "depend"]
[make "-C" "src" "-j%{jobs}%"]
[make "-C" "src" "-j%{jobs}%"]
]
install: [
[make "-C" "src" "install"]
]
remove: [
["sh" "-eux" "./run_autoconf_if_needed.sh"] # when used in pinned mode,
# the configure *cannot* yet be
# generated
["sh" "-eux" "./run_configure.sh" "--prefix" prefix ]
[make "-C" "src" "uninstall"]
]
depends: [
"ocaml" { >= "4.04.2" & <= "4.07.1" }
"ocamlfind" {build}
"menhir"
"ocamlgraph" { >= "1.8.5" & < "1.9~" }
"ocamlfind"
"piqi"
"piqilib"
"zarith"
"zmq"
"menhir"
"llvm"
]
available: [ ocaml-version >= "4.04.2" & ocaml_version < "4.06.0"]
depexts: [
[ "z3" "protobuf-compiler" ] { os-family = "debian" }
[ "z3" "protobuf-compiler" ] { os-family = "fedora" }
[ "z3" "protobuf" ] { os-family = "archlinux" }
[ "z3" "protobuf" ] { os-family = "openbsd" }
]
messages: [
"BINSEC uses external automatic solvers, like boolector, z3, cvc4, or yices
for some functionalities. Only Z3 is listed in depexts.
install the others through your package manager."
]
......@@ -598,9 +598,7 @@ CVC4
Z3
DOT
HEADACHE
CMAKE
OCAMLDOC
PROTOC
PIQI2CAML
PIQI
MENHIR
......@@ -1744,6 +1742,17 @@ fi
has_or_die $MAKE "Could not find GNU make"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking GNU make version" >&5
$as_echo_n "checking GNU make version... " >&6; }
GNU_MAKE_LEAST_VERSION=3.82
GNU_MAKE_VERSION=`$MAKE --version | head -n 1 | cut -d' ' -f 3`
case $GNU_MAKE_VERSION in
3.82*) $as_echo "Good! ($GNU_MAKE_VERSION)";;
4.**) $as_echo "Good! ($GNU_MAKE_VERSION)";;
# 4.2.1.*) AS_ECHO("Good! ($GNU_MAKE_VERSION)");;
*) as_fn_error $? "\"Please use a GNU Make version >= $GNU_MAKE_LEAST_VERSION (found $GNU_MAKE_VERSION).\"" "$LINENO" 5;;
esac
# Extract the first word of "ocamlfind", so it can be a program name with args.
set dummy ocamlfind; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
......@@ -1874,12 +1883,15 @@ fi
$as_echo_n "checking version of OCaml... " >&6; }
OCAMLCVERSION=`$OCAMLC -version`
LEAST_VERSION="4.04.2"
MOST_VERSION="4.05.0"
MOST_VERSION="4.07.1"
case $OCAMLCVERSION in
4.04*) $as_echo "Good! ($OCAMLCVERSION)";;
4.05*) $as_echo "Good! ($OCAMLCVERSION)";;
# no support for 4.06.* && 4.07 due to piqilib dependency on optcomp which depends on ocaml < 4.06.0
*) as_fn_error $? "\"Please use an ocaml version >= $LEAST_VERSION and <= $MOST_VERSION (found $OCAMLCVERSION).\"" "$LINENO" 5;;
4.06.0) $as_echo "Good! ($OCAMLCVERSION)";; # tested & included 2019-07-25
4.06.1) $as_echo "Good! ($OCAMLCVERSION)";; # tested & included 2019-07-25
4.07.0) $as_echo "Good! ($OCAMLCVERSION)";; # tested & included 2019-07-25
4.07.1) $as_echo "Good! ($OCAMLCVERSION)";; # tested & included 2019-07-25
*) as_fn_error $? "\"Please use an OCaml version >= $LEAST_VERSION and <= $MOST_VERSION (found $OCAMLCVERSION).\"" "$LINENO" 5;;
esac
......@@ -2284,46 +2296,6 @@ fi
has_or_die $PIQI2CAML "Could not find piqic-ocaml"
# Extract the first word of "protoc", so it can be a program name with args.
set dummy protoc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_PROTOC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$PROTOC"; then
ac_cv_prog_PROTOC="$PROTOC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_PROTOC="protoc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
test -z "$ac_cv_prog_PROTOC" && ac_cv_prog_PROTOC="no"
fi
fi
PROTOC=$ac_cv_prog_PROTOC
if test -n "$PROTOC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PROTOC" >&5
$as_echo "$PROTOC" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
has_or_die $PROTOC "Could not find protoc"
# Optional libraries #
......@@ -2374,49 +2346,6 @@ else
fi
# Extract the first word of "cmake", so it can be a program name with args.
set dummy cmake; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CMAKE+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$CMAKE"; then
ac_cv_prog_CMAKE="$CMAKE" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CMAKE="cmake"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
test -z "$ac_cv_prog_CMAKE" && ac_cv_prog_CMAKE="no"
fi
fi
CMAKE=$ac_cv_prog_CMAKE
if test -n "$CMAKE"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CMAKE" >&5
$as_echo "$CMAKE" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test x"$CMAKE" = xno; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"You will not be able to compile PINSEC\"" >&5
$as_echo "$as_me: WARNING: \"You will not be able to compile PINSEC\"" >&2;}
fi
## headache
# Extract the first word of "headache", so it can be a program name with args.
set dummy headache; ac_word=$2
......@@ -2684,6 +2613,10 @@ PIQI_DIR="piqi"
ac_config_commands="$ac_config_commands piqi_directory"
ac_config_commands="$ac_config_commands version"
# See https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Particular-Programs.html
for ac_prog in gawk mawk nawk awk
do
......@@ -2911,7 +2844,6 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
ac_config_files="$ac_config_files Config.mk"
cat >confcache <<\_ACEOF
......@@ -3623,6 +3555,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
#
depend_file="src/.depend"
dir="src/$PIQI_DIR"
src_dir="src"
_ACEOF
......@@ -3634,6 +3567,7 @@ do
case $ac_config_target in
"depend") CONFIG_COMMANDS="$CONFIG_COMMANDS depend" ;;
"piqi_directory") CONFIG_COMMANDS="$CONFIG_COMMANDS piqi_directory" ;;
"version") CONFIG_COMMANDS="$CONFIG_COMMANDS version" ;;
"Config.mk") CONFIG_FILES="$CONFIG_FILES Config.mk" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
......@@ -4066,6 +4000,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
case $ac_file$ac_mode in
"depend":C) touch ${depend_file} ;;
"piqi_directory":C) mkdir -p $dir ;;
"version":C) cp VERSION $src_dir ;;
"Config.mk":F) chmod a-w Config.mk ;;
esac
......
##########################################################################
# This file is part of BINSEC. #
# #
# Copyright (C) 2016-2018 #
# Copyright (C) 2016-2019 #
# CEA (Commissariat à l'énergie atomique et aux énergies #
# alternatives) #
# #
......@@ -38,6 +38,16 @@ has_lib_or_die ()
AC_CHECK_PROG(MAKE, make, make, no)
has_or_die $MAKE "Could not find GNU make"
AC_MSG_CHECKING([GNU make version])
GNU_MAKE_LEAST_VERSION=3.82
GNU_MAKE_VERSION=`$MAKE --version | head -n 1 | cut -d' ' -f 3`
case $GNU_MAKE_VERSION in
3.82*) AS_ECHO("Good! ($GNU_MAKE_VERSION)");;
4.**) AS_ECHO("Good! ($GNU_MAKE_VERSION)");;
# 4.2.1.*) AS_ECHO("Good! ($GNU_MAKE_VERSION)");;
*) AC_MSG_ERROR("Please use a GNU Make version >= $GNU_MAKE_LEAST_VERSION (found $GNU_MAKE_VERSION).");;
esac
AC_CHECK_PROG(OCAMLFIND, ocamlfind, ocamlfind, no)
has_or_die $OCAMLFIND "Could not find ocamlfind"
......@@ -56,12 +66,15 @@ fi
AC_MSG_CHECKING([version of OCaml])
OCAMLCVERSION=`$OCAMLC -version`
LEAST_VERSION="4.04.2"
MOST_VERSION="4.05.0"
MOST_VERSION="4.07.1"
case $OCAMLCVERSION in
4.04*) AS_ECHO("Good! ($OCAMLCVERSION)");;
4.05*) AS_ECHO("Good! ($OCAMLCVERSION)");;
# no support for 4.06.* && 4.07 due to piqilib dependency on optcomp which depends on ocaml < 4.06.0
*) AC_MSG_ERROR("Please use an ocaml version >= $LEAST_VERSION and <= $MOST_VERSION (found $OCAMLCVERSION).");;
4.06.0) AS_ECHO("Good! ($OCAMLCVERSION)");; # tested & included 2019-07-25
4.06.1) AS_ECHO("Good! ($OCAMLCVERSION)");; # tested & included 2019-07-25
4.07.0) AS_ECHO("Good! ($OCAMLCVERSION)");; # tested & included 2019-07-25
4.07.1) AS_ECHO("Good! ($OCAMLCVERSION)");; # tested & included 2019-07-25
*) AC_MSG_ERROR("Please use an OCaml version >= $LEAST_VERSION and <= $MOST_VERSION (found $OCAMLCVERSION).");;
esac
......@@ -166,9 +179,6 @@ has_or_die $PIQI "Could not find piqi"
AC_CHECK_PROG(PIQI2CAML, piqic-ocaml , piqic-ocaml, no)
has_or_die $PIQI2CAML "Could not find piqic-ocaml"
AC_CHECK_PROG(PROTOC, protoc, protoc, no)
has_or_die $PROTOC "Could not find protoc"
# Optional libraries #
......@@ -181,11 +191,6 @@ else
fi
AC_CHECK_PROG(CMAKE, cmake, cmake, no)
if test x"$CMAKE" = xno; then
AC_MSG_WARN("You will not be able to compile PINSEC")
fi
## headache
AC_CHECK_PROG(HEADACHE, headache, headache, no)
if test x"$HEADACHE" = xno; then
......@@ -223,6 +228,9 @@ AC_CONFIG_COMMANDS([depend], [touch ${depend_file}], [depend_file="src/.depend"]
PIQI_DIR="piqi"
AC_CONFIG_COMMANDS([piqi_directory], [mkdir -p $dir],[dir="src/$PIQI_DIR"])
AC_CONFIG_COMMANDS([version],[cp VERSION $src_dir],[src_dir="src"])
# See https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Particular-Programs.html
AC_PROG_AWK
AC_PROG_MKDIR_P
......@@ -242,7 +250,6 @@ AC_SUBST(OCAMLBEST)
AC_SUBST(HEADACHE)
AC_SUBST(PIQI)
AC_SUBST(PIQI2CAML)
AC_SUBST(PROTOC)
AC_SUBST(PIQI_DIR)
AC_SUBST(AWK)
AC_SUBST(MKDIR_P)
......
Semantic analysis of binary executables.
#!/bin/sh -eux
if [ ! -f "configure" ]; then
autoconf
fi
#!/bin/sh -eux
exec ./configure "$@"
project(pinsec)
cmake_minimum_required(VERSION 3.0)
if(CMAKE_VERSION VERSION_GREATER 3.1)
cmake_policy(SET CMP0054 NEW)
endif()
#=============== GLOBALS VARS ================
# ---- Looking for the Pintool directory
find_path(PIN_ROOT_DIR
NAMES source/include/pin/pin.H
PATHS $ENV{PIN_ROOT_DIR}
DOC "Pin's base directory"
)
if(NOT PIN_ROOT_DIR)
message(FATAL_ERROR "Pin not found!\n Please set the environment variable PIN_ROOT_DIR to the base directory of the pin library.\n")
endif(NOT PIN_ROOT_DIR)
message(STATUS "PIN_ROOT_DIR: ${PIN_ROOT_DIR}")
if(WIN32)
find_path(JANSSON_DIR PATHS $ENV{JANSSON_DIR} DOC "Jansson's base directory")
if(NOT JANSSON_DIR)
message(FATAL_ERROR "Jansson directory not found!\n Please set the environment variable JANSSON_DIR to the base directory of the jansson library.\n")
endif(NOT JANSSON_DIR)
message(STATUS "JANSSON_DIR: ${JANSSON_DIR}")
find_path(PROTOBUF_DIR PATHS $ENV{PROTOBUF_DIR} DOC "Protobuf's base directory")
if(NOT PROTOBUF_DIR)
message(FATAL_ERROR "Protobuf not found!\n Please set the environment variable PROTOBUF_DIR to the base directory of the protobuf library.\n")
endif(NOT PROTOBUF_DIR)
message(STATUS "PROTOBUF_DIR: ${PIN_ROOT_DIR}")
endif(WIN32)
#----------------------
#---- Check compiler version
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fabi-version=2")
endif()
endif()
#---------------------------
#Set the target architecture
set(PIN_CPU_ARCH "ia32") #ia32e (for 64bits)
set(PIN_CPU_ARCH_LONG "ia32") #intel64 (for 64 bits)
#===============================================
#=============== DEFINITIONS =================
#Set definitions for the Pintool
set(PIN_DEFINITIONS "")
list(APPEND PIN_DEFINITIONS BIGARRAY_MULTIPLIER=1 USING_XED)
if("${PIN_CPU_ARCH}" STREQUAL "ia32e")
list(APPEND PIN_DEFINITIONS TARGET_IA32E HOST_IA32E)
elseif("${PIN_CPU_ARCH}" STREQUAL "ia32")
list(APPEND PIN_DEFINITIONS TARGET_IA32 HOST_IA32)
endif("${PIN_CPU_ARCH}" STREQUAL "ia32e")
if(UNIX)
list(APPEND PIN_DEFINITIONS TARGET_LINUX)
elseif(WIN32)
list(APPEND PIN_DEFINITIONS TARGET_WINDOWS _WIN32 _SECURE_SCL=0 _CRT_SECURE_NO_DEPRECATE _CPPUNWIND)
endif()
#=============================================
#============== INCLUDES ===============
find_package(Boost REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
set(PIN_INCLUDE_DIRS
${PIN_ROOT_DIR}/extras/xed-${PIN_CPU_ARCH_LONG}/include
${PIN_ROOT_DIR}/source/include/pin
${PIN_ROOT_DIR}/source/include/pin/gen
${PIN_ROOT_DIR}/extras/components/include
${LOCAL_INCLUDE_DIR}
)
include_directories(${PIN_INCLUDE_DIRS})
if(UNIX)
#ZMQ specific
include_directories("${CMAKE_SOURCE_DIR}/lib/zmq/include")
elseif(WIN32)
set(CMAKE_CONFIGURATION_TYPES Release)
include_directories("${JANSSON_DIR}/build/include")
include_directories("${PROTOBUF_DIR}/src")
else()
endif()
#=========================================
#Generate protobuf files
if(NOT EXISTS "${CMAKE_SOURCE_DIR}/src/types/protobuf/trace.pb.h") #Assume that if one does not exists none of them are
message(WARNING "Protobuf files not generated! Please use make cpp in proto/ directory.")
#execute_process(COMMAND protoc --proto_path=../../../proto --cpp_out=../src/types/protobuf ../../../proto/common.proto ../../../proto/dba.proto ../../../proto/config.proto ../../../proto/instruction.proto ../../../proto/syscall.proto ../../../proto/libcall.proto ../../../proto/message.proto ../../../proto/trace.proto)
endif()