diff --git a/python/idautils.py b/python/idautils.py index ca9aeb5..0d11320 100644 --- a/python/idautils.py +++ b/python/idautils.py @@ -13,6 +13,7 @@ idautils.py - High level utility functions for IDA """ import idaapi import idc +import types def refs(ea, funcfirst, funcnext): """ @@ -427,4 +428,45 @@ class Strings: return Strings.StringItem(self._si) return None + +def _Assemble(ea, line): + """ + Please refer to Assemble() - INTERNAL USE ONLY + """ + if type(line) == types.StringType: + lines = [line] + else: + lines = line + ret = [] + for line in lines: + seg = idaapi.getseg(ea) + if not seg: + return (False, "No segment at ea") + ip = ea - (idaapi.ask_selector(seg.sel) << 4) + buf = idaapi.AssembleLine(ea, seg.sel, ip, seg.bitness, line) + if not buf: + return (False, "Assembler failed: " + line) + ea += len(buf) + ret.append(buf) + + if len(ret) == 1: + ret = ret[0] + return (True, ret) + + +def Assemble(ea, line): + """ + Assembles one or more lines (does not display an message dialogs) + If line is a list then this function will attempt to assemble all the lines + This function will turn on batch mode temporarily so that no messages are displayed on the screen + + @param ea: start address + @return: (False, "Error message") or (True, asm_buf) or (True, [asm_buf1, asm_buf2, asm_buf3]) + """ + old_batch = idc.Batch(1) + ret = _Assemble(ea, line) + idc.Batch(old_batch) + return ret + + cpu = _cpu() diff --git a/swig/idp.i b/swig/idp.i index b052b66..c3dc8e4 100644 --- a/swig/idp.i +++ b/swig/idp.i @@ -279,7 +279,7 @@ int idaapi IDB_Callback(void *ud, int notification_code, va_list va) } } -// Assemble an instruction (display a warning if an error is found) +// Assemble an instruction into the database (display a warning if an error is found) // args: // ea_t ea - linear address of instruction // ea_t cs - cs of instruction @@ -290,7 +290,7 @@ int idaapi IDB_Callback(void *ud, int notification_code, va_list va) inline const int assemble(ea_t ea, ea_t cs, ea_t ip, bool use32, const char *line) { int inslen; - char buf[256]; // FIXME: Shouldn't be longer than this... is there a MAX_INSTR_LENGTH anywhere? + char buf[MAXSTR]; if (ph.notify != NULL) { @@ -303,4 +303,24 @@ inline const int assemble(ea_t ea, ea_t cs, ea_t ip, bool use32, const char *lin } return 0; } + +// Assemble an instruction to a buffer (display a warning if an error is found) +// args: +// ea_t ea - linear address of instruction +// ea_t cs - cs of instruction +// ea_t ip - ip of instruction +// bool use32 - is 32bit segment? +// const char *line - line to assemble +// returns: 1: success, 0: failure +inline const PyObject *AssembleLine(ea_t ea, ea_t cs, ea_t ip, bool use32, const char *line) +{ + int inslen; + char buf[MAXSTR]; + if (ph.notify != NULL && + (inslen = ph.notify(ph.assemble, ea, cs, ip, use32, line, buf)) > 0) + { + return PyString_FromStringAndSize(buf, inslen); + } + Py_RETURN_NONE; +} %}