pbiernat / ripr

Package Binary Code as a Python class using Binary Ninja and Unicorn Engine
MIT License
397 stars 29 forks source link

Binary Ninja log: "Python plugin 'ripr' could not be loaded" #5

Closed michael-myers closed 7 years ago

michael-myers commented 7 years ago

Has ripr been tested on MacOS? I have another plugin (binja-retdec) that works, and I've installed ripr the same way, but ripr fails to load. Let me know if there is a way to debug this further.

$ pwd
/Users/myname/Library/Application Support/Binary Ninja/plugins
myname-MacBook-Pro:plugins myname$ tree
.
├── binja-retdec
│   ├── LICENSE
│   ├── LICENSE-RetDec
│   ├── README.md
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── api_key
│   ├── plugin.json
│   ├── retdec.py
│   ├── retdec.pyc
│   ├── utils.py
│   └── utils.pyc
└── ripr
    ├── __init__.py
    ├── __init__.pyc
    ├── analysis_engine.py
    ├── analysis_engine.pyc
    ├── codegen.py
    ├── defunct
    │   ├── __init__.py
    │   └── widgets.py
    ├── dependency.py
    ├── gui.py
    ├── gui.pyc
    └── packager.py
sheriffsparks commented 7 years ago

What is the error messages displayed in the binaryninja log when you open it?

michael-myers commented 7 years ago

That is the only error message: "Python plugin 'ripr' could not be loaded"

I tried checking the "plugin development debugging" checkbox in the Binary Ninja preferences menu, but there was nothing different about the log output.

michael-myers commented 7 years ago

I found the debugging info flag: launching Binary Ninja with "-e", the following is printed to the console. It looks to be complaining about PyQt5 being missing.

$ /Applications/Binary\ Ninja.app/Contents/MacOS/binaryninja -e
Traceback (most recent call last):
  File "/Users/myname/Library/Application Support/Binary Ninja/plugins/ripr/__init__.py", line 7, in <module>
    from analysis_engine import *
  File "/Users/myname/Library/Application Support/Binary Ninja/plugins/ripr/analysis_engine.py", line 13, in <module>
    import gui
  File "/Users/myname/Library/Application Support/Binary Ninja/plugins/ripr/gui.py", line 8, in <module>
    from PyQt5 import QtWidgets, QtGui, QtCore
ImportError: No module named PyQt5
sheriffsparks commented 7 years ago

Just run

sudo apt-get install python-pyqt5
michael-myers commented 7 years ago

Yes, on Ubuntu. I was working on how to get this dependency installed on MacOS, though. The pip installer only provides a PyQt5 binary for Windows, and errors out with a message to Mac users to get it from a Git repo with no readme. The Homebrew package manager, by default (brew install pyqt5) installs Python 3 and then the PyQt5 package is only available from Python 3 (/usr/local/lib/python3.6/site-packages/PyQt5). Binary Ninja's Python runtime and paths are all 2.7 stuff. So this had me stuck for a bit.

But the solution to installing the PyQt5 dependency on a Mac, for Python 2, is this:

$ brew install pyqt5 --with-python --without-python3`
$ mkdir -p ~/Library/Python/2.7/lib/python/site-packages
$ echo 'import site; site.addsitedir("/usr/local/lib/python2.7/site-packages")' >> ~/Library/Python/2.7/lib/python/site-packages/homebrew.pth

Testing that I've got the dependency now:

$ python
Python 2.7.10 (default, Jul 30 2016, 19:40:32) 
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from PyQt5 import *
>>> quit()

Ok, so I launch Binary Ninja, and it crashes now. The top of the call stack shows that it crashed in Qt code, and the bottom of the call stack shows that it was trying to load plugins when it crashed:

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_CRASH (SIGABRT)
Exception Codes:       0x0000000000000000, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Application Specific Information:
abort() called

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib            0x00007fffc02b1dd6 __pthread_kill + 10
1   libsystem_pthread.dylib           0x00007fffc039d787 pthread_kill + 90
2   libsystem_c.dylib                 0x00007fffc0217420 abort + 129
3   org.qt-project.QtCore             0x000000010e11ebc9 0x10e109000 + 89033
4   org.qt-project.QtCore             0x000000010e1205d9 QMessageLogger::fatal(char const*, ...) const + 233
5   org.qt-project.QtWidgets          0x000000010d5afb4c QWidgetPrivate::QWidgetPrivate(int) + 604
6   org.qt-project.QtWidgets          0x000000010d5b09be QWidget::QWidget(QWidget*, QFlags<Qt::WindowType>) + 46
7   QtWidgets.so                      0x000000010d1b946e init_type_QWidget(_sipSimpleWrapper*, _object*, _object*, _object**, _object**, _object**) + 206
8   sip.so                            0x000000010e6d96fb sipSimpleWrapper_init + 180
9   org.python.python                 0x000000010a5422ff 0x10a4f1000 + 332543
10  org.python.python                 0x000000010a4fb75b PyObject_Call + 99
...
33  org.python.python                 0x000000010a4fb8e9 0x10a4f1000 + 43241
34  org.python.python                 0x000000010a4fb881 PyObject_CallFunction + 187
35  org.python.python                 0x000000010a5896c1 PyImport_Import + 386
36  org.python.python                 0x000000010a587cf8 PyImport_ImportModule + 31
37  libpythonplugin.dylib             0x000000010a4e5598 CorePluginInit + 2424
38  libbinaryninjacore.dylib          0x000000010289ca0d 0x102875000 + 162317
39  libbinaryninjacore.dylib          0x000000010289aea8 BNInitCorePlugins + 232
40  com.vector35.binaryninja          0x00000001022cf9f5 main + 5285
41  com.vector35.binaryninja          0x00000001022cb134 start + 52

🤷🏻‍♂️

Here is what the debugging info says in the console:

$ /Applications/Binary\ Ninja.app/Contents/MacOS/binaryninja -d -e
CorePluginInit()
objc[94173]: Class RunLoopModeTracker is implemented in both /Applications/Binary Ninja.app/Contents/Frameworks/QtCore.framework/Versions/5/QtCore (0x103ff2de0) and /usr/local/opt/qt@5.7/lib/QtCore.framework/Versions/5/QtCore (0x10e635df0). One of the two will be used. Which one is undefined.
objc[94173]: Class NotificationReceiver is implemented in both /Applications/Binary Ninja.app/Contents/Frameworks/QtWidgets.framework/Versions/5/QtWidgets (0x10313f240) and /usr/local/opt/qt@5.7/lib/QtWidgets.framework/Versions/5/QtWidgets (0x10da9bef0). One of the two will be used. Which one is undefined.
[!] Not running in IDA
QWidget: Must construct a QApplication before a QWidget
Abort trap: 6

Removing the ripr directory from the plugins directory makes the crash (and the above console debug messages) go away.

sheriffsparks commented 7 years ago

Oh right sorry I forgot you have it on a MAC. I will try installing it on a MAC later and let you know if I figure it out.

pbiernat commented 7 years ago

I've only used/tested ripr on Linux and Windows. Theoretically, everything should "just work" if you have a compatible pyqt5, but I'm not familiar enough with macOS to offer much guidance there.

Be sure to let me know if you get it working!

zglozman commented 7 years ago

ImportError: /home/zglozman/Desktop/binaryninja/libQt5Core.so.5: version `Qt_5.7' not found (required by /usr/lib/python2.7/dist-packages/PyQt5/QtWidgets.x86_64-linux-gnu.so) Python plugin 'ripr' could not be loaded

zglozman@zzz-bbb:~/.binaryninja/plugins$ apt-cache search python-pyqt5

python-pyqt5 - Python 2 bindings for Qt5 python-pyqt5-dbg - Python 2 bindings for Qt5 (debug extensions) python-pyqt5.qtmultimedia - Python 2 bindings for Qt5's Multimedia module python-pyqt5.qtmultimedia-dbg - Python 2 bindings for Qt5's Multimedia module (debug extensions) python-pyqt5.qtopengl - Python 2 bindings for Qt5's OpenGL module python-pyqt5.qtopengl-dbg - Python 2 bindings for Qt5's OpenGL module (debug extension) python-pyqt5.qtpositioning - Python 2 bindings for QtPositioning module python-pyqt5.qtpositioning-dbg - Python 2 bindings for QtPositioning module (debug extension) python-pyqt5.qtquick - Python 2 bindings for QtQuick module python-pyqt5.qtquick-dbg - Python 2 bindings for QtQuick module (debug extensions) python-pyqt5.qtsensors - Python 2 bindings for QtSensors module python-pyqt5.qtsensors-dbg - Python 2 bindings for QtSensors module (debug extension) python-pyqt5.qtserialport - Python 2 bindings for QtSerialPort module python-pyqt5.qtserialport-dbg - Python 2 bindings for QtSerialPort module (debug extension) python-pyqt5.qtsql - Python 2 bindings for Qt5's SQL module python-pyqt5.qtsql-dbg - Python 2 bindings for Qt5's SQL module (debug extension) python-pyqt5.qtsvg - Python 2 bindings for Qt5's SVG module python-pyqt5.qtsvg-dbg - Python 2 bindings for Qt5's SVG module (debug extension) python-pyqt5.qtwebchannel - Python 2 bindings for Qt5's WebChannel module python-pyqt5.qtwebchannel-dbg - Python 2 bindings for Qt5's Webchannel module (debug extension) python-pyqt5.qtwebengine - Python 2 bindings for Qt5's WebEngine module python-pyqt5.qtwebengine-dbg - Python 2 bindings for Qt5's WebEngine module (debug extensions) python-pyqt5.qtwebkit - Python 2 bindings for Qt5's WebKit module python-pyqt5.qtwebkit-dbg - Python 2 bindings for Qt5's WebKit module (debug extensions) python-pyqt5.qtwebsockets - Python 2 bindings for Qt5's WebSockets module python-pyqt5.qtwebsockets-dbg - Python 2 bindings for Qt5's WebSockets module (debug extension) python-pyqt5.qtx11extras - Python 2 bindings for QtX11Extras module python-pyqt5.qtx11extras-dbg - Python 2 bindings for QtX11Extras module (debug extension) python-pyqt5.qtxmlpatterns - Python 2 bindings for Qt5's XmlPatterns module python-pyqt5.qtxmlpatterns-dbg - Python 2 bindings for Qt5's XmlPatterns module (debug extension) python-pyqt5.enginio - Python 2 bindings for Enginio library python-pyqt5.enginio-dbg - Python 2 bindings for Enginio library (debug extension) python-pyqt5.qsci - Python bindings for QScintilla 2 with Qt 5 python-pyqt5.qsci-dbg - Python bindings for QScintilla 2 (Qt 5 debug extensions)

pbiernat commented 7 years ago

The latest version no longer requires PyQt5 bindings, so I'm marking this as closed. If you have any other issues specific to OSX, please let me know.