Skip to content

Instantly share code, notes, and snippets.

@psifertex
Last active May 8, 2024 03:21
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 [ -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 -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
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"
@msmallcombe
Copy link

@psifertex the script works great for macOS!

@saagarjha
Copy link

Consider

--- binexport_binja_original.sh	2023-05-08 04:04:31
+++ binexport_binja.sh	2023-05-08 04:06:13
@@ -8,7 +8,7 @@
   DOWNLOADS=~/Downloads
 else
   mdir ~/downloads
-  DOWNLOAD=~/downloads
+  DOWNLOADS=~/downloads
 fi
 BE_PATH=$DOWNLOADS/binexport
 if [ -d ~/.binaryninja ] && [ -f ~/.binaryninja/lastrun ]
@@ -103,14 +103,14 @@
 then
   echo "\u001b[36m[+] Linking BinExport plugin to Binary Ninja plugin folder"
   echo "\u001b[0m"
-  ln -sf ~/Downloads/binexport/build/binaryninja/binexport12_binaryninja.so ~/Library/Application\ Support/Binary\ Ninja/plugins
+  ln -sf "$DOWNLOADS/binexport/build/binaryninja/binexport12_binaryninja.so" ~/Library/Application\ Support/Binary\ Ninja/plugins
 fi

-if [ ! -L ~/Downloads/binexport/build/binaryninja/binexport12_binaryninja.dylib ]
+if [ ! -L "$DOWNLOADS/binexport/build/binaryninja/binexport12_binaryninja.dylib" ]
 then
   echo "\u001b[36m[+] Linking BinExport plugin to Binary Ninja plugin folder"
   echo "\u001b[0m"
-  ln -sf ~/Downloads/binexport/build/binaryninja/binexport12_binaryninja.dylib ~/Library/Application\ Support/Binary\ Ninja/plugins
+  ln -sf "$DOWNLOADS/binexport/build/binaryninja/binexport12_binaryninja.dylib" ~/Library/Application\ Support/Binary\ Ninja/plugins
 fi

 echo "\u001b[32;1m[+] Done!"

@psifertex
Copy link
Author

Thanks I also was symlinking the so into the wrong user folder but I fixed that too. I'll try to give it a go on linux soon.

@saagarjha
Copy link

The commits you relied on have changed in the binexport repo. To save you some sed usage I'll see if they'll take a change to just specify a tag directly in their CMAKE files.

@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

@debxrshi
Copy link

debxrshi commented May 5, 2024

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!

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