{ "metadata": { "name": "", "signature": "sha256:f5408c7d078b1f23da341f6b83115e8bbd05fe67e7e12e5d53bf667162b1525b" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "#Cython and IDA Pro\n", "To run this notebook you will need the [ida_ipython](https://github.com/james91b/ida_ipython) plugin. The binary used is notepad.exe. This notebook shows how you can use [Cython](https://github.com/cython/cython) to access IDA api's that are not exposed via IDAPython. As you can see below in this example i used gcc with the [Anaconda](http://continuum.io/downloads) distribution to compile the Cython code. I suggest trying to trying to compile some Cython outside of IDA first, to make sure that it is all working." ] }, { "cell_type": "code", "collapsed": false, "input": [ "import idc\n", "print \"MD5: {} Binary: {}\".format(idc.GetInputMD5(), idc.GetInputFile())" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "-----------------------------------------------------------------------------------------------------\n", "Python 2.7.5 |Anaconda 2.1.0 (32-bit)| (default, May 31 2013, 10:43:53) [MSC v.1500 32 bit (Intel)] \n", "IDAPython v1.7.0 final (serial 0) (c) The IDAPython Team \n", "-----------------------------------------------------------------------------------------------------\n", "MD5: E30299799C4ECE3B53F4A7B8897A35B6 Binary: notepad.exe" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n" ] } ], "prompt_number": 1 }, { "cell_type": "markdown", "metadata": {}, "source": [ "##My configuration\n", "Below are some commands to show my configuration, so you can use it for comparision. " ] }, { "cell_type": "code", "collapsed": false, "input": [ "!echo %PYTHONHOME%\n", "!where gcc\n", "!gcc -v" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "C:\\Anaconda\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "C:\\Anaconda\\Scripts\\gcc.bat\n" ] }, { "output_type": "stream", "stream": "stderr", "text": [ "Using built-in specs.\n", "COLLECT_GCC=C:\\Anaconda\\Scripts\\gcc.bat\\..\\..\\MinGW\\bin\\gcc.exe\n", "COLLECT_LTO_WRAPPER=c:/anaconda/mingw/bin/../libexec/gcc/i686-w64-mingw32/4.7.0/lto-wrapper.exe\n", "Target: i686-w64-mingw32\n", "Configured with: ../../../build/gcc/src/configure --target=i686-w64-mingw32 --prefix=/c/bb/vista64-mingw32/mingw-x86-x86/build/build/root --with-sysroot=/c/bb/vista64-mingw32/mingw-x86-x86/build/build/root --enable-languages=all,obj-c++ --enable-fully-dynamic-string --disable-multilib\n", "Thread model: win32\n", "gcc version 4.7.0 20111219 (experimental) (GCC) \n" ] } ], "prompt_number": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "I have also set my compiler to MinGW32 in `disutils.cfg` file" ] }, { "cell_type": "code", "collapsed": false, "input": [ "!type %PYTHONHOME%\\Lib\\distutils\\distutils.cfg" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[build]\n", "compiler=mingw32\n" ] } ], "prompt_number": 3 }, { "cell_type": "markdown", "metadata": {}, "source": [ "##The Actual Cython Code" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First we load the Cython extention for IPython, then we create a simple test to call in msg funciton." ] }, { "cell_type": "code", "collapsed": false, "input": [ "%load_ext cythonmagic" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 4 }, { "cell_type": "code", "collapsed": false, "input": [ "%%cython -+ -f -IC:/dev/IDA/idasdks/idasdk61/include -c \"-D__NT__ -D__IDP__ -DWIN32\" --link-args \"C:/dev/IDA/idasdks/idasdk61/lib/x86_win_gcc_32/ida.a\"\n", "cdef extern from \"pro.h\": pass\n", "cdef extern from \"kernwin.hpp\":\n", " int msg(const char* msg, ...)\n", " \n", "msg(\"Hello from Cython!\\n\")" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 5 }, { "cell_type": "markdown", "metadata": {}, "source": [ "The command line parameters mean the following.\n", "\n", "- `-+` forces C++ mode\n", "- `-f` will force recompile/execution each time\n", "- `-IC:/dev/IDA/idasdks/idasdk61/include` points to your IDA SDK include\n", "- `-c \"-D__NT__ -D__IDP__ -DWIN32\"` definitions for the IDA SDK to compile\n", "- `--link-args \"C:/dev/IDA/idasdks/idasdk61/lib/x86_win_gcc_32/ida.a\"` library file for linking\n", "\n", "You will need to change some of these to get it to work on other compilers, you can read more of the documentation below." ] }, { "cell_type": "code", "collapsed": false, "input": [ "%%cython?" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Below is a slightly more complicated example exposing some of the type info api" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%%cython -+ -f -lm -IC:/dev/IDA/idasdks/idasdk61/include -c \"-D__NT__ -D__IDP__ -DWIN32\" --link-args \"C:/dev/IDA/idasdks/idasdk61/lib/x86_win_gcc_32/ida.a\"\n", "ctypedef unsigned int ea_t\n", "ctypedef int bool\n", "\n", "cdef extern from \"pro.h\":\n", " cdef cppclass _qstring[T]:\n", " T *c_str() \n", " ctypedef _qstring[uchar] qtype\n", "\n", "cdef extern from \"nalt.hpp\":\n", " bool get_tinfo(ea_t ea, qtype *type, qtype *fields) \n", " \n", "cpdef pget_tinfo(ea_t ea):\n", " cdef qtype typ\n", " cdef qtype fields\n", " get_tinfo(ea, &typ, &fields)\n", " return typ.c_str(), fields.c_str()" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 7 }, { "cell_type": "code", "collapsed": false, "input": [ "hex(idc.LocByName(\"_WinMain@16\"))" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 8, "text": [ "'0x401005'" ] } ], "prompt_number": 8 }, { "cell_type": "code", "collapsed": false, "input": [ "pget_tinfo(idc.LocByName(\"_WinMain@16\"))" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 9, "text": [ "('\\x0cS\\x07\\x05=\\nHINSTANCE=\\nHINSTANCE=\\x06LPSTR\\x07',\n", " '\\nhInstance\\x0ehPrevInstance\\nlpCmdLine\\tnShowCmd')" ] } ], "prompt_number": 9 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Cython can be used to access the C API or to speed up code. You could also just write most of the code in C then just call in from Cython in the notebook, if you\u2019re more comfortable with that. For more information have a look at the [documentation](http://docs.cython.org/)." ] } ], "metadata": {} } ] }