Пример #1
0
/*
header: typeinf.hpp
#<pydoc>
def apply_type_to_stkarg(op, v, type, name):
    """
    Apply type information to a stack variable

    @param op: reference to instruction operand
    @param v: immediate value in the operand (usually op.addr)
    @param type: type string. Retrieve from idc.ParseType("type string", flags)[1]
    @param name: stack variable name

    @return: Boolean
    """
    pass
#</pydoc>
*/
bool py_apply_type_to_stkarg(
    PyObject *py_op,
    PyObject *py_uv,
    PyObject *py_type,
    const char *name)
{
  uint64 v;
  PYW_GIL_CHECK_LOCKED_SCOPE();
  op_t *op = op_t_get_clink(py_op);
  if ( op == NULL || !PyW_GetNumber(py_uv, &v) || !PyString_Check(py_type))
  {
    return false;
  }
  else
  {
    const type_t *t = (type_t *) PyString_AsString(py_type);
    tinfo_t tif;
    tif.deserialize(idati, &t);
    borref_t br(py_op);
    bool rc;
    Py_BEGIN_ALLOW_THREADS;
    rc = apply_tinfo_to_stkarg(*op, uval_t(v), tif, name);
    Py_END_ALLOW_THREADS;
    return rc;
  }
}
Пример #2
0
/*
header: frame.hpp
#<pydoc>
def add_stkvar3(op, v, flags):
    """
    Automatically add stack variable if doesn't exist
    Processor modules should use ua_stkvar2()
    @param op: reference to instruction operand
    @param v: immediate value in the operand (usually op.addr)
    @param flags: combination of STKVAR_... constants
    @return: Boolean
    """
    pass
#</pydoc>
*/
bool py_add_stkvar3(PyObject *py_op, PyObject *py_v, int flags)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  op_t *op = op_t_get_clink(py_op);
  uint64 v;
  return ( op == NULL || !PyW_GetNumber(py_v, &v) || !add_stkvar3(*op, sval_t(v), flags)) ? false : true;
}
Пример #3
0
/*
#<pydoc>
def OutImmChar(op, outflags = 0):
    """
    Output operand value as a commented character constant
    @param op: operand (of type op_t)
    @return: None
    """
    pass
#</pydoc>
*/
static void py_OutImmChar(PyObject *x)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  op_t *op = op_t_get_clink(x);
  if ( op != NULL )
    OutImmChar(*op);
}
Пример #4
0
/*
#<pydoc>
def dbg_read_memory(ea, sz):
    """
    Reads from the debugee's memory at the specified ea
    @return:
        - The read buffer (as a string)
        - Or None on failure
    """
    pass
#</pydoc>
*/
static PyObject *dbg_read_memory(PyObject *py_ea, PyObject *py_sz)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();

  uint64 ea, sz;
  if ( !dbg_can_query() || !PyW_GetNumber(py_ea, &ea) || !PyW_GetNumber(py_sz, &sz) )
    Py_RETURN_NONE;

  // Create a Python string
  PyObject *ret = PyString_FromStringAndSize(NULL, Py_ssize_t(sz));
  if ( ret == NULL )
    Py_RETURN_NONE;

  // Get the internal buffer
  Py_ssize_t len;
  char *buf;
  PyString_AsStringAndSize(ret, &buf, &len);

  if ( (size_t)read_dbg_memory(ea_t(ea), buf, size_t(sz)) != sz )
  {
    // Release the string on failure
    Py_DECREF(ret);
    // Return None on failure
    Py_RETURN_NONE;
  }
  return ret;
}
Пример #5
0
static PyObject *py_add_menu_item(
  const char *menupath,
  const char *name,
  const char *hotkey,
  int flags,
  PyObject *pyfunc,
  PyObject *args)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  bool no_args;

  // No slash in the menu path?
  const char *p = strrchr(menupath, '/');
  if ( p == NULL )
    Py_RETURN_NONE;

  if ( args == Py_None )
  {
    no_args = true;
    args = PyTuple_New(0);
    if ( args == NULL )
      return NULL;
  }
  else if ( !PyTuple_Check(args) )
  {
    PyErr_SetString(PyExc_TypeError, "args must be a tuple or None");
    return NULL;
  }
  else
  {
    no_args = false;
  }

  // Form a tuple holding the function to be called and its arguments
  PyObject *cb_data = Py_BuildValue("(OO)", pyfunc, args);

  // If we created an empty tuple, then we must free it
  if ( no_args )
    Py_DECREF(args);

  // Add the menu item
  bool b = add_menu_item(menupath, name, hotkey, flags, py_menu_item_callback, (void *)cb_data);

  if ( !b )
  {
    Py_XDECREF(cb_data);
    Py_RETURN_NONE;
  }
  // Create a context (for the delete_menu_item())
  py_add_del_menu_item_ctx *ctx = new py_add_del_menu_item_ctx();

  // Form the complete menu path
  ctx->menupath.append(menupath, p - menupath + 1);
  ctx->menupath.append(name);
  // Save callback data
  ctx->cb_data = cb_data;

  // Return context to user
  return PyCObject_FromVoidPtr(ctx, NULL);
}
Пример #6
0
//-------------------------------------------------------------------------
// callback for enumerating imports
// ea:   import address
// name: import name (NULL if imported by ordinal)
// ord:  import ordinal (0 for imports by name)
// param: user parameter passed to enum_import_names()
// return: 1-ok, 0-stop enumeration
static int idaapi py_import_enum_cb(
  ea_t ea,
  const char *name,
  uval_t ord,
  void *param)
{
  // If no name, try to get the name associated with the 'ea'. It may be coming from IDS
  char name_buf[MAXSTR];
  if ( name == NULL )
    name = get_true_name(BADADDR, ea, name_buf, sizeof(name_buf));

  PYW_GIL_CHECK_LOCKED_SCOPE();
  ref_t py_name;
  if ( name == NULL )
    py_name = borref_t(Py_None);
  else
    py_name = newref_t(PyString_FromString(name));

  newref_t py_ord(Py_BuildValue(PY_FMT64, pyul_t(ord)));
  newref_t py_ea(Py_BuildValue(PY_FMT64, pyul_t(ea)));
  newref_t py_result(
          PyObject_CallFunctionObjArgs(
                  (PyObject *)param,
                  py_ea.o,
                  py_name.o,
                  py_ord.o,
                  NULL));
  return py_result != NULL && PyObject_IsTrue(py_result.o) ? 1 : 0;
}
Пример #7
0
//-------------------------------------------------------------------------
PyObject *py_tag_addr(ea_t ea)
{
  char buf[100];
  tag_addr(buf, buf + sizeof(buf), ea);
  PYW_GIL_CHECK_LOCKED_SCOPE();
  return PyString_FromString(buf);
}
Пример #8
0
/*
#<pydoc>
def set_user_defined_prefix(width, callback):
    """
    User-defined line-prefixes are displayed just after the autogenerated
    line prefixes. In order to use them, the plugin should call the
    following function to specify its width and contents.
    @param width: the width of the user-defined prefix
    @param callback: a get_user_defined_prefix callback to get the contents of the prefix.
        Its arguments:
          ea     - linear address
          lnnum  - line number
          indent - indent of the line contents (-1 means the default instruction)
                   indent and is used for instruction itself. see explanations for printf_line()
          line   - the line to be generated. the line usually contains color tags this argument
                   can be examined to decide whether to generated the prefix
          bufsize- the maximum allowed size of the output buffer
        It returns a buffer of size < bufsize

    In order to remove the callback before unloading the plugin, specify the width = 0 or the callback = None
    """
    pass
#</pydoc>
*/
static PyObject *py_set_user_defined_prefix(size_t width, PyObject *pycb)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  if ( width == 0 || pycb == Py_None )
  {
    // Release old callback reference
    Py_XDECREF(py_get_user_defined_prefix);

    // ...and clear it
    py_get_user_defined_prefix = NULL;

    // Uninstall user defind prefix
    set_user_defined_prefix(0, NULL);
  }
  else if ( PyCallable_Check(pycb) )
  {
    // Release old callback reference
    Py_XDECREF(py_get_user_defined_prefix);

    // Copy new callback and hold a reference
    py_get_user_defined_prefix = pycb;
    Py_INCREF(py_get_user_defined_prefix);

    set_user_defined_prefix(width, s_py_get_user_defined_prefix);
  }
  else
  {
    Py_RETURN_FALSE;
  }
  Py_RETURN_TRUE;
}
Пример #9
0
//-------------------------------------------------------------------------
PyObject *py_tag_addr(ea_t ea)
{
  qstring tag;
  tag_addr(&tag, ea);
  PYW_GIL_CHECK_LOCKED_SCOPE();
  return PyString_FromString(tag.begin());
}
Пример #10
0
//<code(py_bytes)>
//------------------------------------------------------------------------
static bool idaapi py_testf_cb(flags_t flags, void *ud)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  newref_t py_flags(PyLong_FromUnsignedLong(flags));
  newref_t result(PyObject_CallFunctionObjArgs((PyObject *) ud, py_flags.o, NULL));
  return result != NULL && PyObject_IsTrue(result.o);
}
Пример #11
0
/*
#<pydoc>
def tag_remove(colstr):
    """
    Remove color escape sequences from a string
    @param colstr: the colored string with embedded tags
    @return: a new string w/o the tags
    """
    pass
#</pydoc>
*/
PyObject *py_tag_remove(const char *instr)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  qstring qbuf;
  tag_remove(&qbuf, instr);
  return PyString_FromString(qbuf.c_str());
}
Пример #12
0
/*
#<pydoc>
def enum_import_names(mod_index, callback):
    """
    Enumerate imports from a specific module.
    Please refer to ex_imports.py example.

    @param mod_index: The module index
    @param callback: A callable object that will be invoked with an ea, name (could be None) and ordinal.
    @return: 1-finished ok, -1 on error, otherwise callback return value (<=0)
    """
    pass
#</pydoc>
*/
static int py_enum_import_names(int mod_index, PyObject *py_cb)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  if ( !PyCallable_Check(py_cb) )
    return -1;
  return enum_import_names(mod_index, py_import_enum_cb, py_cb);
}
Пример #13
0
/*
#<pydoc>
def generate_disassembly(ea, max_lines, as_stack, notags):
    """
    Generate disassembly lines (many lines) and put them into a buffer

    @param ea: address to generate disassembly for
    @param max_lines: how many lines max to generate
    @param as_stack: Display undefined items as 2/4/8 bytes
    @return:
        - None on failure
        - tuple(most_important_line_number, tuple(lines)) : Returns a tuple containing
          the most important line number and a tuple of generated lines
    """
    pass
#</pydoc>
*/
PyObject *py_generate_disassembly(
  ea_t ea,
  int max_lines,
  bool as_stack,
  bool notags)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  if ( max_lines <= 0 )
    Py_RETURN_NONE;

  qstring qbuf;
  char **lines = new char *[max_lines];
  int lnnum;
  int nlines = generate_disassembly(ea, lines, max_lines, &lnnum, as_stack);

  newref_t py_tuple(PyTuple_New(nlines));
  for ( int i=0; i<nlines; i++ )
  {
    const char *s = lines[i];
    size_t line_len = strlen(s);
    if ( notags )
    {
      qbuf.resize(line_len+5);
      tag_remove(s, &qbuf[0], line_len);
      s = (const char *)&qbuf[0];
    }
    PyTuple_SetItem(py_tuple.o, i, PyString_FromString(s));
    qfree(lines[i]);
  }
  delete [] lines;
  return Py_BuildValue("(iO)", lnnum, py_tuple.o);
}
Пример #14
0
/*
#<pydoc>
def decode_preceding_insn(ea):
    """
    Decodes the preceding instruction. Please check ua.hpp / decode_preceding_insn()
    @param ea: current ea
    @return: tuple(preceeding_ea or BADADDR, farref = Boolean)
    """
    pass
#</pydoc>
*/
PyObject *py_decode_preceding_insn(ea_t ea)
{
  bool farref;
  ea_t r = decode_preceding_insn(ea, &farref);
  PYW_GIL_CHECK_LOCKED_SCOPE();
  return Py_BuildValue("(" PY_FMT64 "i)", pyul_t(r), farref ? 1 : 0);
}
Пример #15
0
/*
#<pydoc>
def generate_disassembly(ea, max_lines, as_stack, notags):
    """
    Generate disassembly lines (many lines) and put them into a buffer

    @param ea: address to generate disassembly for
    @param max_lines: how many lines max to generate
    @param as_stack: Display undefined items as 2/4/8 bytes
    @return:
        - None on failure
        - tuple(most_important_line_number, tuple(lines)) : Returns a tuple containing
          the most important line number and a tuple of generated lines
    """
    pass
#</pydoc>
*/
PyObject *py_generate_disassembly(
        ea_t ea,
        int max_lines,
        bool as_stack,
        bool notags)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  if ( max_lines <= 0 )
    Py_RETURN_NONE;

  qstring qbuf;
  qstrvec_t lines;
  int lnnum;
  int nlines = generate_disassembly(&lines, &lnnum, ea, max_lines, as_stack);

  newref_t py_tuple(PyTuple_New(nlines));
  for ( int i=0; i < nlines; i++ )
  {
    const qstring &l = lines[i];
    const char *s = l.c_str();
    if ( notags )
    {
      tag_remove(&qbuf, l);
      s = qbuf.c_str();
    }
    PyTuple_SetItem(py_tuple.o, i, PyString_FromString(s));
  }
  return Py_BuildValue("(iO)", lnnum, py_tuple.o);
}
Пример #16
0
// Get definition of a registered custom data format and returns a dictionary
static PyObject *py_get_custom_data_type(int dtid)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  const data_type_t *dt = get_custom_data_type(dtid);
  if ( dt == NULL )
    Py_RETURN_NONE;
  return py_data_type_to_py_dict(dt);
}
Пример #17
0
// Get definition of a registered custom data format and returns a dictionary
static PyObject *py_get_custom_data_format(int dtid, int fid)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  const data_format_t *df = get_custom_data_format(dtid, fid);
  if ( df == NULL )
    Py_RETURN_NONE;
  return py_data_format_to_py_dict(df);
}
Пример #18
0
static void insn_t_set_auxpref(PyObject *self, PyObject *value)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  insn_t *link = insn_t_get_clink(self);
  if ( link == NULL )
    return;
  link->auxpref = (uint16)PyInt_AsLong(value);
}
Пример #19
0
static void insn_t_set_flags(PyObject *self, PyObject *value)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  insn_t *link = insn_t_get_clink(self);
  if ( link == NULL )
    return;
  link->flags = (char)PyInt_AsLong(value);
}
Пример #20
0
static PyObject *op_t_get_specval(PyObject *self)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  op_t *link = op_t_get_clink(self);
  if ( link == NULL )
    Py_RETURN_NONE;
  return Py_BuildValue(PY_FMT64, (pyul_t)link->specval);
}
Пример #21
0
static void op_t_set_reg_phrase(PyObject *self, PyObject *value)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  op_t *link = op_t_get_clink(self);
  if ( link == NULL )
    return;
  link->reg = (uint16)PyInt_AsLong(value);
}
Пример #22
0
static PyObject *op_t_get_reg_phrase(PyObject *self)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  op_t *link = op_t_get_clink(self);
  if ( link == NULL )
    Py_RETURN_NONE;
  return Py_BuildValue("H", link->reg);
}
Пример #23
0
static void op_t_set_type(PyObject *self, PyObject *value)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  op_t *link = op_t_get_clink(self);
  if ( link == NULL )
    return;
  link->type = (optype_t)PyInt_AsLong(value);
}
Пример #24
0
/*
#<pydoc>
def internal_get_sreg_base():
    """
    Get the sreg base, for the given thread.

    @return: The sreg base, or BADADDR on failure.
    """
    pass
#</pydoc>
*/
static ea_t py_internal_get_sreg_base(thid_t tid, int sreg_value)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  ea_t answer;
  return internal_get_sreg_base(tid, sreg_value, &answer) < 1
       ? BADADDR
       : answer;
}
Пример #25
0
static void op_t_set_specflag4(PyObject *self, PyObject *value)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  op_t *link = op_t_get_clink(self);
  if ( link == NULL )
    return;
  link->specflag4 = (char)PyInt_AsLong(value);
}
Пример #26
0
static PyObject *insn_t_get_flags(PyObject *self)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  insn_t *link = insn_t_get_clink(self);
  if ( link == NULL )
    Py_RETURN_NONE;
  return Py_BuildValue("b", link->flags);
}
Пример #27
0
/*
#<pydoc>
def visit_patched_bytes(ea1, ea2, callable):
    """
    Enumerates patched bytes in the given range and invokes a callable
    @param ea1: start address
    @param ea2: end address
    @param callable: a Python callable with the following prototype:
                     callable(ea, fpos, org_val, patch_val).
                     If the callable returns non-zero then that value will be
                     returned to the caller and the enumeration will be
                     interrupted.
    @return: Zero if the enumeration was successful or the return
             value of the callback if enumeration was interrupted.
    """
    pass
#</pydoc>
*/
static int py_visit_patched_bytes(ea_t ea1, ea_t ea2, PyObject *py_callable)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  if ( !PyCallable_Check(py_callable) )
    return 0;
  else
    return visit_patched_bytes(ea1, ea2, py_visit_patched_bytes_cb, py_callable);
}
Пример #28
0
//------------------------------------------------------------------------
// Wraps the (next|prev)that()
static ea_t py_npthat(ea_t ea, ea_t bound, PyObject *py_callable, bool next)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  if ( !PyCallable_Check(py_callable) )
    return BADADDR;
  else
    return (next ? next_that : prev_that)(ea, bound, py_testf_cb, py_callable);
}
Пример #29
0
static PyObject *op_t_get_specflag4(PyObject *self)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  op_t *link = op_t_get_clink(self);
  if ( link == NULL )
    Py_RETURN_NONE;
  return Py_BuildValue("b", link->specflag4);
}
Пример #30
0
static PyObject *insn_t_get_ea(PyObject *self)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  insn_t *link = insn_t_get_clink(self);
  if ( link == NULL )
    Py_RETURN_NONE;
  return Py_BuildValue(PY_FMT64, (pyul_t)link->ea);
}