mirror of
https://github.com/cemu-project/idapython.git
synced 2024-12-28 02:31:53 +01:00
- some code cleanup
- added idaapi. struct_unpack / copy_bits / as_signed utility functions - added pywraps.hpp utility header
This commit is contained in:
parent
33c93df0cf
commit
b935e24aba
82
pywraps.hpp
Normal file
82
pywraps.hpp
Normal file
@ -0,0 +1,82 @@
|
||||
#ifndef __PYWRAPS_HPP__
|
||||
#define __PYWRAPS_HPP__
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Types
|
||||
#ifndef PYUL_DEFINED
|
||||
#define PYUL_DEFINED
|
||||
#ifdef __EA64__
|
||||
typedef unsigned PY_LONG_LONG pyul_t;
|
||||
#else
|
||||
typedef unsigned long pyul_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __EA64__
|
||||
#define PY_FMT64 "K"
|
||||
#else
|
||||
#define PY_FMT64 "k"
|
||||
#endif
|
||||
|
||||
// Vector of PyObject*
|
||||
typedef qvector<PyObject *> ppyobject_vec_t;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// PyIdc conversion object IDs
|
||||
#define PY_ICID_INT64 0
|
||||
#define PY_ICID_BYREF 1
|
||||
#define PY_ICID_OPAQUE 2
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Constants used by the pyvar_to_idcvar and idcvar_to_pyvar functions
|
||||
#define CIP_FAILED -1 // Conversion error
|
||||
#define CIP_IMMUTABLE 0 // Immutable object passed. Will not update the object but no error occured
|
||||
#define CIP_OK 1 // Success
|
||||
#define CIP_OK_NODECREF 2 // Success but do not decrement its reference
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// All the exported functions from PyWraps are forward declared here
|
||||
|
||||
// Tries to import a module and swallows the exception if it fails and returns NULL
|
||||
PyObject *PyImport_TryImportModule(const char *name);
|
||||
|
||||
// Tries to get an attribute and swallows the exception if it fails and returns NULL
|
||||
PyObject *PyObject_TryGetAttrString(PyObject *py_var, const char *attr);
|
||||
|
||||
// Converts a Python number (LONGLONG or normal integer) to an IDC variable (VT_LONG or VT_INT64)
|
||||
bool PyGetNumberAsIDC(PyObject *py_var, idc_value_t *idc_var);
|
||||
|
||||
// Converts a Python number to an uint64 and indicates whether the number was a long number
|
||||
bool PyGetNumber(PyObject *py_var, uint64 *num, bool *is_64 = NULL);
|
||||
|
||||
// Checks if an Python object can be treated like a sequence
|
||||
bool PyIsSequenceType(PyObject *obj);
|
||||
|
||||
// Returns an error string from the last exception (and clears it)
|
||||
bool PyGetError(qstring *out = NULL);
|
||||
|
||||
// If an error occured (it calls PyGetError) it displays it and return TRUE
|
||||
bool PyShowErr(const char *cb_name);
|
||||
|
||||
// [De]Initializes PyWraps
|
||||
bool init_pywraps();
|
||||
void deinit_pywraps();
|
||||
|
||||
// Returns the string representation of a PyObject
|
||||
bool PyObjectToString(PyObject *obj, qstring *out);
|
||||
|
||||
// Converts Python variable to IDC variable
|
||||
// gvar_sn is used in case the Python object was a created from a call to idcvar_to_pyvar and the IDC object was a VT_REF
|
||||
int pyvar_to_idcvar(
|
||||
PyObject *py_var,
|
||||
idc_value_t *idc_var,
|
||||
int *gvar_sn = NULL);
|
||||
|
||||
// Converts from IDC to Python
|
||||
// We support converting VT_REF IDC variable types
|
||||
int idcvar_to_pyvar(
|
||||
const idc_value_t &idc_var,
|
||||
PyObject **py_var);
|
||||
|
||||
|
||||
#endif
|
252
swig/idaapi.i
252
swig/idaapi.i
@ -55,45 +55,82 @@
|
||||
|
||||
//<code(py_idaapi)>
|
||||
|
||||
#ifndef PYUL_DEFINED
|
||||
#define PYUL_DEFINED
|
||||
typedef unsigned PY_LONG_LONG pyul_t;
|
||||
#include "pywraps.hpp"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// String constants used
|
||||
static const char PY_IDC_CLASS_NAME[] = "py_idc_object_class";
|
||||
static const char PY_IDC_GLOBAL_VAR_FMT[] = "__py_cvt_gvar_%d";
|
||||
static const char PY_IDCCVT_ID_ATTR[] = "__idc_cvt_id__";
|
||||
static const char PY_IDCCVT_VALUE_ATTR[] = "__idc_cvt_value__";
|
||||
static const char S_PY_IDC_OPAQUE_T[] = "py_idc_cvt_helper_t";
|
||||
static const char S_PROPS[] = "props";
|
||||
static const char S_NAME[] = "name";
|
||||
static const char S_ASM_KEYWORD[] = "asm_keyword";
|
||||
static const char S_MENU_NAME[] = "menu_name";
|
||||
static const char S_HOTKEY[] = "hotkey";
|
||||
static const char S_VALUE_SIZE[] = "value_size";
|
||||
static const char S_MAY_CREATE_AT[] = "may_create_at";
|
||||
static const char S_CALC_ITEM_SIZE[] = "calc_item_size";
|
||||
static const char S_ID[] = "id";
|
||||
static const char S_PRINTF[] = "printf";
|
||||
static const char S_TEXT_WIDTH[] = "text_width";
|
||||
static const char S_SCAN[] = "scan";
|
||||
static const char S_ANALYZE[] = "analyze";
|
||||
static const char S_CBSIZE[] = "cbsize";
|
||||
static const char S_ON_CLICK[] = "OnClick";
|
||||
static const char S_ON_CLOSE[] = "OnClose";
|
||||
static const char S_ON_DBL_CLICK[] = "OnDblClick";
|
||||
static const char S_ON_CURSOR_POS_CHANGED[] = "OnCursorPosChanged";
|
||||
static const char S_ON_KEYDOWN[] = "OnKeydown";
|
||||
static const char S_ON_POPUP[] = "OnPopup";
|
||||
static const char S_ON_HINT[] = "OnHint";
|
||||
static const char S_ON_POPUP_MENU[] = "OnPopupMenu";
|
||||
static const char S_ON_EDIT_LINE[] = "OnEditLine";
|
||||
static const char S_ON_INSERT_LINE[] = "OnInsertLine";
|
||||
static const char S_ON_GET_LINE[] = "OnGetLine";
|
||||
static const char S_ON_DELETE_LINE[] = "OnDeleteLine";
|
||||
static const char S_ON_REFRESH[] = "OnRefresh";
|
||||
static const char S_ON_SELECT_LINE[] = "OnSelectLine";
|
||||
static const char S_ON_COMMAND[] = "OnCommand";
|
||||
static const char S_ON_GET_ICON[] = "OnGetIcon";
|
||||
static const char S_ON_GET_LINE_ATTR[] = "OnGetLineAttr";
|
||||
static const char S_ON_GET_SIZE[] = "OnGetSize";
|
||||
static const char S_ON_GETTEXT[] = "OnGetText";
|
||||
static const char S_ON_ACTIVATE[] = "OnActivate";
|
||||
static const char S_ON_DEACTIVATE[] = "OnDeactivate";
|
||||
static const char S_ON_SELECT[] = "OnSelect";
|
||||
static const char S_M_EDGES[] = "_edges";
|
||||
static const char S_M_NODES[] = "_nodes";
|
||||
static const char S_M_THIS[] = "_this";
|
||||
static const char S_M_TITLE[] = "_title";
|
||||
|
||||
#ifdef __PYWRAPS__
|
||||
static const char S_PY_IDAAPI_MODNAME[] = "__main__";
|
||||
#else
|
||||
static const char S_PY_IDAAPI_MODNAME[] = "idaapi";
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
static const char PY_IDC_CLASS_NAME[] = "py_idc_object_class";
|
||||
static const char PY_IDC_GLOBAL_VAR_FMT[] = "__py_cvt_gvar_%d";
|
||||
static const char PY_IDCCVT_ID_ATTR[] = "__idc_cvt_id__";
|
||||
static const char PY_IDCCVT_VALUE_ATTR[] = "__idc_cvt_value__";
|
||||
static const char S_PY_IDC_OPAQUE_T[] = "py_idc_cvt_helper_t";
|
||||
|
||||
#ifndef __PYWRAPS__
|
||||
static const char S_PY_IDAAPI_MODNAME[] = "idaapi";
|
||||
#else
|
||||
static const char S_PY_IDAAPI_MODNAME[] = "__main__";
|
||||
#endif
|
||||
|
||||
// Constants used by get_idaapi_class_reference()
|
||||
#define PY_CLSID_CVT_INT64 0
|
||||
#define PY_CLSID_APPCALL_SKEL_OBJ 1
|
||||
#define PY_CLSID_CVT_BYREF 2
|
||||
#define PY_CLSID_LAST 3
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// PyIdc conversion object ids
|
||||
#define PY_ICID_INT64 0
|
||||
#define PY_ICID_BYREF 1
|
||||
#define PY_ICID_OPAQUE 2
|
||||
|
||||
static PyObject *py_cvt_helper_module = NULL;
|
||||
static bool pywraps_initialized = false;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
idc_class_t *get_py_idc_cvt_opaque()
|
||||
static idc_class_t *get_py_idc_cvt_opaque()
|
||||
{
|
||||
return find_idc_class(S_PY_IDC_OPAQUE_T);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// IDC Opaque object destructor: when the IDC object dies we kill the
|
||||
// opaque Python object along with it
|
||||
static const char py_idc_cvt_helper_dtor_args[] = { VT_OBJ, 0 };
|
||||
static error_t idaapi py_idc_opaque_dtor(
|
||||
idc_value_t *argv,
|
||||
@ -122,7 +159,7 @@ bool init_pywraps()
|
||||
if (py_cvt_helper_module == NULL)
|
||||
{
|
||||
// Take a reference to the module so we can create the needed class instances
|
||||
py_cvt_helper_module = PyImport_ImportModule(S_PY_IDAAPI_MODNAME);
|
||||
py_cvt_helper_module = PyImport_TryImportModule(S_PY_IDAAPI_MODNAME);
|
||||
if (py_cvt_helper_module == NULL)
|
||||
return false;
|
||||
}
|
||||
@ -175,7 +212,6 @@ static PyObject *get_idaapi_class_reference(const int class_id)
|
||||
"Appcall_object__",
|
||||
"PyIdc_cvt_refclass__"
|
||||
};
|
||||
|
||||
return PyObject_GetAttrString(py_cvt_helper_module, class_names[class_id]);
|
||||
}
|
||||
|
||||
@ -209,7 +245,7 @@ PyObject *PyImport_TryImportModule(const char *name)
|
||||
// converted to a VT_INT64 or not. For example: 2**32-1 = 0xffffffff which
|
||||
// can fit in a C long but Python creates a PyLong object for it.
|
||||
// And because of that we are confused as to whether to convert to 32 or 64
|
||||
bool PyGetNumber(PyObject *py_var, idc_value_t *idc_var)
|
||||
bool PyGetNumberAsIDC(PyObject *py_var, idc_value_t *idc_var)
|
||||
{
|
||||
if (!(PyInt_CheckExact(py_var) || PyLong_CheckExact(py_var)))
|
||||
return false;
|
||||
@ -235,6 +271,49 @@ bool PyGetNumber(PyObject *py_var, idc_value_t *idc_var)
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Parses a Python object as a long or long long
|
||||
bool PyGetNumber(PyObject *py_var, uint64 *num, bool *is_64)
|
||||
{
|
||||
if (!(PyInt_CheckExact(py_var) || PyLong_CheckExact(py_var)))
|
||||
return false;
|
||||
|
||||
// Can we convert to C long?
|
||||
long l = PyInt_AsLong(py_var);
|
||||
if (!PyErr_Occurred())
|
||||
{
|
||||
if (num != NULL)
|
||||
*num = uint64(l);
|
||||
if (is_64 != NULL)
|
||||
*is_64 = false;
|
||||
return true;
|
||||
}
|
||||
// Clear last error
|
||||
PyErr_Clear();
|
||||
// Can be fit into a C unsigned long?
|
||||
unsigned long ul = PyLong_AsUnsignedLong(py_var);
|
||||
if (!PyErr_Occurred())
|
||||
{
|
||||
if (num != NULL)
|
||||
*num = uint64(ul);
|
||||
if (is_64 != NULL)
|
||||
*is_64 = false;
|
||||
return true;
|
||||
}
|
||||
PyErr_Clear();
|
||||
PY_LONG_LONG ll = PyLong_AsLongLong(py_var);
|
||||
if (!PyErr_Occurred())
|
||||
{
|
||||
if (num != NULL)
|
||||
*num = uint64(ll);
|
||||
if (is_64 != NULL)
|
||||
*is_64 = true;
|
||||
return true;
|
||||
}
|
||||
PyErr_Clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Checks if a given object is of sequence type
|
||||
bool PyIsSequenceType(PyObject *obj)
|
||||
@ -271,10 +350,10 @@ bool PyObjectToString(PyObject *obj, qstring *out)
|
||||
//--------------------------------------------------------------------------
|
||||
// Checks if a Python error occured and fills the out parameter with the
|
||||
// exception string
|
||||
bool PyGetError(qstring *out = NULL)
|
||||
bool PyGetError(qstring *out)
|
||||
{
|
||||
PyObject *py_err;
|
||||
if ( (py_err = PyErr_Occurred()) == NULL)
|
||||
if ((py_err = PyErr_Occurred()) == NULL)
|
||||
return false;
|
||||
|
||||
PyObject *err_type, *err_value, *err_traceback;
|
||||
@ -284,6 +363,17 @@ bool PyGetError(qstring *out = NULL)
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// A loud version of PyGetError() which gets the error and displays it
|
||||
bool PyShowErr(const char *cb_name)
|
||||
{
|
||||
static qstring err_str;
|
||||
if (!PyGetError(&err_str))
|
||||
return false;
|
||||
warning("IDAPython: Error while calling Python callback <%s>:\n%s", cb_name, err_str.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Checks if the given py_var is a special PyIdc_cvt_helper object.
|
||||
// It does that by examining the magic attribute and returns its numeric value.
|
||||
@ -328,22 +418,19 @@ static bool create_py_idc_opaque_obj(PyObject *py_var, idc_value_t *idc_var)
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Converts a Python variable into an IDC variable
|
||||
// This function returns:
|
||||
// 0 - failure
|
||||
// 1 - success
|
||||
// 2 - success but do not decrement the reference of the py_var (used by opaque values)
|
||||
// This function returns on one CIP_XXXX
|
||||
int pyvar_to_idcvar(
|
||||
PyObject *py_var,
|
||||
idc_value_t *idc_var,
|
||||
int *gvar_sn = NULL)
|
||||
int *gvar_sn)
|
||||
{
|
||||
PyObject *attr;
|
||||
// None / NULL
|
||||
if (py_var == NULL || py_var == Py_None)
|
||||
idc_var->set_long(0);
|
||||
// Numbers?
|
||||
else if (PyGetNumber(py_var, idc_var))
|
||||
return 1;
|
||||
else if (PyGetNumberAsIDC(py_var, idc_var))
|
||||
return CIP_OK;
|
||||
// String
|
||||
else if (PyString_Check(py_var))
|
||||
idc_var->_set_string(PyString_AsString(py_var), PyString_Size(py_var));
|
||||
@ -360,6 +447,7 @@ int pyvar_to_idcvar(
|
||||
// void*
|
||||
else if (PyCObject_Check(py_var))
|
||||
idc_var->set_pvoid(PyCObject_AsVoidPtr(py_var));
|
||||
// Is it a Python list?
|
||||
else if (PyList_CheckExact(py_var) || PyIsSequenceType(py_var))
|
||||
{
|
||||
// Create the object
|
||||
@ -379,7 +467,7 @@ int pyvar_to_idcvar(
|
||||
|
||||
// Convert the item into an IDC variable
|
||||
idc_value_t v;
|
||||
ok = pyvar_to_idcvar(py_item, &v, gvar_sn) > 0;
|
||||
ok = pyvar_to_idcvar(py_item, &v, gvar_sn) >= CIP_OK;
|
||||
if (ok)
|
||||
{
|
||||
// Form the attribute name
|
||||
@ -397,7 +485,7 @@ int pyvar_to_idcvar(
|
||||
if (!ok)
|
||||
break;
|
||||
}
|
||||
return ok ? 1 : 0;
|
||||
return ok ? CIP_OK : CIP_FAILED;
|
||||
}
|
||||
// Dictionary: we convert to an IDC object
|
||||
else if (PyDict_Check(py_var))
|
||||
@ -426,7 +514,7 @@ int pyvar_to_idcvar(
|
||||
|
||||
// Convert the attribute into an IDC value
|
||||
idc_value_t v;
|
||||
ok = pyvar_to_idcvar(val, &v, gvar_sn) > 0;
|
||||
ok = pyvar_to_idcvar(val, &v, gvar_sn) >= CIP_OK;
|
||||
if (ok)
|
||||
{
|
||||
// Store the attribute
|
||||
@ -439,7 +527,15 @@ int pyvar_to_idcvar(
|
||||
}
|
||||
// Decrement attribute reference
|
||||
Py_DECREF(py_items);
|
||||
return ok ? 1 : 0;
|
||||
return ok ? CIP_OK : CIP_FAILED;
|
||||
}
|
||||
// Possible function?
|
||||
else if (PyCallable_Check(py_var))
|
||||
{
|
||||
idc_var->clear();
|
||||
idc_var->vtype = VT_FUNC;
|
||||
idc_var->funcidx = -1; // Does not apply
|
||||
return CIP_OK;
|
||||
}
|
||||
// Objects:
|
||||
// - pyidc_cvt objects: int64, byref, opaque
|
||||
@ -460,7 +556,7 @@ int pyvar_to_idcvar(
|
||||
return false;
|
||||
idc_var->set_int64(PyLong_AsLongLong(attr));
|
||||
Py_DECREF(attr);
|
||||
return 1;
|
||||
return CIP_OK;
|
||||
//
|
||||
// BYREF
|
||||
//
|
||||
@ -468,19 +564,19 @@ int pyvar_to_idcvar(
|
||||
{
|
||||
// BYREF always require this parameter
|
||||
if (gvar_sn == NULL)
|
||||
return 0;
|
||||
return CIP_FAILED;
|
||||
|
||||
// Get the value attribute
|
||||
attr = PyObject_TryGetAttrString(py_var, PY_IDCCVT_VALUE_ATTR);
|
||||
if (attr == NULL)
|
||||
return 0;
|
||||
return CIP_FAILED;
|
||||
|
||||
// Create a global variable
|
||||
char buf[MAXSTR];
|
||||
qsnprintf(buf, sizeof(buf), PY_IDC_GLOBAL_VAR_FMT, *gvar_sn);
|
||||
idc_value_t *gvar = add_idc_gvar(buf);
|
||||
// Convert the python value into the IDC global variable
|
||||
bool ok = pyvar_to_idcvar(attr, gvar, gvar_sn) > 0;
|
||||
bool ok = pyvar_to_idcvar(attr, gvar, gvar_sn) >= CIP_OK;
|
||||
if (ok)
|
||||
{
|
||||
(*gvar_sn)++;
|
||||
@ -488,7 +584,7 @@ int pyvar_to_idcvar(
|
||||
VarRef(idc_var, gvar);
|
||||
}
|
||||
Py_DECREF(attr);
|
||||
return ok ? 1 : 0;
|
||||
return ok ? CIP_OK : CIP_FAILED;
|
||||
}
|
||||
//
|
||||
// OPAQUE
|
||||
@ -496,8 +592,8 @@ int pyvar_to_idcvar(
|
||||
case PY_ICID_OPAQUE:
|
||||
{
|
||||
if (!create_py_idc_opaque_obj(py_var, idc_var))
|
||||
return 0;
|
||||
return 2; // do not decrement the reference
|
||||
return CIP_FAILED;
|
||||
return CIP_OK_NODECREF;
|
||||
}
|
||||
//
|
||||
// Other objects
|
||||
@ -509,7 +605,7 @@ int pyvar_to_idcvar(
|
||||
if (py_dir == NULL || !PyList_Check(py_dir) || size == 0)
|
||||
{
|
||||
Py_XDECREF(py_dir);
|
||||
return 0;
|
||||
return CIP_FAILED;
|
||||
}
|
||||
// Create the IDC object
|
||||
VarObject(idc_var);
|
||||
@ -532,10 +628,10 @@ int pyvar_to_idcvar(
|
||||
attr = PyObject_GetAttrString(py_var, field_name);
|
||||
if (attr == NULL
|
||||
// Convert the attribute into an IDC value
|
||||
|| pyvar_to_idcvar(attr, &v, gvar_sn) <= 0)
|
||||
|| pyvar_to_idcvar(attr, &v, gvar_sn) < CIP_OK)
|
||||
{
|
||||
Py_XDECREF(attr);
|
||||
return 0;
|
||||
return CIP_FAILED;
|
||||
}
|
||||
// Store the attribute
|
||||
VarSetAttr(idc_var, field_name, &v);
|
||||
@ -544,18 +640,14 @@ int pyvar_to_idcvar(
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
return CIP_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Converts an IDC variable to a Python variable
|
||||
// If py_var points to an existing object then the object will be updated
|
||||
// If py_var points to an existing immutable object then ZERO is returned
|
||||
// Return codes:
|
||||
#define CIP_FAILED -1 // Conversion error
|
||||
#define CIP_IMMUTABLE 0 // Immutable object passed. Will not update the object but no error occured
|
||||
#define CIP_OK 1 // Success
|
||||
#define CIP_OK_NODECREF 2 // Success but do not decrement its reference
|
||||
// Returns one of CIP_xxxx. Check pywraps.hpp
|
||||
int idcvar_to_pyvar(
|
||||
const idc_value_t &idc_var,
|
||||
PyObject **py_var)
|
||||
@ -588,9 +680,11 @@ int idcvar_to_pyvar(
|
||||
Py_DECREF(py_cls);
|
||||
break;
|
||||
}
|
||||
#if !defined(NO_OBSOLETE_FUNCS) || defined(__EXPR_SRC)
|
||||
case VT_STR:
|
||||
*py_var = PyString_FromString(idc_var.str);
|
||||
break;
|
||||
#endif
|
||||
case VT_STR2:
|
||||
if (*py_var == NULL)
|
||||
{
|
||||
@ -736,7 +830,7 @@ int idcvar_to_pyvar(
|
||||
%}
|
||||
|
||||
// Do not create separate wrappers for default arguments
|
||||
%feature("compactdefaultargs");
|
||||
%feature("compactdefaultargs");
|
||||
|
||||
#ifdef __EA64__
|
||||
#ifdef __GNUC__
|
||||
@ -783,7 +877,7 @@ typedef int error_t;
|
||||
%binary_output_or_none(void *buf, size_t bufsize);
|
||||
%binary_output_with_size(void *buf, size_t *bufsize);
|
||||
|
||||
// Accept single Python string for const void * + size input arguments
|
||||
// Accept single Python string for const void * + size input arguments
|
||||
// For example: put_many_bytes() and patch_many_bytes()
|
||||
%apply (char *STRING, int LENGTH) { (const void *buf, size_t size) };
|
||||
%apply (char *STRING, int LENGTH) { (const void *buf, size_t len) };
|
||||
@ -858,7 +952,7 @@ idainfo *get_inf_structure(void)
|
||||
|
||||
%pythoncode %{
|
||||
#<pycode(py_idaapi)>
|
||||
|
||||
import struct
|
||||
# -----------------------------------------------------------------------
|
||||
# Seek constants
|
||||
SEEK_SET = 0 # from the file start
|
||||
@ -971,6 +1065,52 @@ def as_uint32(v):
|
||||
def as_int32(v):
|
||||
return -((~v & 0xffffffff)+1)
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
def as_signed(v, nbits = 32):
|
||||
return -(( ~v & ((1 << nbits)-1) ) + 1) if v & (1 << nbits-1) else v
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Copy bits from a value
|
||||
def copy_bits(b, s, e=-1):
|
||||
# end-bit not specified? use start bit (thus extract one bit)
|
||||
if e == -1:
|
||||
e = s
|
||||
# swap start and end if start > end
|
||||
if s > e:
|
||||
e, s = s, e
|
||||
|
||||
mask = 0
|
||||
for i in xrange(s, e+1):
|
||||
mask |= 1 << i
|
||||
|
||||
return (b & mask) >> s
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
struct_unpack_table = {
|
||||
1: ('b', 'B'),
|
||||
2: ('h', 'H'),
|
||||
4: ('l', 'L'),
|
||||
8: ('q', 'Q')
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def struct_unpack(value, signed = False, offs = 0):
|
||||
"""
|
||||
Unpack a value given its length and offset using struct.unpack_from().
|
||||
This function will know how to unpack the given value by using the lookup table 'struct_unpack_table'
|
||||
"""
|
||||
# Supported length?
|
||||
n = len(value)
|
||||
if not n in struct_unpack_table:
|
||||
return None
|
||||
# Conver to number
|
||||
signed = 1 if signed else 0
|
||||
|
||||
# Unpack
|
||||
return struct.unpack_from(struct_unpack_table[n][signed], value, offs)[0]
|
||||
|
||||
|
||||
|
||||
#</pycode(py_idaapi)>
|
||||
|
||||
%}
|
@ -163,29 +163,6 @@ uint32 choose_choose(PyObject *self,
|
||||
#define thisobj ((py_choose2_t *) obj)
|
||||
#define thisdecl py_choose2_t *_this = thisobj
|
||||
#define MENU_COMMAND_CB(id) static uint32 idaapi s_menu_command_##id(void *obj, uint32 n) { return thisobj->on_command(id, int(n)); }
|
||||
#define DECL_MENU_COMMAND_CB(id) s_menu_command_##id
|
||||
#define S_ON_EDIT_LINE "OnEditLine"
|
||||
#define S_ON_INSERT_LINE "OnInsertLine"
|
||||
#define S_ON_GET_LINE "OnGetLine"
|
||||
#define S_ON_DELETE_LINE "OnDeleteLine"
|
||||
#define S_ON_REFRESH "OnRefresh"
|
||||
#define S_ON_SELECT_LINE "OnSelectLine"
|
||||
#define S_ON_COMMAND "OnCommand"
|
||||
#define S_ON_GET_ICON "OnGetIcon"
|
||||
#ifdef CH_ATTRS
|
||||
#define S_ON_GET_LINE_ATTR "OnGetLineAttr"
|
||||
#endif
|
||||
#define S_ON_GET_SIZE "OnGetSize"
|
||||
#define S_ON_CLOSE "OnClose"
|
||||
#define CHOOSE2_HAVE_DEL 0x0001
|
||||
#define CHOOSE2_HAVE_INS 0x0002
|
||||
#define CHOOSE2_HAVE_UPDATE 0x0004
|
||||
#define CHOOSE2_HAVE_EDIT 0x0008
|
||||
#define CHOOSE2_HAVE_ENTER 0x0010
|
||||
#define CHOOSE2_HAVE_GETICON 0x0020
|
||||
#define CHOOSE2_HAVE_GETATTR 0x0040
|
||||
#define CHOOSE2_HAVE_COMMAND 0x0080
|
||||
#define CHOOSE2_HAVE_ONCLOSE 0x0100
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Helper functions
|
||||
@ -217,6 +194,18 @@ void choose2_del_instance(PyObject *self)
|
||||
class py_choose2_t
|
||||
{
|
||||
private:
|
||||
enum
|
||||
{
|
||||
CHOOSE2_HAVE_DEL = 0x0001,
|
||||
CHOOSE2_HAVE_INS = 0x0002,
|
||||
CHOOSE2_HAVE_UPDATE = 0x0004,
|
||||
CHOOSE2_HAVE_EDIT = 0x0008,
|
||||
CHOOSE2_HAVE_ENTER = 0x0010,
|
||||
CHOOSE2_HAVE_GETICON = 0x0020,
|
||||
CHOOSE2_HAVE_GETATTR = 0x0040,
|
||||
CHOOSE2_HAVE_COMMAND = 0x0080,
|
||||
CHOOSE2_HAVE_ONCLOSE = 0x0100
|
||||
};
|
||||
int flags;
|
||||
int cb_flags;
|
||||
qstring title;
|
||||
@ -233,7 +222,6 @@ private:
|
||||
//------------------------------------------------------------------------
|
||||
// Static methods to dispatch to member functions
|
||||
//------------------------------------------------------------------------
|
||||
#ifdef CH_ATTRS
|
||||
static int idaapi ui_cb(void *obj, int notification_code, va_list va)
|
||||
{
|
||||
if ( notification_code != ui_get_chooser_item_attrs )
|
||||
@ -244,7 +232,6 @@ private:
|
||||
thisobj->on_get_line_attr(n, attr);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
static uint32 idaapi s_sizer(void *obj)
|
||||
{
|
||||
return (uint32)thisobj->on_get_size();
|
||||
@ -300,7 +287,7 @@ private:
|
||||
line_arr[i][0] = '\0';
|
||||
|
||||
// Call Python
|
||||
PyObject *list = PyObject_CallMethod(self, S_ON_GET_LINE, "l", lineno - 1);
|
||||
PyObject *list = PyObject_CallMethod(self, (char *)S_ON_GET_LINE, "i", lineno - 1);
|
||||
if (list == NULL)
|
||||
return;
|
||||
for (int i=ncols-1;i>=0;i--)
|
||||
@ -317,7 +304,7 @@ private:
|
||||
|
||||
size_t on_get_size()
|
||||
{
|
||||
PyObject *pyres = PyObject_CallMethod(self, S_ON_GET_SIZE, NULL);
|
||||
PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_GET_SIZE, NULL);
|
||||
if (pyres == NULL)
|
||||
return 0;
|
||||
size_t res = PyInt_AsLong(pyres);
|
||||
@ -332,7 +319,7 @@ private:
|
||||
unhook_from_notification_point(HT_UI, ui_cb, this);
|
||||
#endif
|
||||
// Call Python
|
||||
PyObject *pyres = PyObject_CallMethod(self, S_ON_CLOSE, NULL);
|
||||
PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_CLOSE, NULL);
|
||||
Py_XDECREF(pyres);
|
||||
Py_XDECREF(self);
|
||||
|
||||
@ -346,7 +333,7 @@ private:
|
||||
|
||||
int on_delete_line(int lineno)
|
||||
{
|
||||
PyObject *pyres = PyObject_CallMethod(self, S_ON_DELETE_LINE, "l", lineno - 1);
|
||||
PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_DELETE_LINE, "i", lineno - 1);
|
||||
if (pyres == NULL)
|
||||
return lineno;
|
||||
size_t res = PyInt_AsLong(pyres);
|
||||
@ -356,7 +343,7 @@ private:
|
||||
|
||||
int on_refresh(int lineno)
|
||||
{
|
||||
PyObject *pyres = PyObject_CallMethod(self, S_ON_REFRESH, "l", lineno - 1);
|
||||
PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_REFRESH, "i", lineno - 1);
|
||||
if (pyres == NULL)
|
||||
return lineno;
|
||||
size_t res = PyInt_AsLong(pyres);
|
||||
@ -366,25 +353,25 @@ private:
|
||||
|
||||
void on_insert_line()
|
||||
{
|
||||
PyObject *pyres = PyObject_CallMethod(self, S_ON_INSERT_LINE, NULL);
|
||||
PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_INSERT_LINE, NULL);
|
||||
Py_XDECREF(pyres);
|
||||
}
|
||||
|
||||
void on_select_line(int lineno)
|
||||
{
|
||||
PyObject *pyres = PyObject_CallMethod(self, S_ON_SELECT_LINE, "l", lineno - 1);
|
||||
PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_SELECT_LINE, "i", lineno - 1);
|
||||
Py_XDECREF(pyres);
|
||||
}
|
||||
|
||||
void on_edit_line(int lineno)
|
||||
{
|
||||
PyObject *pyres = PyObject_CallMethod(self, S_ON_EDIT_LINE, "l", lineno - 1);
|
||||
PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_EDIT_LINE, "i", lineno - 1);
|
||||
Py_XDECREF(pyres);
|
||||
}
|
||||
|
||||
int on_command(int cmd_id, int lineno)
|
||||
{
|
||||
PyObject *pyres = PyObject_CallMethod(self, S_ON_COMMAND, "ll", lineno - 1, cmd_id);
|
||||
PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_COMMAND, "ii", lineno - 1, cmd_id);
|
||||
if (pyres==NULL)
|
||||
return lineno;
|
||||
size_t res = PyInt_AsLong(pyres);
|
||||
@ -394,15 +381,14 @@ private:
|
||||
|
||||
int on_get_icon(int lineno)
|
||||
{
|
||||
PyObject *pyres = PyObject_CallMethod(self, S_ON_GET_ICON, "l", lineno - 1);
|
||||
PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_GET_ICON, "i", lineno - 1);
|
||||
size_t res = PyInt_AsLong(pyres);
|
||||
Py_XDECREF(pyres);
|
||||
return res;
|
||||
}
|
||||
#ifdef CH_ATTRS
|
||||
void on_get_line_attr(int lineno, chooser_item_attrs_t *attr)
|
||||
{
|
||||
PyObject *pyres = PyObject_CallMethod(self, S_ON_GET_LINE_ATTR, "l", lineno - 1);
|
||||
PyObject *pyres = PyObject_CallMethod(self, (char *)S_ON_GET_LINE_ATTR, "i", lineno - 1);
|
||||
if (pyres == NULL)
|
||||
return;
|
||||
|
||||
@ -416,7 +402,6 @@ private:
|
||||
}
|
||||
Py_XDECREF(pyres);
|
||||
}
|
||||
#endif
|
||||
public:
|
||||
//------------------------------------------------------------------------
|
||||
// Public methods
|
||||
@ -428,12 +413,10 @@ public:
|
||||
menu_cb_idx = 0;
|
||||
self = NULL;
|
||||
}
|
||||
#ifdef CH_ATTRS
|
||||
static py_choose2_t *find_chooser(const char *title)
|
||||
{
|
||||
return (py_choose2_t *) get_chooser_obj(title);
|
||||
}
|
||||
#endif
|
||||
void close()
|
||||
{
|
||||
close_chooser(title.c_str());
|
||||
@ -459,13 +442,11 @@ public:
|
||||
int x1 = -1, int y1 = -1, int x2 = -1, int y2 = -1)
|
||||
{
|
||||
flags = fl;
|
||||
#ifdef CH_ATTRS
|
||||
if ( (flags & CH_ATTRS) != 0 )
|
||||
{
|
||||
if ( !hook_to_notification_point(HT_UI, ui_cb, this) )
|
||||
flags &= ~CH_ATTRS;
|
||||
}
|
||||
#endif
|
||||
this->title = title;
|
||||
return ::choose2(
|
||||
flags,
|
||||
@ -595,9 +576,7 @@ public:
|
||||
{S_ON_REFRESH, CHOOSE2_HAVE_UPDATE},
|
||||
{S_ON_SELECT_LINE, CHOOSE2_HAVE_ENTER},
|
||||
{S_ON_COMMAND, CHOOSE2_HAVE_COMMAND},
|
||||
#ifdef CH_ATTRS
|
||||
{S_ON_GET_LINE_ATTR, CHOOSE2_HAVE_GETATTR},
|
||||
#endif
|
||||
{S_ON_GET_ICON, CHOOSE2_HAVE_GETICON}
|
||||
};
|
||||
cb_flags = 0;
|
||||
@ -631,11 +610,10 @@ public:
|
||||
}
|
||||
Py_XDECREF(attr);
|
||||
|
||||
#ifdef CH_ATTRS
|
||||
// Adjust flags (if needed)
|
||||
if ( (cb_flags & CHOOSE2_HAVE_GETATTR) != 0 )
|
||||
flags |= CH_ATTRS;
|
||||
#endif
|
||||
|
||||
// Increase object reference
|
||||
Py_INCREF(self);
|
||||
this->self = self;
|
||||
@ -666,6 +644,7 @@ public:
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Initialize the callback pointers
|
||||
#define DECL_MENU_COMMAND_CB(id) s_menu_command_##id
|
||||
chooser_cb_t *py_choose2_t::menu_cbs[MAX_CHOOSER_MENU_COMMANDS] =
|
||||
{
|
||||
DECL_MENU_COMMAND_CB(0), DECL_MENU_COMMAND_CB(1),
|
||||
@ -674,33 +653,13 @@ chooser_cb_t *py_choose2_t::menu_cbs[MAX_CHOOSER_MENU_COMMANDS] =
|
||||
DECL_MENU_COMMAND_CB(6), DECL_MENU_COMMAND_CB(7),
|
||||
DECL_MENU_COMMAND_CB(8), DECL_MENU_COMMAND_CB(9)
|
||||
};
|
||||
#undef DECL_MENU_COMMAND_CB
|
||||
|
||||
#undef POPUP_NAMES_COUNT
|
||||
#undef MAX_CHOOSER_MENU_COMMANDS
|
||||
#undef thisobj
|
||||
#undef thisdecl
|
||||
#undef MENU_COMMAND_CB
|
||||
#undef DECL_MENU_COMMAND_CB
|
||||
#undef S_ON_EDIT_LINE
|
||||
#undef S_ON_INSERT_LINE
|
||||
#undef S_ON_GET_LINE
|
||||
#undef S_ON_DELETE_LINE
|
||||
#undef S_ON_REFRESH
|
||||
#undef S_ON_SELECT_LINE
|
||||
#undef S_ON_COMMAND
|
||||
#undef S_ON_GET_ICON
|
||||
#undef S_ON_GET_LINE_ATTR
|
||||
#undef S_ON_GET_SIZE
|
||||
#undef S_ON_CLOSE
|
||||
#undef CHOOSE2_HAVE_DEL
|
||||
#undef CHOOSE2_HAVE_INS
|
||||
#undef CHOOSE2_HAVE_UPDATE
|
||||
#undef CHOOSE2_HAVE_EDIT
|
||||
#undef CHOOSE2_HAVE_ENTER
|
||||
#undef CHOOSE2_HAVE_GETICON
|
||||
#undef CHOOSE2_HAVE_GETATTR
|
||||
#undef CHOOSE2_HAVE_COMMAND
|
||||
#undef CHOOSE2_HAVE_ONCLOSE
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
int choose2_show(PyObject *self)
|
||||
|
Loading…
Reference in New Issue
Block a user