IDA python over IPC


Author: David Zimmer
Date: 11.08.17 - 3:58am



Continuing on from a previous thought about IDASRVR and x64 IDA7.

Everytime I want a new command in IDASRVR i need to find the functionality in the C API, then write a new stub to make it accessible over my IPC mechanism. Its no surprise I have only implemented what I have needed as I have needed it.

The IDA Python API wraps a zillion more things than I have, can I just have my C IPC server call the python api and then pass me back the return value?

Thought two, with the differences between the C API and compile requirements between IDA 6.95 and IDA 7 and also between 32bit and 64bit databases do I even want to deal with the C API anymore. Can I just host the entire IPC server in python as a .py plugin?

I have been experimenting with both of these things.

The python IPC server was pretty straight forward to create. I use the same WM_COPYDATA mechanism as IDASRVR. This lets clients broadcast to enumerate all open server windows, is by default synchronous across processes and has a built in timeout I dont have to worry about. Even through its local and windows only its just the way to go for my needs. Only downside is you have to manually start it when you want to use it although this could be overcome I am sure.

So basically it listens on a hwnd, when a command comes in it uses python exec or eval to run it. Script output is returned to the IPC client through a reply() function.

Ok cool. Now what about the C IDASRVR plugin. Can I run arbitrary python commands from that? The answer again is yes.

I did a little digging and found a hexblog post that got me started. I had experimented with python embedding a little bit, so now I got to play some more.

One thing i noticed when embedding Python within an IDA plugin... IDA links against the python27.dll always. When i compiled my plugin in debug mode it would fail to load, but release mode was ok. It didnt matter which lib i linked against (python27_d.lib or python27.lib).

Turns out python.h has a little hidden surprise

#include python.h -> pyconfig.h -> ifdef _DEBUG pragma comment(lib,"python27_d.lib") 

The solution is:

#ifdef _DEBUG
	#undef _DEBUG
	#include python27/Python.h
	#define _DEBUG
#else
	#include python27/Python.h
#endif

Now when we receive a python command over IPC

case 40: //pycmd:hwnd:replace(cmd,":",chr(5))
	  if( argc != 2 ){msg("pycmd needs 2 args"); return -1;}
	  hPYClient = atoi(args[1]);                    //hwnd used in idasrvr.reply so we dont have to track in py
	  for(i=0;i<strlen(args[2]);i++){               //since we use : as a token transpose back..
		  if(args[2][i] == 5) args[2][i] = ':';     // use idasrvr.reply to ret vals to caller through ipc
	  }
	  PyGILState_STATE state = PyGILState_Ensure(); // Acquire the GIL
	  init_pyClient();                              // add our idasrvr extension to the pyEnv
	  PyRun_SimpleString(pyStub);
	  PyRun_SimpleString(args[2]);                  // execute the python code passed to us by remote client
	  PyGILState_Release(state);                    // Release the GIL


In order to return values back to our IPC client again we add a reply() function called from the script itself. Two caveats here:
  • Adding new functions in C to python seems to require a module import. This necessitates a bulky import line and module.function type call.
  • The underlying IPC mechanism has a limit of 1024 characters per chunk.
To keep user scripts simple, I want to take care of both of these details so they can remain small and concise. This is where the pyStub comes in:

import idasrvr

def chunkString(s,sz=1000):
    o = []
    while s:
        o.append(s[:sz])
        s = s[sz:]
    return o

def reply(message):
    #print "sending msg '%s'" % message
    message = str(message)

    if len(message) > 1000:
        chunks = chunkString(message)
        for c in chunks:
            idasrvr.reply(c)
    else:
        idasrvr.reply(message)


Now the client scripts can just simply call reply(). You can also see the hPyClient respond to hwnd has also been cached by the C code for simplicity.

So anyway..it works and it was pretty easy to implement. I still need to bench mark it to see how much of a hit I am taking. I am sure it will be slow, but It will be nice to have as a fall back for API i havent implemented in C yet. At the end of the day I am just one dude tinkering on what I need. One of the things I need is the ability to leverage other peoples work so here it is in all of its lazy sloppy glory!  *

I have added support for the pycmd handler in IDASRVR. The vb6 demo project has support for it already and it is as simple to use as the following:

resp = ida.pythonTest("reply('A'*1001)")



*This feels a little sloppy and slow, but I only have limited time and just need to get things done plus python is already loaded and installed with IDA. End of the day the C embedding was implemented in 60 lines of code, less than two hours time, and makes hundreds of new API available to me at zero additional cost. You cant ignore leverage like that.




Comments: (0)

 
Leave Comment:
Name:
Email: (not shown)
Message: (Required)
 



Twitter
RSS

About Me
More Blogs
Main Site
Posts:
IDA python over IPC
dns wildcard blocking
64bit IDA Plugins
Twitter Feed
anterior lines
misc news/updates
KANAL Mod
Decoders again
CDO.Message Breakpoints
SysAnalyzer Updates
SysAnalyzer and Site Updates
crazy decoder
ida js w/dbg
flash patching #2
JS Graphing
packet reassembly
Delphi IDA Plugin
scdbg IDA integration
API Hash Database
Winmerge plugin
IDACompare Updates
Guest Post @ hexblog
TCP Stream Reassembly
SysAnalyzer Updates
Apilogger Video
Shellcode2Exe trainer
scdbg updates
IDA Javascript w/IDE
Rop Analysis II
scdbg vrs ROP
flash patching
x64 Hooks
micro hook
jmp api+5 *2
SysAnalyzer Updates
InjDll runtime config
C# Asm/Dsm Library
Shellcode Hook Detection
Updates II
findDll
Java Hacking
Windows 8
Win7 x64
Graphing ideas
.Net Hacking
Old iDefense Releases
BootLoaders
hll shellcode
ActionScript Tips
-patch fu
scdbg ordinal lookup
scdbg -api mode
Peb Module Lists
scdbg vrs Process Injection
GetProcAddress Scanner
scdbg fopen mode
scdbg findsc mode
scdbg MemMonitor
demo shellcodes
scdbg download
api hashs redux
Api hash gen
Retro XSS Chat Codes
Exe as DLL
Olly Plugins
Debugging Explorer
Attach to hidden process
JS Refactoring
Asm and Shellcode in CSharp
Fancy Return Address
PDF Stream Dumper
Malcode Call API by Hash
WinDbg Cheat Sheet
GPG Automation