mirror of
https://github.com/cemu-project/idapython.git
synced 2025-03-03 16:55:22 +01:00
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
This commit is contained in:
parent
e2a0ee8204
commit
5fe579530a
48
examples/ex_dbg.py
Normal file
48
examples/ex_dbg.py
Normal file
@ -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"
|
21
swig/dbg.i
21
swig/dbg.i
@ -5,12 +5,31 @@ typedef struct
|
|||||||
ushort fval[6]; // 12: floating point value in the internal representation (see ieee.h)
|
ushort fval[6]; // 12: floating point value in the internal representation (see ieee.h)
|
||||||
} regval_t;
|
} 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"
|
%include "dbg.hpp"
|
||||||
|
|
||||||
%feature("director") DBG_Hooks;
|
%feature("director") DBG_Hooks;
|
||||||
|
|
||||||
|
%{
|
||||||
|
//<code(py_dbg)>
|
||||||
|
PyObject *meminfo_vec_t_to_py(meminfo_vec_t &areas);
|
||||||
|
//</code(py_dbg)>
|
||||||
|
%}
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
|
|
||||||
|
//<inline(py_dbg)>
|
||||||
|
PyObject *py_get_manual_regions()
|
||||||
|
{
|
||||||
|
meminfo_vec_t areas;
|
||||||
|
get_manual_regions(&areas);
|
||||||
|
return meminfo_vec_t_to_py(areas);
|
||||||
|
}
|
||||||
|
//</inline(py_dbg)>
|
||||||
|
|
||||||
int idaapi DBG_Callback(void *ud, int notification_code, va_list va);
|
int idaapi DBG_Callback(void *ud, int notification_code, va_list va);
|
||||||
class DBG_Hooks
|
class DBG_Hooks
|
||||||
{
|
{
|
||||||
|
160
swig/idd.i
160
swig/idd.i
@ -1,4 +1,6 @@
|
|||||||
%ignore debugger_t;
|
%ignore debugger_t;
|
||||||
|
%ignore memory_info_t;
|
||||||
|
%ignore register_info_t;
|
||||||
|
|
||||||
%apply unsigned char { char dtyp };
|
%apply unsigned char { char dtyp };
|
||||||
|
|
||||||
@ -6,8 +8,166 @@
|
|||||||
|
|
||||||
%clear(char dtyp);
|
%clear(char dtyp);
|
||||||
|
|
||||||
|
%{
|
||||||
|
//<code(py_idd)>
|
||||||
|
#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;i<dbg->registers_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;i<nbits;i++)
|
||||||
|
{
|
||||||
|
const char *s = ri.bit_strings[i];
|
||||||
|
PyList_SetItem(py_bits, i, PyString_FromString(s == NULL ? "" : s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
py_bits = Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
// name flags class dtyp bit_strings bit_strings_default_mask
|
||||||
|
PyList_SetItem(py_list, i,
|
||||||
|
Py_BuildValue("(sIIINI)",
|
||||||
|
ri.name,
|
||||||
|
ri.flags,
|
||||||
|
(unsigned int)ri.register_class,
|
||||||
|
(unsigned int)ri.dtyp,
|
||||||
|
py_bits,
|
||||||
|
(unsigned int)ri.bit_strings_default));
|
||||||
|
}
|
||||||
|
return py_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *dbg_get_thread_sreg_base(PyObject *py_tid, PyObject *py_sreg_value)
|
||||||
|
{
|
||||||
|
if (!dbg_can_query() || !PyInt_Check(py_tid) || !PyInt_Check(py_sreg_value))
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
ea_t answer;
|
||||||
|
thid_t tid = PyInt_AsLong(py_tid);
|
||||||
|
int sreg_value = PyInt_AsLong(py_sreg_value);
|
||||||
|
if (dbg->thread_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
|
||||||
|
//</code(py_idd)>
|
||||||
|
%}
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
|
|
||||||
|
//<inline(py_idd)>
|
||||||
|
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();
|
||||||
|
//</inline(py_idd)>
|
||||||
|
|
||||||
char get_event_module_name(const debug_event_t* ev, char *buf, size_t bufsize)
|
char get_event_module_name(const debug_event_t* ev, char *buf, size_t bufsize)
|
||||||
{
|
{
|
||||||
qstrncpy(buf, ev->modinfo.name, bufsize);
|
qstrncpy(buf, ev->modinfo.name, bufsize);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user