- updated debughook example

- wrapped print_type
- minor mods to idc.py
- added idautils.GetIdbDir
- added Names()
- added Modules()
- added idautils.peutils_t()
- simplecustviewer_t.GetLineNo() now returns -1 on failure
- idc.py / setregval: it was not possible to set register values > 0x7fffffff
This commit is contained in:
elias.bachaalany 2010-07-27 14:44:31 +00:00
parent 97a9805336
commit 686e018bdc
7 changed files with 142 additions and 21 deletions

View File

@ -4,7 +4,10 @@
# This script start the executable and steps through the first five # This script start the executable and steps through the first five
# instructions. Each instruction is disassembled after execution. # instructions. Each instruction is disassembled after execution.
# #
# Author: Gergely Erdelyi <gergely.erdelyi@d-dome.net> # Original Author: Gergely Erdelyi <gergely.erdelyi@d-dome.net>
#
# Maintained By: IDAPython Team
#
#--------------------------------------------------------------------- #---------------------------------------------------------------------
from idaapi import * from idaapi import *
@ -19,6 +22,10 @@ class MyDbgHook(DBG_Hooks):
print "Process exited pid=%d tid=%d ea=0x%x code=%d" % (pid, tid, ea, code) print "Process exited pid=%d tid=%d ea=0x%x code=%d" % (pid, tid, ea, code)
return 0 return 0
def dbg_library_unload(self, pid, tid, ea, info):
print "Library unloaded: pid=%d tid=%d ea=0x%x info=%s" % (pid, tid, ea, info)
return 0
def dbg_library_load(self, pid, tid, ea, name, base, size): def dbg_library_load(self, pid, tid, ea, name, base, size):
print "Library loaded: pid=%d tid=%d name=%s base=%x" % (pid, tid, name, base) print "Library loaded: pid=%d tid=%d name=%s base=%x" % (pid, tid, name, base)
@ -31,6 +38,19 @@ class MyDbgHook(DBG_Hooks):
# 1 - to always display a breakpoint warning dialog. # 1 - to always display a breakpoint warning dialog.
return 0 return 0
def dbg_suspend_process(self):
print "Process suspended"
def dbg_exception(self, pid, tid, ea, exc_code, exc_can_cont, exc_ea, exc_info):
print "Exception: pid=%d tid=%d ea=0x%x exc_code=0x%x can_continue=%d exc_ea=0x%x exc_info=%s" % (
pid, tid, ea, exc_code & idaapi.BADADDR, exc_can_cont, exc_ea, exc_info)
# return values:
# -1 - to display an exception warning dialog
# if the process is suspended.
# 0 - to never display an exception warning dialog.
# 1 - to always display an exception warning dialog.
return 0
def dbg_trace(self, tid, ea): def dbg_trace(self, tid, ea):
print tid, ea print tid, ea
return 0 return 0
@ -39,6 +59,10 @@ class MyDbgHook(DBG_Hooks):
print "Step into" print "Step into"
return self.dbg_step_over() return self.dbg_step_over()
# def dbg_run_to(self, tid):
# print "Runto: tid=%d" % tid
# idaapi.continue_process()
def dbg_step_over(self): def dbg_step_over(self):
eip = GetRegValue("EIP") eip = GetRegValue("EIP")
print "0x%x %s" % (eip, GetDisasm(eip)) print "0x%x %s" % (eip, GetDisasm(eip))

View File

@ -14,6 +14,7 @@ idautils.py - High level utility functions for IDA
import idaapi import idaapi
import idc import idc
import types import types
import os
def refs(ea, funcfirst, funcnext): def refs(ea, funcfirst, funcnext):
""" """
@ -240,6 +241,26 @@ def Chunks(start):
yield (chunk.startEA, chunk.endEA) yield (chunk.startEA, chunk.endEA)
status = func_iter.next() status = func_iter.next()
def Modules():
"""
Returns a list of module objects with name,size,base and the rebase_to attributes
"""
mod = idaapi.module_info_t()
result = idaapi.get_first_module(mod)
while result:
yield idaapi.object_t(name=mod.name, size=mod.size, base=mod.base, rebase_to=mod.rebase_to)
result = idaapi.get_next_module(mod)
def Names():
"""
Returns a list of names
@return: tuple(ea, name)
"""
for i in xrange(idaapi.get_nlist_size()):
ea = idaapi.get_nlist_ea(i)
name = idaapi.get_nlist_name(i)
yield (ea, name)
def Segments(): def Segments():
""" """
@ -424,14 +445,26 @@ class Strings(object):
return Strings.StringItem(self._si) return Strings.StringItem(self._si)
return None return None
# -----------------------------------------------------------------------
def GetRegisterList(): def GetRegisterList():
"""Returns the register list""" """Returns the register list"""
return idaapi.ph_get_regnames() return idaapi.ph_get_regnames()
# -----------------------------------------------------------------------
def GetIdbDir():
"""
Get IDB directory
This function returns directory path of the current IDB database
"""
return os.path.dirname(idaapi.cvar.database_idb) + os.sep
# -----------------------------------------------------------------------
def GetInstructionList(): def GetInstructionList():
"""Returns the instruction list of the current processor module""" """Returns the instruction list of the current processor module"""
return [i[0] for i in idaapi.ph_get_instruc() if i[0]] return [i[0] for i in idaapi.ph_get_instruc() if i[0]]
# -----------------------------------------------------------------------
def _Assemble(ea, line): def _Assemble(ea, line):
""" """
Please refer to Assemble() - INTERNAL USE ONLY Please refer to Assemble() - INTERNAL USE ONLY
@ -496,6 +529,7 @@ def _copy_obj(src, dest, skip_list = None):
setattr(dest, x, t) setattr(dest, x, t)
return dest return dest
# -----------------------------------------------------------------------
class _reg_dtyp_t(object): class _reg_dtyp_t(object):
""" """
INTERNAL INTERNAL
@ -509,6 +543,7 @@ class _reg_dtyp_t(object):
def __eq__(self, other): def __eq__(self, other):
return (self.reg == other.reg) and (self.dtyp == other.dtyp) return (self.reg == other.reg) and (self.dtyp == other.dtyp)
# -----------------------------------------------------------------------
class _procregs(object): class _procregs(object):
"""Utility class allowing the users to identify registers in a decoded instruction""" """Utility class allowing the users to identify registers in a decoded instruction"""
def __getattr__(self, attr): def __getattr__(self, attr):
@ -522,6 +557,7 @@ class _procregs(object):
def __setattr__(self, attr, value): def __setattr__(self, attr, value):
raise AttributeError(attr) raise AttributeError(attr)
# -----------------------------------------------------------------------
class _cpu(object): class _cpu(object):
"Simple wrapper around GetRegValue/SetRegValue" "Simple wrapper around GetRegValue/SetRegValue"
def __getattr__(self, name): def __getattr__(self, name):
@ -532,6 +568,37 @@ class _cpu(object):
#print "cpu.set(%s)"%name #print "cpu.set(%s)"%name
return idc.SetRegValue(value, name) return idc.SetRegValue(value, name)
# -----------------------------------------------------------------------
class peutils_t(object):
"""
PE utility class. Retrieves PE information from the database.
Constants from pe.h
"""
PE_NODE = "$ PE header" # netnode name for PE header
PE_ALT_DBG_FPOS = idaapi.BADADDR & -1 # altval() -> translated fpos of debuginfo
PE_ALT_IMAGEBASE = idaapi.BADADDR & -2 # altval() -> loading address (usually pe.imagebase)
PE_ALT_PEHDR_OFF = idaapi.BADADDR & -3 # altval() -> offset of PE header
PE_ALT_NEFLAGS = idaapi.BADADDR & -4 # altval() -> neflags
PE_ALT_TDS_LOADED = idaapi.BADADDR & -5 # altval() -> tds already loaded(1) or invalid(-1)
PE_ALT_PSXDLL = idaapi.BADADDR & -6 # altval() -> if POSIX(x86) imports from PSXDLL netnode
def __init__(self):
self.__penode = idaapi.netnode()
self.__penode.create(peutils_t.PE_NODE)
imagebase = property(
lambda self: self.__penode.altval(peutils_t.PE_ALT_IMAGEBASE)
)
header = property(
lambda self: self.__penode.altval(peutils_t.PE_ALT_PEHDR_OFF)
)
def __str__(self):
return "peutils_t(imagebase=%s, header=%s)" % (hex(self.imagebase), hex(self.header))
# -----------------------------------------------------------------------
cpu = _cpu() cpu = _cpu()
"""This is a special class instance used to access the registers as if they were attributes of this object. """This is a special class instance used to access the registers as if they were attributes of this object.
For example to access the EAX register: For example to access the EAX register:

View File

@ -3817,7 +3817,7 @@ def writestr(handle, s):
# F U N C T I O N S # F U N C T I O N S
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
def MakeFunction(start, end): def MakeFunction(start, end = idaapi.BADADDR):
""" """
Create a function Create a function
@ -7094,13 +7094,13 @@ def SetRegValue(value, name):
A register name in the left side of an assignment will do too. A register name in the left side of an assignment will do too.
""" """
rv = idaapi.regval_t() rv = idaapi.regval_t()
if type(value)==types.StringType: if type(value) == types.StringType:
value = int(value) value = int(value, 16)
elif type(value)!=types.IntType: elif type(value) != types.IntType and type(value) != types.LongType:
print "SetRegValue: value must be integer!" print "SetRegValue: value must be integer!"
return BADADDR return BADADDR
if value<0: if value < 0:
#ival_set cannot handle negative numbers #ival_set cannot handle negative numbers
value &= 0xFFFFFFFF value &= 0xFFFFFFFF
@ -7249,7 +7249,8 @@ def AddBptEx(ea, size, bpttype):
return idaapi.add_bpt(ea, size, bpttype) return idaapi.add_bpt(ea, size, bpttype)
def AddBpt(ea): return AddBptEx(ea, 0, BPT_SOFT) def AddBpt(ea):
return AddBptEx(ea, 0, BPT_SOFT)
def DelBpt(ea): def DelBpt(ea):
@ -7499,17 +7500,17 @@ def WriteExe(filepath):
return GenerateFile(OFILE_EXE, filepath, 0, BADADDR, 0) return GenerateFile(OFILE_EXE, filepath, 0, BADADDR, 0)
def AddConst(enum_id,name,value): return AddConstEx(enum_id,name,value,-1) def AddConst(enum_id,name,value): return AddConstEx(enum_id,name,value,-1)
def AddStruc(index,name): return AddStrucEx(index,name,0) def AddStruc(index,name): return AddStrucEx(index,name,0)
def AddUnion(index,name): return AddStrucEx(index,name,1) def AddUnion(index,name): return AddStrucEx(index,name,1)
def OpStroff(ea,n,strid): return OpStroffEx(ea,n,strid,0) def OpStroff(ea,n,strid): return OpStroffEx(ea,n,strid,0)
def OpEnum(ea,n,enumid): return OpEnumEx(ea,n,enumid,0) def OpEnum(ea,n,enumid): return OpEnumEx(ea,n,enumid,0)
def DelConst(constid, v, mask): return DelConstEx(constid, v, 0, mask) def DelConst(constid, v, mask): return DelConstEx(constid, v, 0, mask)
def GetConst(constid, v, mask): return GetConstEx(constid, v, 0, mask) def GetConst(constid, v, mask): return GetConstEx(constid, v, 0, mask)
def AnalyseArea(sEA, eEA): return AnalyzeArea(sEA,eEA) def AnalyseArea(sEA, eEA): return AnalyzeArea(sEA,eEA)
def MakeStruct(ea,name): return MakeStructEx(ea, -1, name) def MakeStruct(ea,name): return MakeStructEx(ea, -1, name)
def Name(ea): return NameEx(BADADDR, ea) def Name(ea): return NameEx(BADADDR, ea)
def GetTrueName(ea): return GetTrueNameEx(BADADDR, ea) def GetTrueName(ea): return GetTrueNameEx(BADADDR, ea)
def MakeName(ea, name): return MakeNameEx(ea,name,SN_CHECK) def MakeName(ea, name): return MakeNameEx(ea,name,SN_CHECK)
#def GetFrame(ea): return GetFunctionAttr(ea, FUNCATTR_FRAME) #def GetFrame(ea): return GetFunctionAttr(ea, FUNCATTR_FRAME)
@ -7533,6 +7534,8 @@ def SegDefReg(ea, reg, value): return SetSegDefReg(ea, reg, va
def Comment(ea): return GetCommentEx(ea, 0) def Comment(ea): return GetCommentEx(ea, 0)
"""Returns the non-repeatable comment or None"""
def RptCmt(ea): return GetCommentEx(ea, 1) def RptCmt(ea): return GetCommentEx(ea, 1)
def SetReg(ea, reg, value): return SetRegEx(ea, reg, value, SR_user) def SetReg(ea, reg, value): return SetRegEx(ea, reg, value, SR_user)

View File

@ -293,7 +293,7 @@ int idaapi DBG_Callback(void *ud, int notification_code, va_list va)
} }
catch (Swig::DirectorException &) catch (Swig::DirectorException &)
{ {
msg("Exception in IDP Hook function:\n"); msg("Exception in DBG Hook function:\n");
if (PyErr_Occurred()) if (PyErr_Occurred())
{ {
PyErr_Print(); PyErr_Print();

View File

@ -713,7 +713,7 @@ int idaapi IDB_Callback(void *ud, int notification_code, va_list va)
} }
catch (Swig::DirectorException &) catch (Swig::DirectorException &)
{ {
msg("Exception in IDP Hook function:\n"); msg("Exception in IDB Hook function:\n");
if (PyErr_Occurred()) if (PyErr_Occurred())
{ {
PyErr_Print(); PyErr_Print();

View File

@ -2862,9 +2862,9 @@ class simplecustviewer_t(object):
return _idaapi.pyscv_get_pos(self.__this, mouse) return _idaapi.pyscv_get_pos(self.__this, mouse)
def GetLineNo(self, mouse = 0): def GetLineNo(self, mouse = 0):
"""Calls GetPos() and returns the current line number only or None on failure""" """Calls GetPos() and returns the current line number or -1 on failure"""
r = self.GetPos(mouse) r = self.GetPos(mouse)
return None if not r else r[0] return -1 if not r else r[0]
def Jump(self, lineno, x=0, y=0): def Jump(self, lineno, x=0, y=0):
return _idaapi.pyscv_jumpto(self.__this, lineno, x, y) return _idaapi.pyscv_jumpto(self.__this, lineno, x, y)

View File

@ -116,6 +116,8 @@
%ignore apply_type_to_stkarg; %ignore apply_type_to_stkarg;
%rename (apply_type_to_stkarg) py_apply_type_to_stkarg; %rename (apply_type_to_stkarg) py_apply_type_to_stkarg;
%ignore print_type;
%rename (print_type) py_print_type;
%ignore use_regarg_type_cb; %ignore use_regarg_type_cb;
%ignore set_op_type_t; %ignore set_op_type_t;
@ -201,6 +203,31 @@ PyObject *py_get_type_size0(const til_t *ti, PyObject *tp)
return PyInt_FromLong(sz); return PyInt_FromLong(sz);
} }
//-------------------------------------------------------------------------
/*
#<pydoc>
def print_type(ea, on_line):
"""
Returns the type of an item
@return:
- None on failure
- The type string with a semicolon. Can be used directly with idc.SetType()
"""
pass
#</pydoc>
*/
static PyObject *py_print_type(ea_t ea, bool one_line)
{
char buf[MAXSTR];
if ( print_type(ea, buf, sizeof(buf), one_line) )
{
qstrncat(buf, ";", sizeof(buf));
return PyString_FromString(buf);
}
else
Py_RETURN_NONE;
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
/* /*
#<pydoc> #<pydoc>