From 5fe579530adf7254cb35278c94f6a55786fb6a1d Mon Sep 17 00:00:00 2001 From: "elias.bachaalany" Date: Mon, 5 Oct 2009 10:30:50 +0000 Subject: [PATCH] dbg.i/idd.i: wrapped some functions from the dbg/debugger_t class: get_manual_regions/dbg_get_memory_info/dbg_get_registers/dbg_get_thread_sreg_base/dbg_read_memory/dbg_write_memory/dbg_can_query --- examples/ex_dbg.py | 48 ++++++++++++++ swig/dbg.i | 21 +++++- swig/idd.i | 160 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 examples/ex_dbg.py diff --git a/examples/ex_dbg.py b/examples/ex_dbg.py new file mode 100644 index 0000000..6f2f8b9 --- /dev/null +++ b/examples/ex_dbg.py @@ -0,0 +1,48 @@ +# +# Demonstrates some functions from the "dbg" class +# + +import idaapi +#from idaapi import dbg_write_memory, dbg_read_memory, dbg_get_thread_sreg_base, dbg_get_registers, dbg_get_memory_info + +def dump_meminfo(L): + # startEA, endEA, name, sclass, sbase, bitness, perm + for (startEA, endEA, name, sclass, sbase, bitness, perm) in L: + print "%x: %x name=<%s> sclass=<%s> sbase=%x bitness=%2x perm=%2x" % (startEA, endEA, name, sclass, sbase, bitness, perm) + +def test_getmeminfo(): + L = idaapi.dbg_get_memory_info() + dump_meminfo(L) + +def test_getregs(): + L = idaapi.dbg_get_registers() + # name flags class dtyp bit_strings bit_strings_default_mask + for (name, flags, cls, dtype, bit_strings, bit_strings_default_mask) in L: + print "name=<%s> flags=%x class=%x dtype=%x bit_strings_mask=%x" % (name, flags, cls, dtype, bit_strings_default_mask) + if bit_strings: + for s in bit_strings: + print " %s" % s + +def test_manual_regions(): + L = idaapi.get_manual_regions() + if not L: + print "no manual regions!" + else: + dump_meminfo(L) + +def test_readwrite(): + ea = cpu.Eip + buf = idaapi.dbg_read_memory(ea, 5) + print "read: ", [hex(ord(x)) for x in buf] + idaapi.dbg_write_memory(ea, buf) + +test_manual_regions() + +if idaapi.dbg_can_query(): + print "%x: fs" % (idaapi.dbg_get_thread_sreg_base(idc.GetCurrentThreadId(), cpu.fs)) + test_getmeminfo() + test_getregs() + test_readwrite() + +else: + print "run and suspend the debugger first" \ No newline at end of file diff --git a/swig/dbg.i b/swig/dbg.i index 794904b..af3b948 100644 --- a/swig/dbg.i +++ b/swig/dbg.i @@ -5,12 +5,31 @@ typedef struct ushort fval[6]; // 12: floating point value in the internal representation (see ieee.h) } regval_t; -%immutable dbg; +%ignore dbg; +%ignore get_manual_regions; +%rename (get_manual_regions) py_get_manual_regions; +%ignore set_manual_regions; %include "dbg.hpp" %feature("director") DBG_Hooks; +%{ +// +PyObject *meminfo_vec_t_to_py(meminfo_vec_t &areas); +// +%} + %inline %{ + +// +PyObject *py_get_manual_regions() +{ + meminfo_vec_t areas; + get_manual_regions(&areas); + return meminfo_vec_t_to_py(areas); +} +// + int idaapi DBG_Callback(void *ud, int notification_code, va_list va); class DBG_Hooks { diff --git a/swig/idd.i b/swig/idd.i index 5fc0c11..cd1c00c 100644 --- a/swig/idd.i +++ b/swig/idd.i @@ -1,4 +1,6 @@ %ignore debugger_t; +%ignore memory_info_t; +%ignore register_info_t; %apply unsigned char { char dtyp }; @@ -6,8 +8,166 @@ %clear(char dtyp); +%{ +// +#ifndef __PYDBG__ +#define __PYDBG__ + +#ifndef PYUL_DEFINED +#define PYUL_DEFINED + typedef unsigned PY_LONG_LONG pyul_t; +#endif + +bool dbg_can_query() +{ + // Reject the request only if no debugger is set + // or the debugger cannot be queried while not in suspended state + return !(dbg == NULL || (!dbg->may_disturb() && get_process_state() != DSTATE_SUSP)); +} + +PyObject *meminfo_vec_t_to_py(meminfo_vec_t &areas) +{ + PyObject *py_list = PyList_New(areas.size()); + meminfo_vec_t::const_iterator it, it_end(areas.end()); + Py_ssize_t i = 0; + for (it=areas.begin();it!=it_end;++it, ++i) + { + const memory_info_t &mi = *it; + // startEA endEA name sclass sbase bitness perm + PyList_SetItem(py_list, i, + Py_BuildValue("(KKssKii)", + pyul_t(mi.startEA), + pyul_t(mi.endEA), + mi.name.c_str(), + mi.sclass.c_str(), + pyul_t(mi.sbase), + (unsigned int)(mi.bitness), + (unsigned int)mi.perm)); + } + return py_list; +} + +PyObject *dbg_get_memory_info() +{ + if (!dbg_can_query()) + Py_RETURN_NONE; + + // Invalidate memory + invalidate_dbgmem_config(); + invalidate_dbgmem_contents(BADADDR, BADADDR); + + meminfo_vec_t areas; + dbg->get_memory_info(areas); + return meminfo_vec_t_to_py(areas); +} + +PyObject *dbg_get_registers() +{ + if (dbg == NULL) + Py_RETURN_NONE; + + PyObject *py_list = PyList_New(dbg->registers_size); + + for (int i=0;iregisters_size;i++) + { + register_info_t &ri = dbg->registers[i]; + PyObject *py_bits; + + // Does this register have bit strings? + if (ri.bit_strings != NULL) + { + int nbits = (int)b2a_width((int)get_dtyp_size(ri.dtyp), 0) * 4; + py_bits = PyList_New(nbits); + for (int i=0;ithread_get_sreg_base(tid, sreg_value, &answer) != 1) + Py_RETURN_NONE; + return Py_BuildValue("K", pyul_t(answer)); +} + +PyObject *dbg_read_memory(PyObject *py_ea, PyObject *py_sz) +{ + if (!dbg_can_query() || !PyNumber_Check(py_ea) || !PyNumber_Check(py_sz)) + Py_RETURN_NONE; + + ea_t ea = ea_t(PyInt_AsSsize_t(py_ea)); + size_t sz = ea_t(PyInt_AsSsize_t(py_sz)); + + char *buf = new char[sz]; + if (buf == NULL) + Py_RETURN_NONE; + + PyObject *ret; + if (dbg->read_memory(ea_t(ea), buf, sz) == sz) + { + ret = PyString_FromStringAndSize(buf, sz); + } + else + { + Py_INCREF(Py_None); + ret = Py_None; + } + delete [] buf; + return ret; +} + +PyObject *dbg_write_memory(PyObject *py_ea, PyObject *py_buf) +{ + if (!dbg_can_query() || !PyString_Check(py_buf) || !PyNumber_Check(py_ea)) + Py_RETURN_NONE; + + ea_t ea = ea_t(PyInt_AsSsize_t(py_ea)); + size_t sz = PyString_GET_SIZE(py_buf); + void *buf = (void *)PyString_AS_STRING(py_buf); + if (dbg->write_memory(ea, buf, sz) != sz) + Py_RETURN_FALSE; + Py_RETURN_TRUE; +} +#endif +// +%} %inline %{ + +// +PyObject *dbg_write_memory(PyObject *py_ea, PyObject *py_buf); +PyObject *dbg_read_memory(PyObject *py_ea, PyObject *py_sz); +PyObject *dbg_get_thread_sreg_base(PyObject *py_tid, PyObject *py_sreg_value); +PyObject *dbg_get_registers(); +PyObject *dbg_get_memory_info(); +bool dbg_can_query(); +// + char get_event_module_name(const debug_event_t* ev, char *buf, size_t bufsize) { qstrncpy(buf, ev->modinfo.name, bufsize);