IDA 6.9, Mac OS X, ‘random’ crashes

Intended audience

IDA 6.9 users on Mac OS X, who have suffered seemingly-apparent crashes while using IDA.

The problem

The Qt 5.4.1 libraries shipped with IDA 6.9 suffer from the following bug: https://bugreports.qt.io/browse/QTBUG-44708, which was apparently fixed in Qt 5.5.0.

If, when IDA crashes, you ever spotted a backtrace that looks like the following:

frame #0: 0x00000000
frame #1: 0x00d8a50d QtGui'QT::QTextEngine::shapeText(int) const + 1187
frame #2: 0x00d8b517 QtGui'QT::QTextEngine::shape(int) const + 1199
frame #3: 0x00d8c977 QtGui'QT::QTextEngine::width(int, int) const + 155
frame #4: 0x00d73571 QtGui'QT::QFontMetricsF::width(QT::QString const&) const + 163
frame #5: 0x00041184 idaq'___lldb_unnamed_function853$$idaq + 420
...

then you’ve been a victim of this rather tiresome issue.

(note: frame #0 doesn’t quite matter; the 2nd line, QT::QTextEngine::shapeText(int), is the important one)

The solution

We have applied the patch mentionned in the Qt bugreport & re-built the libqcocoa.dylib Qt platform support.

You will have to:

  1. download & unzip the following archive: qcocoa.zip.
  2. verify the shasum of the libqcocoa.dylib file:
    $ shasum libqcocoa.dylib 
    afcf3603f593776c6f39f41f81e98843897cf0ed  libqcocoa.dylib
    
  3. place the libqcocoa.dylib binary instead of the one in /path/to/IDA_6.9/idaq.app/Contents/Plugins/

Once that is done, those crashes shouldn’t happen anymore.

A big, big thank you to Willem Jan Hengeveld & Vladimir Putin, who have reported this!

Beware: IDA C++ plugins, Qt 5.x, QStringLiteral: crash at exit-time

Intended audience

IDA C++ plugin authors, who wish to link such plugins against Qt 5.x libraries.

The problem

One of our customers, Aliaksandr Trafimchuk, recently reported that whenever IDA was run with a plugin of his that links against the Qt libraries that we ship, IDA would crash at exit-time (at least on Windows.)

Aliaksandr already did most of the work of figuring out exactly what was causing the crash, and even had a work-around (more like a kludge, as he pointed out, really) for it, but he still wanted to let us know about it so we are aware of the problem & perhaps can communicate about it.

The crash is an access violation, in an area of memory that doesn’t seem to be mapped by any stack, heap, DLL code or data.

The stack reveals that the crash happens at QCoreApplication::~QCoreApplication()-time (i.e., at application exit), when the QFontCache is freeing/releasing its entries:

  Qt5Core.dll!QT::QSettingsGroup::~QSettingsGroup()
  Qt5Gui.dll!QT::QMapNode::destroySubTree()
  Qt5Gui.dll!QT::QFontCache::clear()
  Qt5Gui.dll!QT::QFontCache::~QFontCache()
  [External Code] 
  Qt5Gui.dll!QT::QThreadStorage::deleteData(void * x)
  Qt5Core.dll!QT::QThreadStorageData::set(void * p)
  Qt5Gui.dll!QT::QFont::cleanup()
  Qt5Gui.dll!QT::QGuiApplicationPrivate::~QGuiApplicationPrivate()
  [External Code] 
  Qt5Core.dll!QT::QObject::~QObject()
  Qt5Core.dll!QT::QCoreApplication::~QCoreApplication()
  idaq.exe!013426c5() Unknown
  (...)

Why does that happen?

Our customer’s plugin uses a UI description file, that needs to be processed by Qt’s uic (UI-compiler). The generated code contains lines such as these:

label = new QLabel(TestDialog);
label->setObjectName(QStringLiteral("label"));
QFont font;
font.setFamily(QStringLiteral("Comic Sans MS"));

Note the use of QStringLiteral.

The QStringLiteral type

This is an optimization that came in Qt 5.x, and that causes actual QString instances to be laid out in the .rodata section of the program (together with a special refcount value that is -1, meaning “don’t touch this refcount”.)

Although at exit-time, this “static const” in-.rodata-QString instance wouldn’t be modified (because of the -1 refcount), simply reading it will cause a crash, since the section holding it has been removed from memory.

This is a known limitation/problem, too: https://bugreports.qt.io/browse/QTBUG-46880

The plugin lifecycle

This is where the problem lies: at exit-time, IDA will:

  1. unload plugins
  2. proceed until its QCoreApplication goes out of scope, which will perform (among other things) the QFontCache cleanup.
  3. alas, at that time, the QFontCache still refers to literal QString data, in a section that is now gone (it was discarded at #1)

In fact, Qt expects that any binary that uses Qt libraries should remain in memory, so that some optimizations (such as the QStringLiteral) will continue to work. That’s why, when Qt unloads some of its own plugins, it doesn’t really unload those from memory.

Although the Qt library maintainers consider that having such limitations on binaries that link against Qt is acceptable, I personally hope they try to keep those restrictions as minimal as possible.

The solution

In any case, concerning this QStringLiteral issue, we have a way out: at compilation-time, pass the compiler the following flag: -DQT_NO_UNICODE_LITERAL

This will turn the QStringLiteral() expression into a QString::fromUtf8(), which will allocate the memory on the heap and the plugin should work just fine.


Another possible solution

Another possibility reported by an IDA user (but untested by us), is to add the following after the Qt headers #include directives:

#undef QStringLiteral
#define QStringLiteral(_str) _str

With this method, the literal C-style string will be implicitly converted to a QString, using the default conversion rules.


Footnotes

The kludge (which is Windows-specific) consists of calling LoadLibrary(szMyPluginFilePath), thereby somewhat artificially incrementing the refcount of his plugin, which will cause it to remain in memory & thus the ~QFontCache cleanup will succeed.

IDAPython: migrating PySide code to PyQt5

Background

Contrary to previous versions that shipped with Qt 4.8.4, IDA 6.9 ships with Qt 5.4.1 and as we announced some time ago, this will force some changes for plugin writers who were using IDAPython + PySide in order to build custom interfaces.

What’s more, in addition to the Qt4 -> Qt5 switch, we have also chosen to drop PySide in favor of PyQt5, as it seems to be more actively developed.

Porting

While we were porting some internal plugins & test scripts, we have come across a number of ‘issues’ that are due both to the change in major Qt version, and also to the switch to PyQt5.

Here is a (non-exhaustive) list of such problems that needed to be dealt with.

Use ‘from PyQt5’ instead of ‘from PySide’

   from PySide import QtCore, QtGui

Becomes:

   from PyQt5 import QtCore, QtGui, QtWidgets

(notice the added ‘QtWidgets’. Keep reading.)

Most widgets are now in QtWidgets, not QtGui anymore (Qt5 architecture change)

   from PySide import QtGui
   edit = QtGui.QTextEdit()

Becomes:

   from PyQt5 import QtWidgets
   edit = QtWidgets.QTextEdit()

Converting TForm instances must be done to PyQt

   from PySide import QtGui, QtCore
   form = idaapi.find_tform("Output window")
   w = idaapi.PluginForm.FormToPySideWidget(form)

Becomes:

   from PyQt5 import QtGui, QtCore, QtWidgets
   form = idaapi.find_tform("Output window")
   w = idaapi.PluginForm.FormToPyQtWidget(form)

Public QEvent types are in QtCore.QEvent namespace

   QtCore.QEvent.Type.XXX

Becomes:

   QtCore.QEvent.XXX

Using QObject.connect() to connect signal with slot doesn’t work anymore. Use alternative approach.

   obj.connect(query_action, QtCore.SIGNAL("triggered()"), self.ui.queryGraph)

Becomes:

   query_action.triggered.connect(self.ui.queryGraph)

Misc. required changes (reported by our users)

  • QHeaderView.setResizeMode => QHeaderView.setSectionResizeMode
  • QtCore.Qt.ItemFlag enum was moved to be accessed directly on QtCore.Qt
  • QColorDialog.setCustomColor now takes a QColor instead of an RGB int as the second argument.

Final words

As I said above, this is a non-exhaustive list of issues we encountered. Should you encounter other issues, please let us know about them, so we can update & improve this page to help the community!

IDA 6.9: Qt 5.4.1 configure options & patch

A handful of our users have already requested information regarding the Qt 5.4.1 build, that is shipped with IDA 6.9.

Configure options

Here are the options that were used to build the libraries on:

  • Windows: ...\5.4.1\configure.bat "-debug-and-release" "-nomake" "tests" "-qtnamespace" "QT" "-confirm-license" "-accessibility" "-platform" "win32-msvc2015" "-opengl" "desktop" "-force-debug-info" "-prefix" "C:/Qt/5.4.1"
    • Note that you will very likely have to build with Visual Studio 2015, to obtain compatible libs
  • Linux: .../5.4.1/configure "-debug-and-release" "-nomake" "tests" "-qtnamespace" "QT" "-confirm-license" "-accessibility" "-platform" "linux-g++-32" "-developer-build" "-fontconfig" "-qt-freetype" "-qt-libpng" "-glib" "-qt-xcb" "-dbus" "-qt-sql-sqlite" "-gtkstyle" "-prefix" "/usr/local/Qt/5.4.1"
  • Mac OSX: .../5.4.1/configure "-debug-and-release" "-nomake" "tests" "-qtnamespace" "QT" "-confirm-license" "-accessibility" "-platform" "macx-g++-32" "-fontconfig" "-qt-freetype" "-qt-libpng" "-qt-sql-sqlite" "-prefix" "/Users/Shared/Qt/5.4.1"

patch

In addition to the specific configure options, the Qt build that ships with IDA includes the following patch. You should therefore apply it to your own Qt 5.4.1 sources before compiling, in order to obtain similar binaries.

Installing IDA 6.9 on Linux

IDA is still, as of this writing (December 23rd, 2015), a 32-bit application and both IDA & its installer(*) require certain 32-bit libraries to be present on your Linux system before they can run.

Here is the list of commands you will have to run in order to install those dependencies, for the following systems:

  • Debian & derivative systems such as Ubuntu, Xubuntu, …
  • Red Hat Enterprise Linux 7.2 (and likely other versions as well)
Note: we cannot possibly install & try IDA on all flavors/versions of all Linux distributions, but we will do our best to update this post with relevant information, whenever we learn of a distribution requiring special attention.

(*) that is: if you want the installer to run a graphical interface, instead of a command-line one.

Debian & Ubuntu

Common dependencies

The following should allow IDA to run on most Linux systems deriving from Debian distributions:

sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install libc6-i686:i386 libexpat1:i386 libffi6:i386 libfontconfig1:i386 libfreetype6:i386 libgcc1:i386 libglib2.0-0:i386 libice6:i386 libpcre3:i386 libpng12-0:i386 libsm6:i386 libstdc++6:i386 libuuid1:i386 libx11-6:i386 libxau6:i386 libxcb1:i386 libxdmcp6:i386 libxext6:i386 libxrender1:i386 zlib1g:i386 libx11-xcb1:i386 libdbus-1-3:i386 libxi6:i386 libsm6:i386 libcurl3:i386 

Xubuntu 15.10

It is necessary to also run those commands, for IDA to present a usable GUI on Xubuntu 15.10

sudo apt-get install libgtk2.0-0:i386 gtk2-engines-murrine:i386 gtk2-engines-pixbuf:i386 

Red Hat Enterprise Linux 7.2

IDA will require the following packages to be installed, in order to run properly on RHEL 7.2 (and probably any other RPM-based distribution) :

redhat-lsb-core.i686
glib2.i686
libXext.i686
libXi.i686
libSM.i686
libICE.i686
freetype.i686
fontconfig.i686
dbus-libs.i686 

IDA + Windows + system python 2.7.11

In case you:

  • are running IDA on Windows
  • are using the system’s Python (as opposed to the bundled Python distribution, that one can opt for at installation-time)
  • have installed the recently released Python 2.7.11

…you will have noticed that IDAPython fails to load the ‘site’ module and, consequently, IDAPython is not available.


As far as I understand, this is a Python installer issue, which I reported ( https://bugs.python.org/issue25824 )

While waiting for feedback from the Python authors, we can already offer the two following solutions:

  1. remove Python 2.7.11 and pick an earlier version (2.7.10 is known to work)
  2. open regedit.exe, and rename the key:
    HKLM\Software\Wow6432Node\Python\PythonCore\2.7\PythonPath into
    HKLM\Software\Wow6432Node\Python\PythonCore\2.7-32\PythonPath

This post will be updated whenever more information becomes available on the Python side.

HTH!

(Thanks to Tamir Bahar, who reported this issue very early on!)

Hack of the day #0: Somewhat-automating pseudocode HTML generation, with IDAPython.

The problem

As you may already know1, Hex-Rays decompilers can generate HTML files from pseudocode windows.
That feature, however, is limited to generating HTML for a single function, or a portion of a function.

Recently, one of our customers asked us whether there was a way to generate HTML files for multiple functions all at once. I was at the regret of telling him that, no, we don’t have that feature (and it doesn’t really seem to be of interest to many, since AFAICT we have received no request for it)

However, after the Great Actions Refactoring™, decompiler action are now 1st class IDA citizens (just like any other plugin actions, really.) That means we can now invoke them, just like we could already invoke any IDA core action. We just need to take a few precaution, is all.

A first approach

Here’s a piece of IDAPython code I hammered into shape, that will go through all the functions of the program and (if the current function is decompilable) will prompt the user for saving:

from idaapi import *
from PySide import QtGui, QtCore

# Our piece of code relies on the user having already opened a pseudocode view. That's a limitation, but oh well.
tform = find_tform("Pseudocode-A")
if not tform:
    raise Exception("Please open a pseudocode view")
qwidget = PluginForm.FormToPySideWidget(tform)

# Iterate all funcs
for fidx in xrange(get_func_qty()):
    f = getn_func(fidx)
    try:
        if decompile(f):
            # Ok, we can jump there w/o being
            # switched to "IDA View-A"
            jumpto(f.startEA)

            # Needed. W/o that, focus might be
            # elsewhere, and the 'hx:GenHtml'
            # will refuse to work.
            qwidget.setFocus()

            process_ui_action("hx:GenHtml")
    except DecompilationFailure:
        print "Decompilation failure: %x. Skipping."  % f.startEA
        pass

Notes:

  • I only tried that with IDA 6.8, on a Linux box.
  • this is *NOT* meant to be an elegant, comfortable or rock-solid approach to generating HTML files with pseudocode (hence the ‘Hack of the day’ subject of this post!)
  • this is really just meant to illustrate how IDA APIs can be (ab)used, and perhaps give inspiration to some readers for some of their use-cases
  • this will go through _all_ functions in the program. If you just need to print 20 functions out of 13942, it might become tedious to reject (13942 – 20 =) 13922 “Save file” dialogs.

Improving that code, so only the selected functions will be printed

A possibly nice improvement to this, would be to know what functions the user selected in the “Functions window”, and iterate over those only, prompting for save.

Here’s how I would go about it, knowing that:

  • the ‘Functions window’ is what we call, in IDA-land, a ‘chooser’
  • alas, this is not a user-controlled chooser
  • thus we don’t control the data being printed, nor do we get called back whenever something gets selected/deselected…

    Great Actions Refactoring to the rescue again!

    We will:

    1. create an “Generate HTML files” action that, basically, wraps the above code, then
    2. register a ‘popup being populated’ hook: when the popup is for the ‘Functions window’ we will attach our new action to that popup
    3. then, when that action is invoked (i.e., user clicked it), in our action handler we will retrieve the list of selected indices and iterate over those, prompting for save

    from idaapi import *
    from PySide import QtGui, QtCore
    
    # Register action
    class GenMultiHTML(action_handler_t):
        def __init__(self):
            action_handler_t.__init__(self)
    
        def activate(self, ctx):
            tform = find_tform("Pseudocode-A")
            if not tform:
                raise Exception("Please open a pseudocode view")
            qwidget = PluginForm.FormToPySideWidget(tform)
            for fidx in ctx.chooser_selection:
                f = getn_func(fidx - 1)
                try:
                    if decompile(f):
                        # ok, we can jump there w/o being
                        # switched to "IDA View-A"
                        jumpto(f.startEA)
                        qwidget.setFocus()
                        process_ui_action("hx:GenHtml")
                except DecompilationFailure:
                    print "Decompilation failure: %x. Skipping."  % f.startEA
                    pass
    
            return 1
    
        def update(self, ctx):
            return AST_ENABLE_FOR_FORM if ctx.form_title == "Functions window" else AST_DISABLE_FOR_FORM
    
    register_action(
        action_desc_t(
            'my:gen_multi_html',
            'Generate HTML files',
            GenMultiHTML()))
    
    # Listen to 'finish populating popup' hook, to add our
    # action if the popup is for the "Functions window"
    class Hooks(idaapi.UI_Hooks):
        def finish_populating_tform_popup(self, form, popup):
            if get_tform_title(form) == "Functions window":
                attach_action_to_popup(
                    form,
                    popup,
                    "my:gen_multi_html",
                    None)
    
    hooks = Hooks()
    hooks.hook()
    

    Happy hacking!


    Footnotes

    #1: And if you didn’t know: go to a pseudocode window, click on the function’s title (i.e., the first line), and open the context menu. You can also select a portion of text, and generate HTML just for that.

IDAPython + PySide/PyQt: future plans

Intended audience

IDAPython plugin writers who are using the PySide Qt bindings.

PySide: some background

For some time now it has been possible, through IDAPython, to use PySide bindings to the Qt libraries that are shipped with IDA.

Those PySide bindings were first placed on Hex-Rays’s website and, since we noticed a considerable interest for them, we later decided to ship them with IDA (starting at IDA 6.6.)

What about PyQt?

The choice of PySide over PyQt was essentially due to incompatibilities between the licensing model of PyQt, and that of Hex-Rays.

The problem

PySide appears to have pretty much stopped evolving, and now remains stuck with Qt 4 (i.e., the 4.8 branch.)
PySide isn’t available for Qt 5 and, as of today, the last update of the PySide roadmap dates back to “March 26, 2013”.

There is still some activity on the PySide mailing list, but despite that, not much seems to be happening (and the latest release is from 1 year ago.)

This is very problematic for us as Qt 4 is becoming more and more irrelevant by the day, and we would love to move to Qt 5.

We could, in theory, invest in porting PySide to support Qt 5, but it would probably lead us to an undesirable situation where PySide is pretty much used and maintained by Hex-Rays only.

Meanwhile, in PyQt land

In the meantime, the PyQt people at http://www.riverbankcomputing.co.uk/ have changed their licensing options, and after having contacted them recently, we have found that we can now consider the following:

  • Hex-Rays can acquire PyQt licenses
  • with those, we can build PyQt, and ship it with IDA
  • IDA users can make use of PyQt themselves

In other words, we will be able to provide a replacement for PySide, that:

  • is widely used, and has momentum
  • supports Qt 5

Our plan

Our plan is to roll, in a few days, IDA 6.8 that still depends on Qt 4, and still ships with PySide.

The release after that (i.e., 6.9) will then depend on Qt 5, and come with PyQt.

What that means for developers

Thankfully, the interfaces of PySide and PyQt are highly compatible, and thus it should not be necessary to rewrite your plugins from scratch (in fact, very little should have to be modified.)

I would recommend you to stay tuned to the Hex-Rays forums, so that you can participate in the beta program for IDA 6.9 once it is announced. That will give you the possibility of porting your tools to PyQt before IDA 6.9 is released. We will also provide guidance on how to approach that porting effort (even though, once again, it should be fairly small.)

As you may already know, we are very reluctant to any kind of API/compatibility breakage. But unfortunately, it seems we simply don’t have a choice in this particular case.

Installing PIP packages, and using them from IDA on a 64-bit machine

Recently, one of our customers came to us asking how he should proceed to be able to install python packages, using PIP, and use those from IDA.

The issue he was facing is that his system is a 64-bit Ubuntu 12.04 VM.
Therefore using the Ubuntu-bundled PIP will just result in installing the desired package (let’s say ssdeep) for the system Python runtime, which is a 64-bit runtime and therefore not compatible with IDA.

The best (as in: cleanest) solution I have found is to:

  • build a 32-bits python on the system.
  • pip-install packages in that 32-bits python’s sub-directories.
  • export PYTHONPATH to point to the 32-bits python’s sub-directories.

We figured we’d write it down here just in case it might help others.

Prerequisites

  • Install autoconf
  • Install ia32-libs

Building & installing a 32-bits python

  • ..$ export LD_LIBRARY_PATH=/lib/i386-linux-gnu/:/usr/lib32:$LD_LIBRARY_PATH
  • Download Python2.7.4
    • Note:You should make sure that the MD5 checksum and the size of the file you downloaded match those that are advertised on the page. That would prevent a man-in-the-middle attacker from providing you with a malicious Python bundle.
  • Build it. Note that you’ll probably have to sudo-create a few symlinks. I had to do this, on the Ubuntu 12.04 64-bit VM I tested this on:
    • /lib/i386-linux-gnu/libssl.so/lib/i386-linux-gnu/libssl.so.1.0.0
    • /lib/i386-linux-gnu/libcrypto.so/lib/i386-linux-gnu/libcrypto.so.1.0.0
    • /lib/i386-linux-gnu/libz.so/lib/i386-linux-gnu/libz.so.1
  • For the sake of completeness, here are my build commands (don’t forget the flags, of course):
    • ..$ CFLAGS=-m32 LDFLAGS=-m32 ./configure --prefix=/opt/Python2.7.4-32bits
    • ..$ CFLAGS=-m32 LDFLAGS=-m32 make -j 8

Once the build completes

Here’s what I have as last lines of the build:

INFO: Can't locate Tcl/Tk libs and/or headers

Python build finished, but the necessary bits to build these modules were not found:
_bsddb             _curses            _curses_panel
_sqlite3           _tkinter           bsddb185
bz2                dbm                gdbm
readline           sunaudiodev
To find the necessary bits, look in setup.py in detect_modules() for the module's name.

If you see, below that, that it failed to build, say 'binascii', then something went wrong.

Make sure you run make -j 1 to check out what went wrong (i.e., what library it claims not being able to find)

Once you have succesfully built your 32-bits Python, it’s time to install it: sudo make install

Trying your freshly-built python

..$ /opt/Python2.7.4-32bits/bin/python2.7
Python 2.7.4 (default, Apr 26 2013, 16:03:38)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import binascii
>>>

No complaint so far. Good.

Checking that pkg_resources is available.

Try importing pkg_resources. If it fails, you’ll probably have to do the following:

..$ cd /tmp
..$ curl -O http://python-distribute.org/distribute_setup.py
..$ less distribute_setup.py  # (*)
..$ sudo /opt/Python2.7.4-32bits/bin/python2.7 distribute_setup.py

That will print out quite a fair amount of info, and should succeed.

(*) Note: A careful reader has pointed out that it would be fairly easy to intercept (man-in-the-middle) such an HTTP request, and serve malicious content that would then be piped (as root) to Python.
That’s why I think it’s important to mention, as a third step (i.e., less ...), that the code that was downloaded should ideally be checked. Hopefully, http://python-distribute.org will soon provide HTTPS support, which will limit such MITM attack risks.

Trying your freshly-built python, again

We want to make sure pkg_resources can be imported.

..$ /opt/Python2.7.4-32bits/bin/python2.7
Python 2.7.4 (default, Apr 26 2013, 16:03:38)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkg_resources
>>>

Still no complaint. Good.

If yours complains, you’ll have to first make sure you fix whatever is causing it to fail, because the next will not work without that.

Installing PIP for your new Python build

Since using your system’s PIP will probably not work (as it would build & install things in a 64-bits python sub-directory), you’ll have to install a PIP package specifically for your freshly-built Python.

Here’s how I proceeded:

..$ cd /tmp;
..$ curl -O https://raw.github.com/pypa/pip/master/contrib/get-pip.py;
..$ sudo /opt/Python2.7.4-32bits/bin/python2.7 get-pip.py

PIP is now installed.

PIP-installing a package (i.e., ssdeep)

To download/build/install the ssdeep package I ran, as root (either that, or you’ll have to give your user the rights to write in /opt/Python2.7.4-32bits):

..$ su
Password:
root ..$ export CFLAGS=-m32
root ..$ export LDFLAGS=-m32
root ..$ export LD_LIBRARY_PATH=/lib/i386-linux-gnu/:/usr/lib32:$LD_LIBRARY_PATH
root ..$ /opt/Python2.7.4-32bits/bin/python2.7 /opt/Python2.7.4-32bits/bin/pip install ssdeep

Notice how I use my freshly-built python, with my fresly-installed PIP (and not the system one.)

Note: Don’t forget the export lines, or PIP will partially build stuff for x64, and partially for x86. That, as you can guess, won’t quite work.

If you forgot the export lines and started building anyway (and the build failed because of the mixed architecture issue I just wrote about), make sure you delete whatever is in /tmp/pip-build-*, so that there won’t be stale object files of inappropriate architecture in there.

Check out the PIP-installed package works

..$ /opt/Python2.7.4-32bits/bin/python2.7
Python 2.7.4 (default, Apr 26 2013, 16:03:38)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssdeep
>>> ssdeep
<module 'ssdeep' from '/opt/Python2.7.4-32bits/lib/python2.7/site-packages/ssdeep.so'>
>>> dir(ssdeep)
['Error', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__test__', '__version__', 'compare', 'hash', 'hash_from_file', 'sys']
>>>

So far so good.

Testing the PIP-installed package in IDA

Since that’s still the goal (though you might have forgotten by now, given the amount of directions above.. 😉 ),
we’ll now try and make use of that PIP-installed package in IDA.

  • ..$ export PYTHONPATH=/opt/Python2.7.4-32bits/lib/python2.7/site-packages:/opt/Python2.7.4-32bits/:$PYTHONPATH
  • ..$ idaq

If all went well, typing import ssdeep in the Python input line should properly, silently, nicely import the package.