Skip to content

Instantly share code, notes, and snippets.

@psifertex
Last active March 3, 2025 12:10
Show Gist options
  • Save psifertex/31d9bc3167eca91e466ebaae4382521c to your computer and use it in GitHub Desktop.
Save psifertex/31d9bc3167eca91e466ebaae4382521c to your computer and use it in GitHub Desktop.
BinExport build script for Binary Ninja (macOS + Linux Only)
#!/usr/bin/env zsh
# Note:
# CMake, Clang, clang-format, Ninja, git and sed are required to build
#
# Note that currently there is a bug (https://github.com/google/binexport/issues/117)
# that requires applying this patch, remove when resolved
#
if [[ "$OSTYPE" == "darwin"* ]]; then
SED_CMD="sed -i '' -E -e"
else
SED_CMD="sed -i -E -e"
fi
if [ -d ~/Downloads ]
then
DOWNLOADS=~/Downloads
else
mdir ~/downloads
DOWNLOAD=~/downloads
fi
BE_PATH=$DOWNLOADS/binexport
if [ -d ~/.binaryninja ] && [ -f ~/.binaryninja/lastrun ]
then
BN_USER=~/.binaryninja
BN_PATH=`cat ~/.binaryninja/lastrun`
BINARY_HASH=$(sed 's/^.*\///' < $BN_PATH/api_REVISION.txt 2>/dev/null)
CORES=$(nproc --all)
PLUGIN_DEST=~/.binaryninja/plugins/binexport12_binaryninja.so
PLUGIN_SRC=~/Downloads/binexport/build/binaryninja/binexport12_binaryninja.so
elif [ -d ~/Library/Application\ Support/Binary\ Ninja ] && [ -f ~/Library/Application\ Support/Binary\ Ninja/lastrun ]
then
BN_USER=~/Library/Application\ Support/Binary\ Ninja
BN_PATH=`cat ~/Library/Application\ Support/Binary\ Ninja/lastrun`
BINARY_HASH=$(sed 's/^.*\///' < $BN_PATH/../Resources/api_REVISION.txt 2>/dev/null)
CORES=$(sysctl -n hw.logicalcpu)
PLUGIN_DEST=~/Library/Application\ Support/Binary\ Ninja/plugins/binexport12_binaryninja.dylib
PLUGIN_SRC=~/Downloads/binexport/build/binaryninja/binexport12_binaryninja.dylib
else
echo "Failed to find appropriate Binary Ninja user directory."
exit 1
fi
BN_API_PATH=$DOWNLOADS/binaryninja-api
echo "Configuration:"
echo " DOWNLOADS: $DOWNLOADS"
echo " BE_PATH: $BE_PATH"
echo " BN_API_PATH: $BN_API_PATH"
echo " BN_PATH: $BN_PATH"
echo " BINARY_HASH: $BINARY_HASH"
if [ -z "$BINARY_HASH" ]
then
echo "Failed to find appropriate hash for Binary Ninja"
exit 1
fi
echo "\u001b[36m[+] Cloning BinExport & Binary Ninja API..."
echo "\u001b[0m"
if [ -d $BE_PATH ]
then
pushd $BE_PATH
if git fetch --all
then
git reset --hard origin/main # Because previous runs of this script will dirty the repo
echo "BinExport exists, repo updated"
else
echo Not a repo, remove $BE_PATH to continue
exit
fi
popd
else
git clone https://github.com/google/binexport.git $BE_PATH
fi
if [ ! -d $BN_API_PATH ]
then
git clone --recursive --branch dev https://github.com/Vector35/binaryninja-api.git $BN_API_PATH
fi
pushd $BN_API_PATH
if git fetch --all
then
if git checkout "$BINARY_HASH"
then
git pull
echo "Binary Ninja API exists, repo updated"
else
echo Not a repo or could not match binary hash
exit
fi
fi
popd
echo "\u001b[36m[+] Updating the git hash..."
echo "\u001b[0m"
$SED_CMD "s/(1bd42a73e612f50c68d802acda674c21a30e980c|6e2b374dece03f6fb48a1615fa2bfee809ec2157)/$BINARY_HASH/g" $BE_PATH/cmake/BinExportDeps.cmake
$SED_CMD "s/2023-05-18/2023-09-24/g" $BE_PATH/cmake/BinExportDeps.cmake
echo "\u001b[36m[+] Running regenerate-api-stubs..."
echo "\u001b[0m"
pushd $BE_PATH/binaryninja/stubs/
./regenerate-api-stubs.sh $BN_API_PATH
popd
pushd $BE_PATH
echo "\u001b[36m[+] Building BinExport..."
echo "\u001b[0m"
rm -rf build && mkdir build && cd build
cmake .. -G Ninja -DCMAKE_CXX_FLAGS="-D_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION" -DBINEXPORT_BINARYNINJA_CHANNEL=DEV -DCMAKE_BUILD_TYPE=Release "-DCMAKE_INSTALL_PREFIX=$PWD" -DBINEXPORT_ENABLE_IDAPRO=OFF -DBINEXPORT_ENABLE_BINARYNINJA=ON
cmake --build . --config Release -- "-j$CORES"
popd
if [ -f $PLUGIN_DEST ]
then
echo "\u001b[36m[+] Not linking the plugin, file already exists\u001b[0m"
else
echo "\u001b[36m[+] Linking BinExport plugin to Binary Ninja plugin folder\u001b[0m"
ln -sf $PLUGIN_SRC $PLUGIN_DEST
fi
echo "\u001b[32;1m[+] Done!"
echo "\u001b[0m"
@psifertex
Copy link
Author

Thanks. I noticed it wasn't working this week but hadn't had any time to investigate.

@psifertex
Copy link
Author

Updated for the latest hash in the meantime and also made a few other fixes in particular around the sym linking.

@sourcelocation
Copy link

Thank you so much! Finally managed to get the plugin compiled 👍

Btw, I also had to install clang-format after I was getting weird symbol errors

@psifertex
Copy link
Author

Yup, see the note at the top of the script, it's "documented" there.

@sourcelocation
Copy link

Oops didn’t see that 😅

@psifertex
Copy link
Author

Just updated to include the latest binexport release for those running the latest dev. Hopefully in the future I can make it more robust but that requires some small tweaks to binexport's cmake configs that I've asked Christian to take a look at when he gets a chance.

@saagarjha
Copy link

FYI: your sed line is missing a parenthesis. I think we should also probably get Christian to pull the fmtlib submodule, too?

@psifertex
Copy link
Author

psifertex commented Nov 30, 2023

Actually, I think that line had an extra one. The previous line is matching multiple but that should just be matching the date. Good point though on it being a bug (though a cosmetic one since it just will fail to match).

What's fmtlib needed for?

@saagarjha
Copy link

@1ikeadragon
Copy link

Any script for WIndows?

@psifertex
Copy link
Author

Unfortunately, not right now. I'll try to take a look at it when I have some time but it will be at least a week.

@xusheng6
Copy link

xusheng6 commented May 7, 2024

The current script will fail at the last ln command. The fix is to remove the quotes from https://gist.github.com/psifertex/31d9bc3167eca91e466ebaae4382521c#file-binexport_binja-zsh-L32-L33 (and above as well)

@psifertex
Copy link
Author

Done, mind checking to see if it works for you now?

@xusheng6
Copy link

xusheng6 commented May 8, 2024

Done, mind checking to see if it works for you now?

It now works perfectly for me!

@raymontag
Copy link

On Linux, due to implementation differenced in sed, L92f should be:

sed -i -E -e "s/(1bd42a73e612f50c68d802acda674c21a30e980c|6e2b374dece03f6fb48a1615fa2bfee809ec2157)/$BINARY_HASH/g" $BE_PATH/cmake/BinExportDeps.cmake
sed -i  -E -e "s/2023-05-18/2023-09-24/g" $BE_PATH/cmake/BinExportDeps.cmake

(that is, remove the single quotes after -i)

@psifertex
Copy link
Author

Unfortunately the macOS sed requires that or it won't do the in-place replacement so I'll need to build some OS detection in as well. Just made that change but don't have time to test it right now so caveat emptor.

@blacktop
Copy link

blacktop commented Jan 25, 2025

ERROR
FAILED: CMakeFiles/binaryninjacore.dir/binaryninja/stubs/binaryninjacore.cc.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -Dbinaryninjacore_EXPORTS -I~/Downloads/binexport/build/_deps/binaryninjaapi-src -D_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION -O3 -DNDEBUG -std=c++17 -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.2.sdk -fPIC -Wno-nullability-completeness -Wno-invalid-noreturn -Wno-deprecated -gfull -MD -MT CMakeFiles/binaryninjacore.dir/binaryninja/stubs/binaryninjacore.cc.o -MF CMakeFiles/binaryninjacore.dir/binaryninja/stubs/binaryninjacore.cc.o.d -o CMakeFiles/binaryninjacore.dir/binaryninja/stubs/binaryninjacore.cc.o -c ~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:243:26: error: conflicting types for 'BNDataBufferToEscapedString'
  243 | BINARYNINJACOREAPI char* BNDataBufferToEscapedString(BNDataBuffer* buf,
      |                          ^
~/Downloads/binexport/build/_deps/binaryninjaapi-src/binaryninjacore.h:3148:27: note: previous declaration is here
 3148 |         BINARYNINJACOREAPI char* BNDataBufferToEscapedString(BNDataBuffer* buf, bool nullTerminates);
      |                                  ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:308:5: error: unknown type name 'BNProgressFunction'
  308 |     BNProgressFunction progress, BNSaveSettings* settings) {
      |     ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:317:5: error: unknown type name 'BNProgressFunction'
  317 |     BNProgressFunction progress) {
      |     ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:329:37: error: unknown type name 'BNProgressFunction'
  329 |     BNBinaryView* data, void* ctxt, BNProgressFunction progress,
      |                                     ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:336:43: error: unknown type name 'BNProgressFunction'
  336 |                                           BNProgressFunction progress) {}
      |                                           ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:339:41: error: unknown type name 'BNProgressFunction'
  339 |     BNKeyValueStore* cache, void* ctxt, BNProgressFunction progress,
      |                                         ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:408:20: error: unknown type name 'BNProject'
  408 | BINARYNINJACOREAPI BNProject* BNNewProjectReference(BNProject* project) {
      |                    ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:408:53: error: unknown type name 'BNProject'
  408 | BINARYNINJACOREAPI BNProject* BNNewProjectReference(BNProject* project) {
      |                                                     ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:411:39: error: unknown type name 'BNProject'
  411 | BINARYNINJACOREAPI void BNFreeProject(BNProject* project) {}
      |                                       ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:412:43: error: unknown type name 'BNProject'
  412 | BINARYNINJACOREAPI void BNFreeProjectList(BNProject** projects, size_t count) {}
      |                                           ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:413:20: error: unknown type name 'BNProject'
  413 | BINARYNINJACOREAPI BNProject** BNGetOpenProjects(size_t* count) { return {}; }
      |                    ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:414:20: error: unknown type name 'BNProject'
  414 | BINARYNINJACOREAPI BNProject* BNCreateProject(const char* path,
      |                    ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:418:20: error: unknown type name 'BNProject'
  418 | BINARYNINJACOREAPI BNProject* BNOpenProject(const char* path) { return {}; }
      |                    ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:419:39: error: unknown type name 'BNProject'
  419 | BINARYNINJACOREAPI bool BNProjectOpen(BNProject* project) { return {}; }
      |                                       ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:420:40: error: unknown type name 'BNProject'
  420 | BINARYNINJACOREAPI bool BNProjectClose(BNProject* project) { return {}; }
      |                                        ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:421:41: error: unknown type name 'BNProject'
  421 | BINARYNINJACOREAPI char* BNProjectGetId(BNProject* project) { return {}; }
      |                                         ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:422:41: error: unknown type name 'BNProject'
  422 | BINARYNINJACOREAPI bool BNProjectIsOpen(BNProject* project) { return {}; }
      |                                         ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:423:43: error: unknown type name 'BNProject'
  423 | BINARYNINJACOREAPI char* BNProjectGetPath(BNProject* project) { return {}; }
      |                                           ^
~/Downloads/binexport/binaryninja/stubs/binaryninjacore.cc:424:43: error: unknown type name 'BNProject'
  424 | BINARYNINJACOREAPI char* BNProjectGetName(BNProject* project) { return {}; }
      |                                           ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
[436/671] Building CXX object _deps/protobuf-build/CMakeFiles/libprotoc.dir/src/google/protobuf/compiler/rust/message.cc.o
ninja: build stopped: subcommand failed.

@saagarjha
Copy link

saagarjha commented Jan 27, 2025

Personally I would s/2023-05-18/dev/ because nobody is running a Binary Ninja from a year and a half ago ¯\_(ツ)_/¯

@psifertex
Copy link
Author

Yeah, that's a good point. I'm in the middle of re-writing the script to clean it up a ton anyway. If I have time I will try to get it working on windows too. I'll make sure to include that.

@d0now
Copy link

d0now commented Mar 3, 2025

Somehow binexport new commit(google/binexport@b77ade3) raises boost error on compile time...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment