emesare / binja-msvc

Parses and symbolizes MSVC RTTI information in Binary Ninja.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Installation Instructions?

rickhg12hs opened this issue · comments

If I want to try your plugin with Binary Ninja, how do I do it?

Assuming you have Binary Ninja installed, git, cmake (ver. 3.9 or greater) and a recent C++ compiler.

git clone https://github.com/emesare/binja-msvc
cd binja-msvc
git submodule update --init --recursive
cmake --preset "default-debug" # or "default-release"
cd out/build
cmake --build "default-debug"

Then grab the plugin .so/.dylib/.dll and put it in your plugin directory (see: binary ninja docs for where that directory is)

@rickhg12hs does the above answer your question?

I'll see if I can figure it out, but so far:

First try
$ cmake --preset "default-debug"
Preset CMake variables:

  CMAKE_BUILD_TYPE="Debug"
  CMAKE_INSTALL_PREFIX="/home/rick/src/BinaryNinja/plugins/binja-msvc/out/install/default-debug"

-- The CXX compiler identification is GNU 12.2.1
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/lib64/ccache/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Error at CMakeLists.txt:8 (add_subdirectory):
  The source directory

    /home/rick/src/BinaryNinja/plugins/binja-msvc/binaryninja-api

  does not contain a CMakeLists.txt file.


CMake Error at CMakeLists.txt:26 (target_link_options):
  Cannot specify link options for target "binaryninjaapi" which is not built
  by this project.


CMake Error at CMakeLists.txt:31 (set_target_properties):
  set_target_properties Can not find target to add properties to: fmt


CMake Error at CMakeLists.txt:45 (bn_install_plugin):
  Unknown CMake command "bn_install_plugin".


-- Configuring incomplete, errors occurred!
Second try

After a bit of poking around, I tried:

$ git submodule init
Submodule 'binaryninja-api' (https://github.com/Vector35/binaryninja-api) registered for path 'binaryninja-api'

$ git submodule update
Cloning into '/home/rick/src/BinaryNinja/plugins/binja-msvc/binaryninja-api'...
Submodule path 'binaryninja-api': checked out '1716451033063812056349156332128984540962'

$ cmake --preset "default-debug"
Preset CMake variables:

  CMAKE_BUILD_TYPE="Debug"
  CMAKE_INSTALL_PREFIX="/home/rick/src/BinaryNinja/plugins/binja-msvc/out/install/default-debug"

-- The CXX compiler identification is GNU 12.2.1
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/lib64/ccache/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- The C compiler identification is GNU 12.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/lib64/ccache/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
CMake Error at /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
  Could NOT find Binary Ninja installation.  Please configure with
  -DBN_INSTALL_DIR=<path to Binary Ninja> or set the BN_INSTALL_DIR
  environment variable.  (missing: CORE_LIBRARY)
Call Stack (most recent call first):
  /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:600 (_FPHSA_FAILURE_MESSAGE)
  binaryninja-api/cmake/FindBinaryNinjaCore.cmake:36 (find_package_handle_standard_args)
  binaryninja-api/CMakeLists.txt:33 (find_package)


-- Configuring incomplete, errors occurred!
Third try
$ cmake --preset "default-debug" -DBN_INSTALL_DIR=/home/rick/src/BinaryNinja/binaryninja
Preset CMake variables:

  CMAKE_BUILD_TYPE="Debug"
  CMAKE_INSTALL_PREFIX="/home/rick/src/BinaryNinja/plugins/binja-msvc/out/install/default-debug"

-- Found BinaryNinjaCore: /home/rick/src/BinaryNinja/binaryninja/libbinaryninjacore.so.1  
-- Found Binary Ninja Core: /home/rick/src/BinaryNinja/binaryninja/libbinaryninjacore.so.1
-- Binary Ninja Link Dirs: /home/rick/src/BinaryNinja/binaryninja
-- Binary Ninja Install Dir: /home/rick/src/BinaryNinja/binaryninja
-- Binary Ninja User Plugins Dir: /home/rick/.binaryninja/plugins
CMake Error at binaryninja-api/CMakeLists.txt:38 (add_subdirectory):
  The source directory

    /home/rick/src/BinaryNinja/plugins/binja-msvc/binaryninja-api/vendor/fmt

  does not contain a CMakeLists.txt file.


-- Found Binary Ninja Core: /home/rick/src/BinaryNinja/binaryninja/libbinaryninjacore.so.1
-- Binary Ninja Link Dirs: /home/rick/src/BinaryNinja/binaryninja
-- Binary Ninja Install Dir: /home/rick/src/BinaryNinja/binaryninja
-- Binary Ninja User Plugins Dir: /home/rick/.binaryninja/plugins
CMake Warning at binaryninja-api/cmake/FindBinaryNinjaUI.cmake:33 (find_package):
  By not providing "FindQt6.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "Qt6", but
  CMake did not find one.

  Could not find a package configuration file provided by "Qt6" with any of
  the following names:

    Qt6Config.cmake
    qt6-config.cmake

  Add the installation prefix of "Qt6" to CMAKE_PREFIX_PATH or set "Qt6_DIR"
  to a directory containing one of the above files.  If "Qt6" provides a
  separate development package or SDK, be sure it has been installed.
Call Stack (most recent call first):
  binaryninja-api/CMakeLists.txt:54 (find_package)


-- Could NOT find Binary Ninja UI installation. Check that you are using a valid Binary Ninja, non-headless install, and qmake is in your PATH. (missing: Qt6_FOUND) 
CMake Warning at binaryninja-api/cmake/FindBinaryNinjaUI.cmake:42 (message):
  Could not find Qt6! Make sure qmake is in your PATH.
Call Stack (most recent call first):
  binaryninja-api/CMakeLists.txt:54 (find_package)


CMake Warning at binaryninja-api/CMakeLists.txt:69 (message):
  Binary Ninja UI not found but -DHEADLESS was not specified.  You will not
  be able to build UI plugins.


CMake Error at CMakeLists.txt:31 (set_target_properties):
  set_target_properties Can not find target to add properties to: fmt


-- /home/rick/src/BinaryNinja/plugins/binja-msvc/binaryninja-api
-- Found Binary Ninja Core: /home/rick/src/BinaryNinja/binaryninja/libbinaryninjacore.so.1
-- Binary Ninja Link Dirs: /home/rick/src/BinaryNinja/binaryninja
-- Binary Ninja Install Dir: /home/rick/src/BinaryNinja/binaryninja
-- Binary Ninja User Plugins Dir: /home/rick/.binaryninja/plugins
-- Configuring incomplete, errors occurred!
Try 3.5
$ cd out/build/
$ cmake --build "default-debug"
gmake: Makefile: No such file or directory
gmake: *** No rule to make target 'Makefile'.  Stop.

Oops forgot to init submodules!

git submodule update --init --recursive

fmt is a submodule in binaryninja-api that needs to be present to build (see Vector35/binaryninja-api@1716451).

OK, everything is built and I moved libbinja-msvc.so to ~/.binaryninja/plugins.

Looking in the Log, I see:

[Default] Plugin module '/home/rick/.binaryninja/plugins/libbinja-msvc.so' failed to load
[Default] dlerror() reports: /home/rick/.binaryninja/plugins/libbinja-msvc.so: undefined symbol: BNGetAnalysisTypeContainer
$ nm -CD --defined-only libbinaryninjacore.so.1 | grep BNGetAnalysisType
00000000010058b0 T BNGetAnalysisTypeById
0000000001040d80 T BNGetAnalysisTypeByName
0000000001009190 T BNGetAnalysisTypeByRef
0000000001041c70 T BNGetAnalysisTypeId
000000000102c9c0 T BNGetAnalysisTypeList
0000000001005b30 T BNGetAnalysisTypeNameById
000000000100ccc0 T BNGetAnalysisTypeNames

🤔

FYI:

$ nm -C ./out/build/default-debug/binaryninja-api/CMakeFiles/binaryninjaapi.dir/binaryview.cpp.o | grep BNGetAnalysisType
                 U BNGetAnalysisTypeById
                 U BNGetAnalysisTypeByName
                 U BNGetAnalysisTypeByRef
                 U BNGetAnalysisTypeContainer
                 U BNGetAnalysisTypeId
                 U BNGetAnalysisTypeList
                 U BNGetAnalysisTypeNameById
                 U BNGetAnalysisTypeNames

The current commit for binaryninja-api has the ABI version at 42, you are using an older version of Binary Ninja then what the plugin expects, you need to pull an older version of the binaryninja-api repository so that the ABI matches. To find a commit that matches you should look for the commit prior to the commit that increments the ABI version number, here.

OK, I'll try the dev update channel and see what happens.

Is there anyway this can be automated? I just recently purchased the student personal license and I'm not very familiar with the project structure. I already needed to tell cmake where BN was installed. Could the proper binaryninja-api be determined from that, and then the build/install/etc. just works?

Is there anyway this can be automated? I just recently purchased the student personal license and I'm not very familiar with the project structure. I already needed to tell cmake where BN was installed. Could the proper binaryninja-api be determined from that, and then the build/install/etc. just works?

There is only one proper binaryninja-api and that is the vendored one that the plugin is built against. For your case you are likely on the stable version of Binary Ninja, meaning you are on an older version of the ABI. This plugin is targeting the dev version of Binary Ninja. The hope would be to create a snapshot before bumping the ABI version (usually by pulling a newer version of binaryninja-api), this can be done in a few ways, the easiest being just using the "snapshot" commit that has the compatible ABI version and creating a GitHub release and tagging it as "abi-31" or whatever the ABI version is.

Currently the idea is to have CI in the future (see: #3) build native plugins automatically and be downloadable in the plugin manager. The following GitHub issues are relevant:

I switched to the dev update channel and everything seems to be working now. Thanks for your help

Well, since I'm on the dev update channel, an update occurred and the plugin stopped working. I thought some API probably changed, so I completely re-built/installed the plugin, but something still isn't right.

[Default] Plugin module '/home/rick/.binaryninja/plugins/libbinja-msvc.so' failed to load
[Default] dlerror() reports: /home/rick/.binaryninja/plugins/libbinja-msvc.so: undefined symbol: BNSettingsSetStringObject

How do I fix this?

Playing around with git submodule ..., I was able to update the the submodules to a random (random to me anyway) state so I could re-build/install and it works. 👍🏻

It would be nice if there was a straightforward way of doing this.

I'm also wondering why binaryninja-api is rebuilt for the plugin. Is that for testing purposes??

[Default] Plugin module '/home/rick/.binaryninja/plugins/libbinja-msvc.so' failed to load
[Default] dlerror() reports: /home/rick/.binaryninja/plugins/libbinja-msvc.so: undefined symbol: BNSettingsSetStringObject

How do I fix this?

This is the inverse of the problem before, instead of the plugin being on a newer ABI version relative to your Binary Ninja installation the plugin is on an older ABI version, the commit which bumped the version was Vector35/binaryninja-api@12170f9. To fix this you must update the versioned binaryninja-api to a commit greater or equal to the commit which bumped the version.

I'm also wondering why binaryninja-api is rebuilt for the plugin. Is that for testing purposes??

binaryninja-api is versioned alongside the plugin to tie the plugin to a specific commit, this is because a change in the ABI typically also means a change in the API. There is no perfect solution to this problem, when not versioned, you will end up with the same issues but instead of it happening when you load the plugin it could happen both when you go and load it and when you go to compile it (because the API changed).

I would defer to what I said above about there being a need for automatic releases to prevent users from needing to compile native plugins themselves, while the underlying fix would also be usable to make building easier for the user, its best done in CI where the build environment is known.

This is effectively solved with #24 and #9.

Just a quick note for @rickhg12hs or others following this process that you can find the appropriate commit of the API repo to checkout at by looking in your installation path of Binary Ninja. There is an api_REVISION.txt file that contains the exact commit hash.

So a quick way to fix this would be:

$ cd my-plugin
$ cd binaryninja-api
$ git checkout `cat /Applications/Binary Ninja.app/Contents/Resources/api_REVISION.xt`
$ git submodule update --init --recursive

(adjusting for whatever your platform is as appropriate)

Note that this solves both the "too new" and "too old" cases as it will match the correct commit either way.

After recent plugin changes, the installation/upgrade procedure is different.

CMake Error at CMakeLists.txt:11 (message):
  Provide path to Binary Ninja API source in BN_API_PATH

How should BN_API_PATH be set?

It's just an environment variable, you set it with export or just set it before running the command.

You can see more details here:
https://docs.binary.ninja/dev/plugins.html#project-setup

My current successful build procedure (after installing all dependencies) ...

$  cd my_BN_plugin_dir
$  git clone https://github.com/emesare/binja-msvc
$  cd binja-msvc/
$  git clone https://github.com/Vector35/binaryninja-api.git
$  cd binaryninja-api
$  git checkout $(cut -d '/' -f 7 ~/src/BinaryNinja/binaryninja/api_REVISION.txt)
$  git submodule update --init --recursive
$  cd ..
$  BN_API_PATH=binaryninja-api BN_INSTALL_DIR=/home/rick/src/BinaryNinja/binaryninja/ cmake --preset "default-debug"
$  cd out/build/
$  cmake --build "default-debug"
$  cp -av default-debug/libbinja-msvc.so ~/.binaryninja/plugins/libbinja-msvc.so