IDAPython 0.8.0 patch
Joe Bruce (PSUJobu) <JoeBrucePSUgmailcom> Friday, September 1 2006 12:46.15 CDT


Pedram asked for an article, but since I don't feel this is article-worthy...  ;-)

I started a topic on the IDA Pro bulletin board about an IDAPython loader module. Though I have not had the time to finish that little experiment, I tried out the few unknowns (I have written loader modules before, and know what I need to do).

Question #1: Can you call mem2base() from outside of a loader?  Answer: IDAPython does not wrap mem2base()

Building IDAPython

So, I figured out how to build IDAPython and how Gergo wanted the directory structure set up:

<some_dir>/
    idapython
    idasdk-versions/
        4.9/
    swigsdk-versions/
        4.9/


I added cygwin/bin to my PATH, opened an NT command prompt, and ran vcvars32.bat from my Visual C++ install.  Then you do 'make dist IDAVERSION=4.9' and voila - I had a plugin.  Well, not quite.  I had to edit the makefile to force the SYSTEM to be WindowsNT, since Cygwin 'uname' reports 'CygwinNT', and I had to tweak the paths and add a new environment variable FIND to provide the complete path.  Gergo obviously has some "environmental" differences.  C'est la vie.

Modifying IDAPython

Actually, I really only had to modify the IDA SDK - the version beneath swigsdk-versions/4.9.  In loader.hpp, I moved #ifdef's around to export mem2base() to Python via SWIG.  Rebuild, and "Bam!" - IDAPython kicked up a notch...

...until you try to call idaapi.mem2base() with the logical arguments - a Python string and three integers.  You get a TypeError exception because of the first argument.  Apparently Python strings do not match 'void', which is how SWIG translates the "const void *" argument.

In the end, I changed "const void *" to "const char *" and everyone was happy.

Question #1 (again): Can you call mem2base() from outside of a loader?  Answer: Yes!

Other Possibilities

Why not expose file2base()?  I didn't look into it, but it should be possible.  I only cared about Python strings, since I want to decompress firmware from a source file and disassemble that rather than the compressed stuff.  Python with its "batteries included" mentality already supports a bunch of compression routines, so it is a ready-made solution to my problem.

The same "const void *" to "const char *" change would probably allow patch_many_bytes() to be exposed, too.

Disclaimer

I did not complete the experiment, so I didn't even bother checking segment creation from IDAPython (not that I doubt that those APIs are exposed).  I created a segment by hand in an existing IDB and used Alt+8 to write the two lines of Python required to generate some bogus data and write it into the new segment.

YMMV!

Files

I put the patch to IDAPython's 4.9.patch in my repository.  You need to apply the patch to 0.8.0 and rebuild.  I do not want to supply the binary for several reasons:

1. That's Gergely's "job" - I have no desire to take over IDAPython.  :)

2. Datarescue frowns upon distribution of plugin binaries for anything but the latest IDA Pro revision. Perhaps the SDK freeze makes this a non-issue (for 4.9+), but I would prefer not to help any illicit users of IDA Pro.  It is an excellent tool and well worth the money, IMHO.

3. See #1 - I had enough trouble creating a patch for a patch (timestamp differences cause bogus differences)

Of course, you could just wait for Gergely to release the update.  I only provided the info to demonstrate the ease of enhancing IDAPython.  Despite the lengthy posting, the bulk of the time to make this change was spent figuring out the build environment.  The real work (after this was): edit the SWIG version of the IDA SDK, rebuild, and test.  Were it not for my inexperience with SWIG, it would have taken about 2 minutes...

Comments
Posted: Wednesday, December 31 1969 18:00.00 CST