diff --git a/python/idc.py b/python/idc.py index 7bcfc64..f64c613 100644 --- a/python/idc.py +++ b/python/idc.py @@ -2418,10 +2418,7 @@ def GetLongPrm(offset): val = _IDC_GetAttr(idaapi.cvar.inf, _INFMAP, offset) if offset == INF_PROCNAME: # procName is a character array - # strip it at the terminating zero - idx = val.find('\0') - if idx != -1: - val = val[:idx] + val = idaapi.as_cstr(val) return val def GetShortPrm(offset): diff --git a/pywraps.hpp b/pywraps.hpp index 14c4726..caa84bd 100644 --- a/pywraps.hpp +++ b/pywraps.hpp @@ -155,7 +155,7 @@ Py_ssize_t pyvar_walk_list( PyObject *PyW_IntVecToPyList(const intvec_t &intvec); // Converts an Python list to an intvec -void PyW_PyListToIntVec(PyObject *py_list, intvec_t &intvec); +bool PyW_PyListToIntVec(PyObject *py_list, intvec_t &intvec); // Returns a reference to a class PyObject *get_idaapi_attr(const char *attr); diff --git a/swig/dbg.i b/swig/dbg.i index e9841b1..f823c97 100644 --- a/swig/dbg.i +++ b/swig/dbg.i @@ -6,7 +6,13 @@ typedef struct } regval_t; %ignore dbg; +%ignore register_srcinfo_provider; +%ignore unregister_srcinfo_provider; +%ignore appcall_info_t; %ignore get_manual_regions; +%ignore internal_appcall; +%ignore internal_cleanup_appcall; + %ignore source_file_t; %ignore source_item_t; %ignore srcinfo_provider_t; @@ -15,6 +21,7 @@ typedef struct %ignore bpt_t::eval_cond; %ignore bpt_t::write; %ignore bpt_t::erase; +%ignore bpt_t::cndbody; %rename (get_manual_regions) py_get_manual_regions; %ignore set_manual_regions; %ignore inform_idc_about_debthread; @@ -28,6 +35,22 @@ static PyObject *meminfo_vec_t_to_py(meminfo_vec_t &areas); // %} +%extend bpt_t +{ + PyObject *condition; +} +%{ +PyObject *bpt_t_condition_get(bpt_t *bpt) +{ + return PyString_FromString(bpt->cndbody.c_str()); +} + +void bpt_t_condition_set(bpt_t *bpt, PyObject *val) +{ + if ( PyString_Check(val) ) + bpt->cndbody = PyString_AsString(val); +} +%} %inline %{ // diff --git a/swig/funcs.i b/swig/funcs.i index 4551eb7..fe4affe 100644 --- a/swig/funcs.i +++ b/swig/funcs.i @@ -3,7 +3,6 @@ // FIXME: Are these really useful? %ignore iterate_func_chunks; -%ignore get_idasgn_desc; %ignore get_idasgn_header_by_short_name; // Kernel-only & unexported symbols @@ -27,8 +26,13 @@ %ignore create_func_eas_array; %ignore auto_add_func_tails; %ignore read_tails; + +%ignore get_idasgn_desc; %rename (get_idasgn_desc) py_get_idasgn_desc; +%ignore get_func_cmt; +%rename (get_func_cmt) py_get_func_cmt; + %include "funcs.hpp" %clear(char *buf); @@ -65,9 +69,10 @@ def get_idasgn_desc(n): @param n: number of signature in the list (0..get_idasgn_qty()-1) @return: None on failure or tuple(signame, optlibs) """ + pass # */ -static PyObject *ida_export py_get_idasgn_desc(int n) +static PyObject *py_get_idasgn_desc(int n) { char signame[MAXSTR]; char optlibs[MAXSTR]; @@ -78,4 +83,31 @@ static PyObject *ida_export py_get_idasgn_desc(int n) return Py_BuildValue("(ss)", signame, optlibs); } +//----------------------------------------------------------------------- +/* +# +def get_func_cmt(fn, repeatable): + """ + Retrieve function comment + @param fn: function instance + @param repeatable: retrieve repeatable or non-repeatable comments + @return: None on failure or the comment + """ + pass +# +*/ +static PyObject *py_get_func_cmt(func_t *fn, bool repeatable) +{ + char *s = get_func_cmt(fn, repeatable); + if ( s == NULL ) + { + Py_RETURN_NONE; + } + else + { + PyObject *py_s = PyString_FromString(s); + qfree(s); + return py_s; + } +} %} diff --git a/swig/graph.i b/swig/graph.i index 9367237..cfa8f58 100644 --- a/swig/graph.i +++ b/swig/graph.i @@ -407,7 +407,7 @@ private: } // a graph viewer lost focus - void on_lostfocus(graph_viewer_t *gv) + void on_lostfocus(graph_viewer_t * /*gv*/) { PYW_GIL_ENSURE; PyObject *result = PyObject_CallMethod( @@ -700,7 +700,7 @@ private: self = NULL; } - static void SelectNode(PyObject *self, int nid) + static void SelectNode(PyObject *self, int /*nid*/) { py_graph_t *_this = extract_this(self); if ( _this == NULL || _this->form == NULL ) diff --git a/swig/idaapi.i b/swig/idaapi.i index e4e92e7..764a9ef 100644 --- a/swig/idaapi.i +++ b/swig/idaapi.i @@ -153,7 +153,7 @@ class pycvt_t else if ( (ft > FT_FIRST_NUM && ft < FT_LAST_NUM) && PyW_GetNumber(py_attr, &val.u64) ) ; // nothing to be done // A string array? - else if ( (ft == FT_STRARR || ft == FT_NUM16ARR || FT_CHRARR_STATIC ) + else if ( (ft == FT_STRARR || ft == FT_NUM16ARR || ft == FT_CHRARR_STATIC ) && (PyList_CheckExact(py_attr) || PyW_IsSequenceType(py_attr)) ) { // Return a reference to the attribute @@ -492,7 +492,7 @@ PyObject *PyW_IntVecToPyList(const intvec_t &intvec) //--------------------------------------------------------------------------- static int idaapi pylist_to_intvec_cb( PyObject *py_item, - Py_ssize_t index, + Py_ssize_t /*index*/, void *ud) { intvec_t &intvec = *(intvec_t *)ud; @@ -504,10 +504,10 @@ static int idaapi pylist_to_intvec_cb( return CIP_OK; } -void PyW_PyListToIntVec(PyObject *py_list, intvec_t &intvec) +bool PyW_PyListToIntVec(PyObject *py_list, intvec_t &intvec) { intvec.clear(); - (void)pyvar_walk_list(py_list, pylist_to_intvec_cb, &intvec); + return pyvar_walk_list(py_list, pylist_to_intvec_cb, &intvec) != CIP_FAILED; } //--------------------------------------------------------------------------- @@ -1207,9 +1207,9 @@ int pyvar_to_idcvar( idc_var->set_int64(PyLong_AsLongLong(attr)); Py_DECREF(attr); return CIP_OK; - // - // BYREF - // + // + // BYREF + // case PY_ICID_BYREF: { // BYREF always require this parameter @@ -1822,6 +1822,7 @@ import struct import traceback import os import sys +import bisect import __builtin__ # ----------------------------------------------------------------------- @@ -1852,6 +1853,13 @@ PY_ICID_BYREF = 1 PY_ICID_OPAQUE = 2 """opaque object""" +# Step trace options (used with set_step_trace_options()) +ST_OVER_DEBUG_SEG = 0x01 +"""step tracing will be disabled when IP is in a debugger segment""" + +ST_OVER_LIB_FUNC = 0x02 +"""step tracing will be disabled when IP is in a library function""" + # ----------------------------------------------------------------------- class pyidc_opaque_object_t(object): """This is the base class for all Python<->IDC opaque objects""" diff --git a/swig/idd.i b/swig/idd.i index 9b7a7d7..36322b5 100644 --- a/swig/idd.i +++ b/swig/idd.i @@ -1,5 +1,9 @@ %ignore debugger_t; %ignore memory_info_t; +%ignore lowcnd_t; +%ignore lowcnd_vec_t; +%ignore update_bpt_info_t; +%ignore update_bpt_vec_t; %ignore register_info_t; %ignore appcall; %ignore idd_opinfo_t; @@ -355,7 +359,8 @@ static PyObject *dbg_get_name() { if ( dbg == NULL ) Py_RETURN_NONE; - return PyString_FromString(dbg->name); + else + return PyString_FromString(dbg->name); } //------------------------------------------------------------------------- diff --git a/swig/idp.i b/swig/idp.i index f88b046..f04e29c 100644 --- a/swig/idp.i +++ b/swig/idp.i @@ -421,8 +421,7 @@ static PyObject *ph_get_operand_info( // Allocate register space thid_t tid = get_current_thread(); regvals_t regvalues; - regvalues.reserve(dbg->registers_size); - + regvalues.resize(dbg->registers_size); // Read registers if ( dbg->read_registers(tid, -1, regvalues.begin()) != 1 ) break; @@ -809,22 +808,22 @@ public: return 0; } - virtual int is_call_insn(ea_t ea) + virtual int is_call_insn(ea_t /*ea*/) { return 0; } - virtual int is_ret_insn(ea_t ea, bool strict) + virtual int is_ret_insn(ea_t /*ea*/, bool /*strict*/) { return 0; } virtual PyObject *assemble( - ea_t ea, - ea_t cs, - ea_t ip, - bool use32, - const char *line) + ea_t /*ea*/, + ea_t /*cs*/, + ea_t /*ip*/, + bool /*use32*/, + const char * /*line*/) { return NULL; } @@ -1070,9 +1069,9 @@ int idaapi IDP_Callback(void *ud, int notification_code, va_list va) } } } - catch (Swig::DirectorException &) + catch (Swig::DirectorException &e) { - msg("Exception in IDP Hook function:\n"); + msg("Exception in IDP Hook function: %s\n", e.getMessage()); if ( PyErr_Occurred() ) PyErr_Print(); } @@ -1249,9 +1248,9 @@ int idaapi IDB_Callback(void *ud, int notification_code, va_list va) return proxy->segm_moved(ea, ea2, size); } } - catch (Swig::DirectorException &) + catch (Swig::DirectorException &e) { - msg("Exception in IDB Hook function:\n"); + msg("Exception in IDB Hook function: %s\n", e.getMessage()); if (PyErr_Occurred()) { PyErr_Print(); diff --git a/swig/kernwin.i b/swig/kernwin.i index 0f8beca..1b8d4ff 100644 --- a/swig/kernwin.i +++ b/swig/kernwin.i @@ -11,6 +11,10 @@ %rename (del_menu_item) py_del_menu_item; %ignore vwarning; +%ignore choose_idasgn; +%rename (choose_idasgn) py_choose_idasgn; + + %ignore msg; %rename (msg) py_msg; @@ -105,7 +109,22 @@ void refresh_lists(void) %inline %{ // + //------------------------------------------------------------------------ +static PyObject *py_choose_idasgn() +{ + char *name = choose_idasgn(); + if ( name == NULL ) + { + Py_RETURN_NONE; + } + else + { + PyObject *py_str = PyString_FromString(name); + qfree(name); + return py_str; + } +} //------------------------------------------------------------------------ /* @@ -416,6 +435,7 @@ class UI_Hooks(object): @return: Ignored """ + pass # */ @@ -436,7 +456,7 @@ public: return unhook_from_notification_point(HT_UI, UI_Callback, this); } - virtual int preprocess(const char *name) + virtual int preprocess(const char * /*name*/) { return 0; } @@ -467,9 +487,9 @@ char *idaapi choose_getl(void *self, uint32 n, char *buf) { PYW_GIL_ENSURE; PyObject *pyres = PyObject_CallMethod( - (PyObject *)self, - "getl", - "l", + (PyObject *)self, + "getl", + "l", n); PYW_GIL_RELEASE; @@ -478,7 +498,7 @@ char *idaapi choose_getl(void *self, uint32 n, char *buf) qstrncpy(buf, "", MAXSTR); else qstrncpy(buf, res, MAXSTR); - + Py_XDECREF(pyres); return buf; } @@ -586,18 +606,6 @@ static void formchgcbfa_refresh_field(size_t p_fa, int fid) return fa->refresh_field(fid); } -//--------------------------------------------------------------------------- -static void formchgcbfa_set_field_value( - size_t p_fa, - int fid, - int ft, - PyObject *py_val, - size_t sz) -{ - DECLARE_FORM_ACTIONS; - return fa->refresh_field(fid); -} - //--------------------------------------------------------------------------- static PyObject *formchgcbfa_get_field_value( size_t p_fa, @@ -609,7 +617,7 @@ static PyObject *formchgcbfa_get_field_value( switch ( ft ) { // button - uint32 - case 4: + case 4: { uint32 val; if ( fa->get_field_value(fid, &val) ) @@ -617,7 +625,7 @@ static PyObject *formchgcbfa_get_field_value( break; } // ushort - case 2: + case 2: { ushort val; if ( fa->get_field_value(fid, &val) ) @@ -625,7 +633,7 @@ static PyObject *formchgcbfa_get_field_value( break; } // string label - case 1: + case 1: { char val[MAXSTR]; if ( fa->get_field_value(fid, val) ) @@ -633,7 +641,7 @@ static PyObject *formchgcbfa_get_field_value( break; } // string input - case 3: + case 3: { qstring val; val.resize(sz + 1); @@ -641,7 +649,7 @@ static PyObject *formchgcbfa_get_field_value( return PyString_FromString(val.begin()); break; } - case 5: + case 5: { intvec_t intvec; // Returned as 1-base @@ -653,6 +661,54 @@ static PyObject *formchgcbfa_get_field_value( return PyW_IntVecToPyList(intvec); } + break; + } + // Numeric control + case 6: + { + union + { + sel_t sel; + sval_t sval; + uval_t uval; + ulonglong ull; + } u; + switch ( sz ) + { + case 'S': // sel_t + { + if ( fa->get_field_value(fid, &u.sel) ) + return Py_BuildValue(PY_FMT64, u.sel); + break; + } + // sval_t + case 'n': + case 'N': + case 'D': + case 'O': + case 'Y': + case 'H': + { + if ( fa->get_field_value(fid, &u.sval) ) + return Py_BuildValue(PY_SFMT64, u.sval); + break; + } + case 'L': // uint64 + case 'l': // int64 + { + if ( fa->get_field_value(fid, &u.ull) ) + return Py_BuildValue(sz == 'L' ? "K" : "L", u.ull); + break; + } + case 'M': // uval_t + case '$': // ea_t + { + if ( fa->get_field_value(fid, &u.uval) ) + return Py_BuildValue(PY_FMT64, u.uval); + break; + } + } + break; } } Py_RETURN_NONE; @@ -670,39 +726,44 @@ static bool formchgcbfa_set_field_value( switch ( ft ) { // button - uint32 - case 4: + case 4: { uint32 val = PyLong_AsUnsignedLong(py_val); return fa->set_field_value(fid, &val); } // ushort - case 2: + case 2: { ushort val = PyLong_AsUnsignedLong(py_val) & 0xffff; return fa->set_field_value(fid, &val); } // strings - case 3: - case 1: + case 3: + case 1: return fa->set_field_value(fid, PyString_AsString(py_val)); // intvec_t - case 5: + case 5: { intvec_t intvec; // Passed as 0-based - PyW_PyListToIntVec(py_val, intvec); + if ( !PyW_PyListToIntVec(py_val, intvec) ) + break; // Make 1-based for ( intvec_t::iterator it=intvec.begin(); it != intvec.end(); ++it) (*it)++; - bool ok = fa->set_field_value(fid, &intvec); - return ok; + return fa->set_field_value(fid, &intvec); + } + // Numeric + case 6: + { + uint64 num; + if ( PyW_GetNumber(py_val, &num) ) + return fa->set_field_value(fid, &num); } - // unknown - default: - return false; } + return false; } #undef DECLARE_FORM_ACTIONS @@ -739,9 +800,9 @@ int idaapi UI_Callback(void *ud, int notification_code, va_list va) break; } } - catch (Swig::DirectorException &) + catch (Swig::DirectorException &e) { - msg("Exception in UI Hook function:\n"); + msg("Exception in UI Hook function: %s\n", e.getMessage()); if ( PyErr_Occurred() ) PyErr_Print(); } @@ -768,7 +829,7 @@ bool idaapi py_menu_item_callback(void *userdata) return false; } - bool ret = PyObject_IsTrue(result); + bool ret = PyObject_IsTrue(result) != 0; Py_DECREF(result); return ret; } @@ -2331,7 +2392,7 @@ private: } // The user clicked - static bool idaapi s_cv_click(TCustomControl *cv, int shift, void *ud) + static bool idaapi s_cv_click(TCustomControl * /*cv*/, int shift, void *ud) { customviewer_t *_this = (customviewer_t *)ud; return _this->on_click(shift); @@ -3675,7 +3736,7 @@ class Form(object): def __init__(self, tp, value): cls = Form.fieldtype_to_ctype(tp, self.DefI64) if cls is None: - raise TypeError("Invalid field type: %s" % tp) + raise TypeError("Invalid numeric field type: %s" % tp) # Get a pointer type to the ctype type self.arg = pointer(cls(value)) @@ -4566,7 +4627,7 @@ class Form(object): Converts a control object to a tuple containing the field id and the associated buffer size """ - # Input control depend on the associate buffer size (supplied by the user) + # Input control depend on the associated buffer size (supplied by the user) # Make sure you check instances types taking into account inheritance if isinstance(ctrl, Form.EmbeddedChooserControl): @@ -4578,6 +4639,9 @@ class Form(object): return (3, min(_idaapi.MAXSTR, ctrl.size)) elif isinstance(ctrl, Form.ColorInput): return (4, 0) + elif isinstance(ctrl, Form.NumericInput): + # Pass the numeric control type + return (6, ord(ctrl.tp[0])) elif isinstance(ctrl, Form.InputControl): return (1, ctrl.size) else: diff --git a/swig/name.i b/swig/name.i index 94c47ed..3c3e45d 100644 --- a/swig/name.i +++ b/swig/name.i @@ -11,7 +11,6 @@ %ignore get_struct_operand; %ignore set_debug_names; %ignore get_debug_name; -%ignore get_debug_names; %ignore nameVa; // Unexported & kernel-only @@ -31,8 +30,11 @@ %ignore is_exit_name; %ignore dummy_name_ea; +%ignore get_debug_names; %rename (get_debug_names) py_get_debug_names; %inline %{ +// +//------------------------------------------------------------------------ PyObject *py_get_debug_names(ea_t ea1, ea_t ea2) { // Get debug names @@ -50,11 +52,12 @@ PyObject *py_get_debug_names(ea_t ea1, ea_t ea2) } return dict; } +//------------------------------------------------------------------------ +// %} %pythoncode %{ - -import bisect +# class NearestName: """ @@ -103,5 +106,6 @@ class NearestName: raise StopIteration return self._get_item(index) +# %} %include "name.hpp" diff --git a/swig/pro.i b/swig/pro.i index 85cb2cf..ba77de3 100644 --- a/swig/pro.i +++ b/swig/pro.i @@ -8,6 +8,8 @@ %ignore reloc_info_t; // swig under mac chokes on this %ignore qmutex_create; +%ignore qiterator; +%ignore qrefcnt_t; %ignore qmutex_free; %ignore qmutex_lock; %ignore qmutex_t; diff --git a/swig/struct.i b/swig/struct.i index 0a13f55..b97c40c 100644 --- a/swig/struct.i +++ b/swig/struct.i @@ -9,6 +9,6 @@ // Add a get_member() member function to struc_t. // This helps to access the members array in the class. %extend struc_t { - member_t * get_member(int index) { return &(self->members[index]); } + member_t *get_member(int index) { return &(self->members[index]); } } diff --git a/swig/typeconv.i b/swig/typeconv.i index 13c9cc5..b0dbb72 100644 --- a/swig/typeconv.i +++ b/swig/typeconv.i @@ -1,20 +1,20 @@ -// Convert an incoming Python list to a tid_t[] array +// Convert an incoming Python list to a tid_t[] array %typemap(in) tid_t[ANY](tid_t temp[$1_dim0]) { int i, len; - if (!PySequence_Check($input)) + if (!PySequence_Check($input)) { PyErr_SetString(PyExc_TypeError,"Expecting a sequence"); return NULL; } - /* Cap the number of elements to copy */ + /* Cap the number of elements to copy */ len = PySequence_Length($input) < $1_dim0 ? PySequence_Length($input) : $1_dim0; - for (i =0; i < len; i++) + for (i =0; i < len; i++) { PyObject *o = PySequence_GetItem($input,i); - if (!PyLong_Check(o)) + if (!PyLong_Check(o)) { Py_XDECREF(o); PyErr_SetString(PyExc_ValueError,"Expecting a sequence of long integers"); @@ -32,11 +32,7 @@ $1 = MAXSTR; } %typemap(in,numinputs=0) (TYPEMAP, SIZE) { -#ifdef __cplusplus - $1 = ($1_ltype) new char[MAXSTR+1]; -#else - $1 = ($1_ltype) malloc(MAXSTR+1); -#endif + $1 = ($1_ltype) qalloc(MAXSTR+1); } %typemap(out) ssize_t { /* REMOVING ssize_t return value in $symname */ @@ -51,11 +47,7 @@ Py_INCREF(Py_None); resultobj = Py_None; } -#ifdef __cplusplus - delete [] $1; -#else - free($1); -#endif + qfree($1); } %enddef @@ -85,11 +77,7 @@ $1 = MAXSPECSIZE; } %typemap(in,numinputs=0) (TYPEMAP, SIZE) { -#ifdef __cplusplus - $1 = (char *) new char[MAXSPECSIZE+1]; -#else - $1 = (char *) malloc(MAXSPECSIZE+1); -#endif + $1 = (char *) qalloc(MAXSPECSIZE+1); } %typemap(out) ssize_t { /* REMOVING ssize_t return value in $symname */ @@ -104,11 +92,7 @@ Py_INCREF(Py_None); resultobj = Py_None; } -#ifdef __cplusplus - delete [] (char *)$1; -#else - free((char *)$1); -#endif + qfree((void *)$1); } %enddef @@ -118,11 +102,7 @@ $1 = &ressize; } %typemap(in,numinputs=0) (TYPEMAP, SIZE) { -#ifdef __cplusplus - $1 = (char *) new char[MAXSPECSIZE+1]; -#else - $1 = (char *) malloc(MAXSPECSIZE+1); -#endif + $1 = (char *) qalloc(MAXSPECSIZE+1); } %typemap(out) ssize_t { /* REMOVING ssize_t return value in $symname */ @@ -137,11 +117,7 @@ Py_INCREF(Py_None); resultobj = Py_None; } -#ifdef __cplusplus - delete [] (char *)$1; -#else - free((char *)$1); -#endif + qfree((void *)$1); } %enddef diff --git a/swig/typeinf.i b/swig/typeinf.i index 75e57ce..f250a88 100644 --- a/swig/typeinf.i +++ b/swig/typeinf.i @@ -150,6 +150,10 @@ %ignore regobj_t; %ignore build_func_type; +%ignore append_type_name; +%ignore for_all_types_ex; +%ignore pdb2ti; + %include "typeinf.hpp" // Custom wrappers diff --git a/swig/ua.i b/swig/ua.i index bf7b659..8793ac2 100644 --- a/swig/ua.i +++ b/swig/ua.i @@ -414,7 +414,7 @@ static PyObject *py_get_global_cmd_link() } //------------------------------------------------------------------------- -PyObject *insn_t_is_canon_insn(int itype) +static PyObject *insn_t_is_canon_insn(int itype) { if ( ph.is_canon_insn(itype) ) Py_RETURN_TRUE; @@ -423,13 +423,13 @@ PyObject *insn_t_is_canon_insn(int itype) } //------------------------------------------------------------------------- -PyObject *insn_t_get_canon_feature(int itype) +static PyObject *insn_t_get_canon_feature(int itype) { return Py_BuildValue("I", ph.is_canon_insn(itype) ? ph.instruc[itype-ph.instruc_start].feature : 0); } //------------------------------------------------------------------------- -PyObject *insn_t_get_canon_mnem(int itype) +static PyObject *insn_t_get_canon_mnem(int itype) { if ( ph.is_canon_insn(itype) ) return Py_BuildValue("s", ph.instruc[itype-ph.instruc_start].name);