IDAPythonでpyenvでインストールしたPythonを選択する方法

IDAはバージョン7.4からPython3に対応した

IDAは拡張性にすぐれており、IDAPythonという独自拡張されたPythonによるスクリプティング機能を備えています。 最近までPython2系にしか対応していませんでしたが、バージョン7.4からPython3系に対応しました! 普通はIDAのインストーラがインストールされているPythonを見つけていいかんじにセットアップしてくれるのですが、 私の環境ではpyenvを使っているためやってくれませんでした.... その解決方法を紹介します!私はmacOS上にIDAをインストールしているので、 ここでの説明はmacOS向けのものになりますが、他OSでもおそらく手順は変わりません。

idapyswitchコマンドで使うPythonを選択する

インストーラPythonを見つけてくれなかったり、インストール後に異なるバージョンのPythonに切り替えたかったりしたときは、 idapyswitchコマンドで使用するPythonを後から選択可能です。 idapyswitchコマンドのヘルプに書かれている通り、主な使い方は、 「インストールされているPythonを見つける」、「見つけたPythonを適用する」、「Pythonの動的ライブラリのパスを指定して適用する」の3つです。

$ /Applications/IDA\ Pro\ 7.5/ida64.app/Contents/MacOS/idapyswitch -h
(省略)
IDA is no exception, and this tool is one such Python3 'switcher'.

It can be run in 3 ways:

  1) The default, interactive way
  -------------------------------
     > $ idapyswitch
   will look on the filesystem for available Python3 installations,
   present the user with a list of found versions (sorted according
   to preferability), and let the user pick which one IDA should use.

  2) The 'automatic' way
  ----------------------
     > $ idapyswitch --auto-apply
   will look on the filesystem for available Python3 installations,
   and automatically pick the one it deemed the most preferable.

  3) The 'manual' way
  -------------------
     > $ idapyswitch --force-path /path/to/Python.framework/Versions/3.7/Python
   will pick the path that the user provided.

Once a version is picked, this tool will do the following:

  * patch 'idapython.dylib' and 'idapython64.dylib' so that
    they refer to the right Python3 dylib.

なぜpyenvでインストールしたPythonを選択できなかったか

pyenvでPythonをインストールした場合、静的ライブラリを使ったものがインストールされますが、 idapyswitchコマンドで指定できるのは、Pythonランタイムの動的ライブラリです。 そのため、インストーラがpyenvでインストールしたPythonを認識できなかったようです。 macOSではotoolコマンドで実行ファイルに動的リンクされたライブラリを確認できます。 pyenvでインストールしたpythonの実行ファイルに対して、otoolコマンドを使うと次のようになります。 Python特有の動的ライブラリは確認できません。

$ otool -L /Users/tkmru/.pyenv/versions/3.8.3/bin/python
/Users/tkmru/.pyenv/versions/3.8.3/bin/python:
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
(compatibility version 150.0.0, current version 1575.17.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current
version 1252.250.1)

pyenvでPythonをインストールする際に--enable-frameworkを指定すると、Pythonランタイムの動的ライブラリが生成されます。

$ env PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install 3.8.3

otoolで確認すると、Pythonという名前の動的ライブラリが確認できます。 idapyswitchコマンドでこのパスを指定すると、IDAがpyenvでインストールしたPythonを認識してくれます。

$ otool -L /Users/tkmru/.pyenv/versions/3.8.3/bin/python
/Users/tkmru/.pyenv/versions/3.8.3/bin/python:
    /Users/tkmru/.pyenv/versions/3.8.3/Python.framework/Versions/3.8/Python (compatibility version 3.8.0, current version 3.8.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1)

$ file /Users/tkmru/.pyenv/versions/3.8.3/Python.framework/Versions/3.8/Python
/Users/tkmru/.pyenv/versions/3.8.3/Python.framework/Versions/3.8/Python: Mach-O 64-bit dynamically linked shared library x86_64

$ /Applications/IDA\ Pro\ 7.5/ida64.app/Contents/MacOS/idapyswitch --force-path \
> /Users/tkmru/.pyenv/versions/3.8.3/Python.framework/Versions/3.8/Python