mirror of
https://github.com/cemu-project/idapython.git
synced 2024-11-27 19:44:18 +01:00
- IDA Pro 6.3 support
- The Functions() generator function now accepts function tail start parameter - Added into idc.py: DbgRead/DbgWrite/SetTargetAssembler and stack pointer related functions - Wrapped more type info related functions
This commit is contained in:
parent
4d21b10dc4
commit
69d5c83d28
@ -1,5 +1,11 @@
|
||||
Please see http://code.google.com/p/idapython/source/list for a detailed list of changes.
|
||||
|
||||
Changes from version 1.5.4 to 1.5.5
|
||||
------------------------------------
|
||||
- IDA Pro 6.3 support
|
||||
- The Functions() generator function now accepts function tail start parameter
|
||||
- Added into idc.py: DbgRead/DbgWrite/SetTargetAssembler and stack pointer related functions
|
||||
- Wrapped more type info related functions
|
||||
|
||||
Changes from version 1.5.3 to 1.5.4
|
||||
------------------------------------
|
||||
|
15
build.py
15
build.py
@ -24,7 +24,7 @@ from distutils import sysconfig
|
||||
VERBOSE = True
|
||||
|
||||
IDA_MAJOR_VERSION = 6
|
||||
IDA_MINOR_VERSION = 2
|
||||
IDA_MINOR_VERSION = 3
|
||||
|
||||
if 'IDA' in os.environ:
|
||||
IDA_SDK = os.environ['IDA']
|
||||
@ -36,7 +36,7 @@ else:
|
||||
# IDAPython version
|
||||
VERSION_MAJOR = 1
|
||||
VERSION_MINOR = 5
|
||||
VERSION_PATCH = 4
|
||||
VERSION_PATCH = 5
|
||||
|
||||
# Determine Python version
|
||||
PYTHON_MAJOR_VERSION = int(platform.python_version()[0])
|
||||
@ -319,10 +319,11 @@ def build_plugin(platform, idasdkdir, plugin_name, ea64):
|
||||
builder = GCCBuilder()
|
||||
platform_macros = [ "__LINUX__" ]
|
||||
python_libpath = os.path.join(sysconfig.EXEC_PREFIX, "lib")
|
||||
python_library = "-lpython%d.%d" % (PYTHON_MAJOR_VERSION, PYTHON_MINOR_VERSION)
|
||||
python_library = "-Bdynamic -lpython%d.%d" % (PYTHON_MAJOR_VERSION, PYTHON_MINOR_VERSION)
|
||||
ida_libpath = os.path.join(idasdkdir, "lib", ea64 and "x86_linux_gcc_64" or "x86_linux_gcc_32")
|
||||
ida_lib = ""
|
||||
extra_link_parameters = ""
|
||||
extra_link_parameters = " -s"
|
||||
builder.compiler_parameters += " -O2"
|
||||
# Platform-specific settings for the Windows build
|
||||
elif platform == "win32":
|
||||
builder = MSVCBuilder()
|
||||
@ -333,6 +334,7 @@ def build_plugin(platform, idasdkdir, plugin_name, ea64):
|
||||
ida_lib = "ida.lib"
|
||||
SWIG_OPTIONS += " -D__NT__ "
|
||||
extra_link_parameters = ""
|
||||
builder.compiler_parameters += " -Ox"
|
||||
# Platform-specific settings for the Mac OS X build
|
||||
elif platform == "macosx":
|
||||
builder = GCCBuilder()
|
||||
@ -342,7 +344,8 @@ def build_plugin(platform, idasdkdir, plugin_name, ea64):
|
||||
python_library = "-framework Python"
|
||||
ida_libpath = os.path.join(idasdkdir, "lib", ea64 and "x86_mac_gcc_64" or "x86_mac_gcc_32")
|
||||
ida_lib = ea64 and "-lida64" or "-lida"
|
||||
extra_link_parameters = ""
|
||||
extra_link_parameters = " -s"
|
||||
builder.compiler_parameters += " -O3"
|
||||
|
||||
assert builder, "Unknown platform! No idea how to build here..."
|
||||
|
||||
@ -350,6 +353,8 @@ def build_plugin(platform, idasdkdir, plugin_name, ea64):
|
||||
if ea64:
|
||||
platform_macros.append("__EA64__")
|
||||
|
||||
platform_macros.append("NDEBUG")
|
||||
|
||||
if not '--no-early-load' in sys.argv:
|
||||
platform_macros.append("PLUGINFIX")
|
||||
|
||||
|
@ -8,3 +8,7 @@ REMOVE_CWD_SYS_PATH = 0
|
||||
// Script timeout (in seconds)
|
||||
// (A value of 0 disables the timeout)
|
||||
SCRIPT_TIMEOUT = 3
|
||||
|
||||
// Use a local Python library
|
||||
// If enabled, the "lib" directory tree with modules must be present in IDADIR/python
|
||||
USE_LOCAL_PYTHON = 0
|
||||
|
56
python.cpp
56
python.cpp
@ -125,6 +125,7 @@ static int script_timeout = 2;
|
||||
static bool g_ui_ready = false;
|
||||
static bool g_alert_auto_scripts = true;
|
||||
static bool g_remove_cwd_sys_path = false;
|
||||
static bool g_use_local_python = false;
|
||||
|
||||
static void end_execution();
|
||||
static void begin_execution();
|
||||
@ -369,6 +370,11 @@ const char *idaapi set_python_options(
|
||||
g_remove_cwd_sys_path = *(uval_t *)value != 0;
|
||||
break;
|
||||
}
|
||||
else if ( qstrcmp(keyword, "USE_LOCAL_PYTHON") == 0 )
|
||||
{
|
||||
g_use_local_python = *(uval_t *)value != 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return IDPOPT_BADKEY;
|
||||
} while (false);
|
||||
@ -466,7 +472,10 @@ static bool IDAPython_ExecFile(const char *FileName, char *errbuf, size_t errbuf
|
||||
{
|
||||
PyObject *py_execscript = get_idaapi_attr(S_IDAAPI_EXECSCRIPT);
|
||||
if ( py_execscript == NULL )
|
||||
{
|
||||
qstrncpy(errbuf, "Could not find idaapi." S_IDAAPI_EXECSCRIPT " ?!", errbufsz);
|
||||
return false;
|
||||
}
|
||||
|
||||
char script[MAXSTR];
|
||||
qstrncpy(script, FileName, sizeof(script));
|
||||
@ -1288,6 +1297,25 @@ static void sanitize_path()
|
||||
PySys_SetPath(newpath.begin());
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// we have to do it ourselves because Python 2.7 calls exit() if importing site fails
|
||||
static bool initsite(void)
|
||||
{
|
||||
PyObject *m;
|
||||
m = PyImport_ImportModule("site");
|
||||
if (m == NULL)
|
||||
{
|
||||
PyErr_Print();
|
||||
Py_Finalize();
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
Py_DECREF(m);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Initialize the Python environment
|
||||
bool IDAPython_Init(void)
|
||||
@ -1306,12 +1334,11 @@ bool IDAPython_Init(void)
|
||||
char tmp[QMAXPATH];
|
||||
#ifdef __LINUX__
|
||||
// Export symbols from libpython to resolve imported module deps
|
||||
qsnprintf(tmp, sizeof(tmp), "libpython%d.%d.so.1",
|
||||
PY_MAJOR_VERSION,
|
||||
PY_MINOR_VERSION);
|
||||
if ( !dlopen(tmp, RTLD_NOLOAD | RTLD_GLOBAL | RTLD_LAZY) )
|
||||
// use the standard soname: libpython2.7.so.1.0
|
||||
#define PYLIB "libpython" QSTRINGIZE(PY_MAJOR_VERSION) "." QSTRINGIZE(PY_MINOR_VERSION) ".so.1.0"
|
||||
if ( !dlopen(PYLIB, RTLD_NOLOAD | RTLD_GLOBAL | RTLD_LAZY) )
|
||||
{
|
||||
warning("IDAPython: %s", dlerror());
|
||||
warning("IDAPython dlopen(" PYLIB ") error: %s", dlerror());
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
@ -1350,16 +1377,31 @@ bool IDAPython_Init(void)
|
||||
}
|
||||
}
|
||||
|
||||
if ( g_use_local_python )
|
||||
Py_SetPythonHome(g_idapython_dir);
|
||||
|
||||
// don't import "site" right now
|
||||
Py_NoSiteFlag = 1;
|
||||
|
||||
// Start the interpreter
|
||||
Py_Initialize();
|
||||
|
||||
if ( !Py_IsInitialized() )
|
||||
{
|
||||
warning("IDAPython: Py_Initialize() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// remove current directory
|
||||
sanitize_path();
|
||||
|
||||
// import "site"
|
||||
if ( !g_use_local_python && !initsite() )
|
||||
{
|
||||
warning("IDAPython: importing \"site\" failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enable multi-threading support
|
||||
if ( !PyEval_ThreadsInitialized() )
|
||||
PyEval_InitThreads();
|
||||
@ -1416,7 +1458,7 @@ bool IDAPython_Init(void)
|
||||
parse_plugin_options();
|
||||
|
||||
// Register a RunPythonStatement() function for IDC
|
||||
set_idc_func(S_IDC_RUNPYTHON_STATEMENT, idc_runpythonstatement, idc_runpythonstatement_args);
|
||||
set_idc_func_ex(S_IDC_RUNPYTHON_STATEMENT, idc_runpythonstatement, idc_runpythonstatement_args, 0);
|
||||
|
||||
// A script specified on the command line is run
|
||||
if ( g_run_when == run_on_init )
|
||||
@ -1463,7 +1505,7 @@ void IDAPython_Term(void)
|
||||
deinit_pywraps();
|
||||
|
||||
// Uninstall IDC function
|
||||
set_idc_func(S_IDC_RUNPYTHON_STATEMENT, NULL, NULL);
|
||||
set_idc_func_ex(S_IDC_RUNPYTHON_STATEMENT, NULL, NULL, 0);
|
||||
|
||||
// Shut the interpreter down
|
||||
Py_Finalize();
|
||||
|
@ -217,9 +217,14 @@ def Functions(start=None, end=None):
|
||||
if not start: start = idaapi.cvar.inf.minEA
|
||||
if not end: end = idaapi.cvar.inf.maxEA
|
||||
|
||||
func = idaapi.get_func(start)
|
||||
if not func:
|
||||
func = idaapi.get_next_func(start)
|
||||
# find first function head chunk in the range
|
||||
chunk = idaapi.get_fchunk(start)
|
||||
if not chunk:
|
||||
chunk = idaapi.get_next_fchunk(start)
|
||||
while chunk and chunk.startEA < end and (chunk.flags & idaapi.FUNC_TAIL) != 0:
|
||||
chunk = idaapi.get_next_fchunk(chunk.startEA)
|
||||
func = chunk
|
||||
|
||||
while func and func.startEA < end:
|
||||
startea = func.startEA
|
||||
yield startea
|
||||
|
208
python/idc.py
208
python/idc.py
@ -1772,6 +1772,35 @@ def DbgQword(ea):
|
||||
return __DbgValue(ea, 8)
|
||||
|
||||
|
||||
def DbgRead(ea, size):
|
||||
"""
|
||||
Read from debugger memory.
|
||||
|
||||
@param ea: linear address
|
||||
@param size: size of data to read
|
||||
@return: data as a string. If failed, If failed, throws an exception
|
||||
|
||||
Thread-safe function (may be called only from the main thread and debthread)
|
||||
"""
|
||||
return idaapi.dbg_read_memory(ea, size)
|
||||
|
||||
|
||||
def DbgWrite(ea, data):
|
||||
"""
|
||||
Write to debugger memory.
|
||||
|
||||
@param ea: linear address
|
||||
@param data: string to write
|
||||
@return: number of written bytes (-1 - network/debugger error)
|
||||
|
||||
Thread-safe function (may be called only from the main thread and debthread)
|
||||
"""
|
||||
if not idaapi.dbg_can_query():
|
||||
return -1
|
||||
elif len(data) > 0:
|
||||
return idaapi.dbg_write_memory(ea, data)
|
||||
|
||||
|
||||
def GetOriginalByte(ea):
|
||||
"""
|
||||
Get original value of program byte
|
||||
@ -2867,6 +2896,16 @@ def SetProcessorType (processor, level):
|
||||
"""
|
||||
return idaapi.set_processor_type(processor, level)
|
||||
|
||||
def SetTargetAssembler(asmidx):
|
||||
"""
|
||||
Set target assembler
|
||||
@param asmidx: index of the target assembler in the array of
|
||||
assemblers for the current processor.
|
||||
|
||||
@return: 1-ok, 0-failed
|
||||
"""
|
||||
return idaapi.set_target_assembler(asmidx)
|
||||
|
||||
SETPROC_COMPAT = idaapi.SETPROC_COMPAT
|
||||
SETPROC_ALL = idaapi.SETPROC_ALL
|
||||
SETPROC_USER = idaapi.SETPROC_USER
|
||||
@ -4340,6 +4379,75 @@ def SetSpDiff(ea, delta):
|
||||
return idaapi.add_user_stkpnt(ea, delta)
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# S T A C K
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
def AddAutoStkPnt2(func_ea, ea, delta):
|
||||
"""
|
||||
Add automatical SP register change point
|
||||
@param func_ea: function start
|
||||
@param ea: linear address where SP changes
|
||||
usually this is the end of the instruction which
|
||||
modifies the stack pointer (cmd.ea+cmd.size)
|
||||
@param delta: difference between old and new values of SP
|
||||
@return: 1-ok, 0-failed
|
||||
"""
|
||||
pfn = idaapi.get_func(func_ea)
|
||||
if not pfn:
|
||||
return 0
|
||||
return idaapi.add_auto_stkpnt2(pfn, ea, delta)
|
||||
|
||||
def AddUserStkPnt(ea, delta):
|
||||
"""
|
||||
Add user-defined SP register change point.
|
||||
|
||||
@param ea: linear address where SP changes
|
||||
@param delta: difference between old and new values of SP
|
||||
|
||||
@return: 1-ok, 0-failed
|
||||
"""
|
||||
return idaapi.add_user_stkpnt(ea, delta);
|
||||
|
||||
def DelStkPnt(func_ea, ea):
|
||||
"""
|
||||
Delete SP register change point
|
||||
|
||||
@param func_ea: function start
|
||||
@param ea: linear address
|
||||
@return: 1-ok, 0-failed
|
||||
"""
|
||||
pfn = idaapi.get_func(func_ea)
|
||||
if not pfn:
|
||||
return 0
|
||||
return idaapi.del_stkpnt(pfn, ea)
|
||||
|
||||
def GetMinSpd(func_ea):
|
||||
"""
|
||||
Return the address with the minimal spd (stack pointer delta)
|
||||
If there are no SP change points, then return BADADDR.
|
||||
|
||||
@param func_ea: function start
|
||||
@return: BADDADDR - no such function
|
||||
"""
|
||||
pfn = idaapi.get_func(func_ea)
|
||||
if not pfn:
|
||||
return BADADDR
|
||||
return idaapi.get_min_spd_ea(pfn)
|
||||
|
||||
def RecalcSpd(cur_ea):
|
||||
"""
|
||||
Recalculate SP delta for an instruction that stops execution.
|
||||
|
||||
@param cur_ea: linear address of the current instruction
|
||||
@return: 1 - new stkpnt is added, 0 - nothing is changed
|
||||
"""
|
||||
return idaapi.recalc_spd(cur_ea)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# E N T R Y P O I N T S
|
||||
# ----------------------------------------------------------------------------
|
||||
@ -4458,9 +4566,9 @@ def GetFixupTgtType(ea):
|
||||
@return: -1 - no fixup at the specified address
|
||||
otherwise returns fixup target type:
|
||||
"""
|
||||
fd = idaapi.get_fixup(ea)
|
||||
fd = idaapi.fixup_data_t()
|
||||
|
||||
if not fd:
|
||||
if not idaapi.get_fixup(ea, fd):
|
||||
return -1
|
||||
|
||||
return fd.type
|
||||
@ -4504,8 +4612,12 @@ def GetFixupTgtSel(ea):
|
||||
@return: -1 - no fixup at the specified address
|
||||
otherwise returns fixup target selector
|
||||
"""
|
||||
fd = idaapi.get_fixup(ea)
|
||||
return -1 if not fd else fd.sel
|
||||
fd = idaapi.fixup_data_t()
|
||||
|
||||
if not idaapi.get_fixup(ea, fd):
|
||||
return -1
|
||||
|
||||
return fd.sel
|
||||
|
||||
|
||||
def GetFixupTgtOff(ea):
|
||||
@ -4517,8 +4629,12 @@ def GetFixupTgtOff(ea):
|
||||
@return: -1 - no fixup at the specified address
|
||||
otherwise returns fixup target offset
|
||||
"""
|
||||
fd = idaapi.get_fixup(ea)
|
||||
return -1 if not fd else fd.off
|
||||
fd = idaapi.fixup_data_t()
|
||||
|
||||
if not idaapi.get_fixup(ea, fd):
|
||||
return -1
|
||||
|
||||
return fd.off
|
||||
|
||||
|
||||
def GetFixupTgtDispl(ea):
|
||||
@ -4530,8 +4646,12 @@ def GetFixupTgtDispl(ea):
|
||||
@return: -1 - no fixup at the specified address
|
||||
otherwise returns fixup target displacement
|
||||
"""
|
||||
fd = idaapi.get_fixup(ea)
|
||||
return -1 if not fd else fd.displacement
|
||||
fd = idaapi.fixup_data_t()
|
||||
|
||||
if not idaapi.get_fixup(ea, fd):
|
||||
return -1
|
||||
|
||||
return fd.displacement
|
||||
|
||||
|
||||
def SetFixup(ea, fixuptype, targetsel, targetoff, displ):
|
||||
@ -4791,6 +4911,30 @@ def GetMemberQty(sid):
|
||||
return -1 if not s else s.memqty
|
||||
|
||||
|
||||
def GetMemberId(sid, member_offset):
|
||||
"""
|
||||
@param sid: structure type ID
|
||||
@param member_offset:. The offset can be
|
||||
any offset in the member. For example,
|
||||
is a member is 4 bytes long and starts
|
||||
at offset 2, then 2,3,4,5 denote
|
||||
the same structure member.
|
||||
|
||||
@return: -1 if bad structure type ID is passed or there is
|
||||
no member at the specified offset.
|
||||
otherwise returns the member id.
|
||||
"""
|
||||
s = idaapi.get_struc(sid)
|
||||
if not s:
|
||||
return -1
|
||||
|
||||
m = idaapi.get_member(s, member_offset)
|
||||
if not m:
|
||||
return -1
|
||||
|
||||
return m.id
|
||||
|
||||
|
||||
def GetStrucPrevOff(sid, offset):
|
||||
"""
|
||||
Get previous offset in a structure
|
||||
@ -6633,6 +6777,15 @@ def SizeOf(typestr):
|
||||
"""
|
||||
return idaapi.get_type_size0(idaapi.cvar.idati, typestr)
|
||||
|
||||
def GetTinfo(ea):
|
||||
"""
|
||||
Get type information of function/variable as 'typeinfo' object
|
||||
|
||||
@param ea: the address of the object
|
||||
@return: None on failure, or (type, fields) tuple.
|
||||
"""
|
||||
return idaapi.idc_get_type_raw(ea)
|
||||
|
||||
def GuessType(ea):
|
||||
"""
|
||||
Guess type of function/variable
|
||||
@ -6652,11 +6805,16 @@ def SetType(ea, newtype):
|
||||
@param newtype: the type string in C declaration form.
|
||||
Must contain the closing ';'
|
||||
if specified as an empty string, then the
|
||||
assciated with 'ea' will be deleted
|
||||
item associated with 'ea' will be deleted.
|
||||
|
||||
@return: 1-ok, 0-failed.
|
||||
"""
|
||||
if newtype is not '':
|
||||
return idaapi.apply_cdecl2(idaapi.cvar.idati, ea, newtype)
|
||||
if idaapi.has_ti(ea):
|
||||
idaapi.del_tinfo(ea)
|
||||
return True
|
||||
return False
|
||||
|
||||
def ParseType(inputtype, flags):
|
||||
"""
|
||||
@ -7680,6 +7838,29 @@ def SetBptAttr(address, bptattr, value):
|
||||
idaapi.update_bpt(bpt)
|
||||
return True
|
||||
|
||||
def SetBptCndEx(ea, cnd, is_lowcnd):
|
||||
"""
|
||||
Set breakpoint condition
|
||||
|
||||
@param ea: any address in the breakpoint range
|
||||
@param cnd: breakpoint condition
|
||||
@param is_lowcnd: 0 - regular condition, 1 - low level condition
|
||||
|
||||
@return: success
|
||||
"""
|
||||
bpt = idaapi.bpt_t()
|
||||
|
||||
if not idaapi.get_bpt(ea, bpt):
|
||||
return False
|
||||
|
||||
bpt.condition = cnd
|
||||
if not is_lowcnd:
|
||||
bpt.flags |= BPT_LOWCND
|
||||
else:
|
||||
bpt.flags &= ~BPT_LOWCND
|
||||
|
||||
return idaapi.update_bpt(bpt)
|
||||
|
||||
|
||||
def SetBptCnd(ea, cnd):
|
||||
"""
|
||||
@ -7690,14 +7871,7 @@ def SetBptCnd(ea, cnd):
|
||||
|
||||
@return: success
|
||||
"""
|
||||
bpt = idaapi.bpt_t()
|
||||
|
||||
if not idaapi.get_bpt(ea, bpt):
|
||||
return False
|
||||
|
||||
bpt.condition = cnd
|
||||
|
||||
return idaapi.update_bpt(bpt)
|
||||
return SetBptCndEx(ea, cnd, 0)
|
||||
|
||||
|
||||
def AddBptEx(ea, size, bpttype):
|
||||
|
@ -68,6 +68,8 @@ def print_banner():
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
# Redirect stderr and stdout to the IDA message window
|
||||
_orig_stdout = sys.stdout;
|
||||
_orig_stderr = sys.stderr;
|
||||
sys.stdout = sys.stderr = IDAPythonStdOut()
|
||||
|
||||
# Assign a default sys.argv
|
||||
|
@ -3,7 +3,7 @@
|
||||
rem Please use the same tag for the same .i file
|
||||
rem That means if many insertions are going to happen in one given .i file then don't use more than code marking tag
|
||||
|
||||
set PY=c:\python26\python.exe
|
||||
set PY=c:\python27\python.exe
|
||||
|
||||
echo.
|
||||
echo -------- DEPLOY started --------------------------------------------------
|
||||
|
@ -168,5 +168,5 @@ plugin_t PLUGIN =
|
||||
"", // multiline help about the plugin
|
||||
|
||||
"pywraps", // the preferred short name of the plugin
|
||||
"Alt-0" // the preferred hotkey to run the plugin
|
||||
"" // the preferred hotkey to run the plugin
|
||||
};
|
||||
|
@ -571,6 +571,14 @@ def test_gpa():
|
||||
|
||||
return 1
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
def test_loaddll():
|
||||
h = loadlib("twain_32.dll")
|
||||
if h == 0:
|
||||
print "failed to load twain32 library!"
|
||||
return -1
|
||||
return 1
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# Packs a simple structure (into the database) and unpacks it back using the idaapi methods
|
||||
def test_pck_idb_raw():
|
||||
@ -884,7 +892,7 @@ def test_exec_throw():
|
||||
# all the tests that take zero parameters
|
||||
tests0 = (test_gpa, test_pck_idb_raw, test_pck_bv_raw,
|
||||
test_unpack_raw, test_pck_idb, test_pck_bv,
|
||||
test_enum_files, test2, test_exec_throw)
|
||||
test_enum_files, test2, test_exec_throw, test_loaddll)
|
||||
test_log = None # test log file
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
@ -152,6 +152,16 @@ static PyObject *py_get_many_bytes(ea_t ea, unsigned int size)
|
||||
//---------------------------------------------------------------------------
|
||||
/*
|
||||
#<pydoc>
|
||||
# Conversion options for get_ascii_contents2():
|
||||
ACFOPT_ASCII = 0x00000000 # convert Unicode strings to ASCII
|
||||
ACFOPT_UTF16 = 0x00000001 # return UTF-16 (aka wide-char) array for Unicode strings
|
||||
# ignored for non-Unicode strings
|
||||
ACFOPT_UTF8 = 0x00000002 # convert Unicode strings to UTF-8
|
||||
# ignored for non-Unicode strings
|
||||
ACFOPT_CONVMASK = 0x0000000F
|
||||
ACFOPT_ESCAPE = 0x00000010 # for ACFOPT_ASCII, convert non-printable
|
||||
# characters to C escapes (\n, \xNN, \uNNNN)
|
||||
|
||||
def get_ascii_contents2(ea, len, type, flags = ACFOPT_ASCII):
|
||||
"""
|
||||
Get contents of ascii string
|
||||
|
@ -562,7 +562,7 @@ private:
|
||||
|
||||
void show()
|
||||
{
|
||||
open_tform(form, FORM_MDI|FORM_TAB|FORM_MENU);
|
||||
open_tform(form, FORM_TAB|FORM_MENU);
|
||||
}
|
||||
|
||||
static py_graph_t *extract_this(PyObject *self)
|
||||
@ -666,7 +666,7 @@ private:
|
||||
qsnprintf(grnode, sizeof(grnode), "$ pygraph %s", title);
|
||||
id.create(grnode);
|
||||
gv = create_graph_viewer(form, id, s_callback, this, 0);
|
||||
open_tform(form, FORM_MDI | FORM_TAB | FORM_MENU);
|
||||
open_tform(form, FORM_TAB | FORM_MENU);
|
||||
if ( gv != NULL )
|
||||
viewer_fit_window(gv);
|
||||
}
|
||||
|
@ -619,7 +619,7 @@ def parse_command_line(cmdline):
|
||||
static PyObject *py_parse_command_line(const char *cmdline)
|
||||
{
|
||||
qstrvec_t args;
|
||||
if ( parse_command_line(cmdline, &args) == 0 )
|
||||
if ( parse_command_line2(cmdline, &args, NULL) == 0 )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
PyObject *py_list = PyList_New(args.size());
|
||||
|
@ -494,7 +494,7 @@ in this case.
|
||||
This flag can be used to delay the code execution
|
||||
until the next UI loop run even from the main thread"""
|
||||
|
||||
def execute_sync(callable, reqf)
|
||||
def execute_sync(callable, reqf):
|
||||
"""
|
||||
Executes a function in the context of the main thread.
|
||||
If the current thread not the main thread, then the call is queued and
|
||||
@ -567,7 +567,7 @@ static int py_execute_sync(PyObject *py_callable, int reqf)
|
||||
/*
|
||||
#<pydoc>
|
||||
|
||||
def execute_ui_requests(callable_list)
|
||||
def execute_ui_requests(callable_list):
|
||||
"""
|
||||
Inserts a list of callables into the UI message processing queue.
|
||||
When the UI is ready it will call one callable.
|
||||
@ -760,7 +760,11 @@ class UI_Hooks(object):
|
||||
IDA is terminated and the database is already closed.
|
||||
The UI may close its windows in this callback.
|
||||
"""
|
||||
pass
|
||||
# if the user forgot to call unhook, do it for him
|
||||
self.unhook()
|
||||
|
||||
def __term__(self):
|
||||
self.term()
|
||||
|
||||
#</pydoc>
|
||||
*/
|
||||
@ -769,6 +773,7 @@ class UI_Hooks
|
||||
public:
|
||||
virtual ~UI_Hooks()
|
||||
{
|
||||
unhook();
|
||||
}
|
||||
|
||||
bool hook()
|
||||
|
@ -139,7 +139,7 @@ static bool plgform_show(
|
||||
PyObject *py_link,
|
||||
PyObject *py_obj,
|
||||
const char *caption,
|
||||
int options = FORM_MDI|FORM_TAB|FORM_MENU|FORM_RESTORE)
|
||||
int options = FORM_TAB|FORM_MENU|FORM_RESTORE)
|
||||
{
|
||||
DECL_PLGFORM;
|
||||
return plgform->show(py_obj, caption, options);
|
||||
|
@ -9,7 +9,7 @@ class PluginForm(object):
|
||||
"""
|
||||
|
||||
FORM_MDI = 0x01
|
||||
"""start by default as MDI"""
|
||||
"""start by default as MDI (obsolete)"""
|
||||
FORM_TAB = 0x02
|
||||
"""attached by default to a tab"""
|
||||
FORM_RESTORE = 0x04
|
||||
@ -38,7 +38,7 @@ class PluginForm(object):
|
||||
@param caption: The form caption
|
||||
@param options: One of PluginForm.FORM_ constants
|
||||
"""
|
||||
options |= PluginForm.FORM_MDI|PluginForm.FORM_TAB|PluginForm.FORM_MENU|PluginForm.FORM_RESTORE
|
||||
options |= PluginForm.FORM_TAB|PluginForm.FORM_MENU|PluginForm.FORM_RESTORE
|
||||
return _idaapi.plgform_show(self.__clink__, self, caption, options)
|
||||
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
%ignore auto_save;
|
||||
%ignore auto_term;
|
||||
%ignore ea_without_xrefs;
|
||||
%ignore postpone_lastinsn_analysis;
|
||||
|
||||
%include "auto.hpp"
|
||||
|
||||
|
10
swig/bytes.i
10
swig/bytes.i
@ -764,6 +764,16 @@ static PyObject *py_get_many_bytes(ea_t ea, unsigned int size)
|
||||
//---------------------------------------------------------------------------
|
||||
/*
|
||||
#<pydoc>
|
||||
# Conversion options for get_ascii_contents2():
|
||||
ACFOPT_ASCII = 0x00000000 # convert Unicode strings to ASCII
|
||||
ACFOPT_UTF16 = 0x00000001 # return UTF-16 (aka wide-char) array for Unicode strings
|
||||
# ignored for non-Unicode strings
|
||||
ACFOPT_UTF8 = 0x00000002 # convert Unicode strings to UTF-8
|
||||
# ignored for non-Unicode strings
|
||||
ACFOPT_CONVMASK = 0x0000000F
|
||||
ACFOPT_ESCAPE = 0x00000010 # for ACFOPT_ASCII, convert non-printable
|
||||
# characters to C escapes (\n, \xNN, \uNNNN)
|
||||
|
||||
def get_ascii_contents2(ea, len, type, flags = ACFOPT_ASCII):
|
||||
"""
|
||||
Get contents of ascii string
|
||||
|
@ -62,9 +62,8 @@ static ea_t get_fchunk_referer(ea_t ea, size_t idx)
|
||||
def get_idasgn_desc(n):
|
||||
"""
|
||||
Get information about a signature in the list.
|
||||
It returns both:
|
||||
signame - the name of the signature
|
||||
optlibs - the names of the optional libraries
|
||||
It returns both: the name of the signature, and names of the
|
||||
optional libraries
|
||||
|
||||
@param n: number of signature in the list (0..get_idasgn_qty()-1)
|
||||
@return: None on failure or tuple(signame, optlibs)
|
||||
|
@ -564,7 +564,7 @@ private:
|
||||
|
||||
void show()
|
||||
{
|
||||
open_tform(form, FORM_MDI|FORM_TAB|FORM_MENU);
|
||||
open_tform(form, FORM_TAB|FORM_MENU);
|
||||
}
|
||||
|
||||
static py_graph_t *extract_this(PyObject *self)
|
||||
@ -668,7 +668,7 @@ private:
|
||||
qsnprintf(grnode, sizeof(grnode), "$ pygraph %s", title);
|
||||
id.create(grnode);
|
||||
gv = create_graph_viewer(form, id, s_callback, this, 0);
|
||||
open_tform(form, FORM_MDI | FORM_TAB | FORM_MENU);
|
||||
open_tform(form, FORM_TAB | FORM_MENU);
|
||||
if ( gv != NULL )
|
||||
viewer_fit_window(gv);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
%constant size_t SIZE_MAX = size_t(-1);
|
||||
|
||||
// Enable automatic docstring generation
|
||||
%feature(autodoc);
|
||||
%feature(autodoc,0);
|
||||
|
||||
%define SWIG_DECLARE_PY_CLINKED_OBJECT(type)
|
||||
%inline %{
|
||||
@ -2694,7 +2694,7 @@ def parse_command_line(cmdline):
|
||||
static PyObject *py_parse_command_line(const char *cmdline)
|
||||
{
|
||||
qstrvec_t args;
|
||||
if ( parse_command_line(cmdline, &args) == 0 )
|
||||
if ( parse_command_line2(cmdline, &args, NULL) == 0 )
|
||||
Py_RETURN_NONE;
|
||||
|
||||
PyObject *py_list = PyList_New(args.size());
|
||||
|
@ -619,7 +619,7 @@ in this case.
|
||||
This flag can be used to delay the code execution
|
||||
until the next UI loop run even from the main thread"""
|
||||
|
||||
def execute_sync(callable, reqf)
|
||||
def execute_sync(callable, reqf):
|
||||
"""
|
||||
Executes a function in the context of the main thread.
|
||||
If the current thread not the main thread, then the call is queued and
|
||||
@ -692,7 +692,7 @@ static int py_execute_sync(PyObject *py_callable, int reqf)
|
||||
/*
|
||||
#<pydoc>
|
||||
|
||||
def execute_ui_requests(callable_list)
|
||||
def execute_ui_requests(callable_list):
|
||||
"""
|
||||
Inserts a list of callables into the UI message processing queue.
|
||||
When the UI is ready it will call one callable.
|
||||
@ -885,7 +885,11 @@ class UI_Hooks(object):
|
||||
IDA is terminated and the database is already closed.
|
||||
The UI may close its windows in this callback.
|
||||
"""
|
||||
pass
|
||||
# if the user forgot to call unhook, do it for him
|
||||
self.unhook()
|
||||
|
||||
def __term__(self):
|
||||
self.term()
|
||||
|
||||
#</pydoc>
|
||||
*/
|
||||
@ -894,6 +898,7 @@ class UI_Hooks
|
||||
public:
|
||||
virtual ~UI_Hooks()
|
||||
{
|
||||
unhook();
|
||||
}
|
||||
|
||||
bool hook()
|
||||
@ -2807,7 +2812,7 @@ static bool plgform_show(
|
||||
PyObject *py_link,
|
||||
PyObject *py_obj,
|
||||
const char *caption,
|
||||
int options = FORM_MDI|FORM_TAB|FORM_MENU|FORM_RESTORE)
|
||||
int options = FORM_TAB|FORM_MENU|FORM_RESTORE)
|
||||
{
|
||||
DECL_PLGFORM;
|
||||
return plgform->show(py_obj, caption, options);
|
||||
@ -5531,7 +5536,7 @@ class PluginForm(object):
|
||||
"""
|
||||
|
||||
FORM_MDI = 0x01
|
||||
"""start by default as MDI"""
|
||||
"""start by default as MDI (obsolete)"""
|
||||
FORM_TAB = 0x02
|
||||
"""attached by default to a tab"""
|
||||
FORM_RESTORE = 0x04
|
||||
@ -5560,7 +5565,7 @@ class PluginForm(object):
|
||||
@param caption: The form caption
|
||||
@param options: One of PluginForm.FORM_ constants
|
||||
"""
|
||||
options |= PluginForm.FORM_MDI|PluginForm.FORM_TAB|PluginForm.FORM_MENU|PluginForm.FORM_RESTORE
|
||||
options |= PluginForm.FORM_TAB|PluginForm.FORM_MENU|PluginForm.FORM_RESTORE
|
||||
return _idaapi.plgform_show(self.__clink__, self, caption, options)
|
||||
|
||||
|
||||
|
12
swig/pro.i
12
swig/pro.i
@ -83,7 +83,17 @@
|
||||
%ignore get_process_exit_code;
|
||||
%ignore BELOW_NORMAL_PRIORITY_CLASS;
|
||||
%ignore parse_command_line;
|
||||
%rename (parse_command_line) py_parse_command_line;
|
||||
%ignore parse_command_line2;
|
||||
%rename (parse_command_line2) py_parse_command_line;
|
||||
%ignore qgetenv;
|
||||
%ignore qsetenv;
|
||||
%ignore qctime;
|
||||
%ignore qlocaltime;
|
||||
%ignore qstrftime;
|
||||
%ignore qstrftime64;
|
||||
%ignore qstrtok;
|
||||
%ignore qstrlwr;
|
||||
%ignore qstrupr;
|
||||
%include "pro.h"
|
||||
|
||||
SWIG_DECLARE_PY_CLINKED_OBJECT(qstrvec_t)
|
||||
|
@ -87,6 +87,7 @@
|
||||
%ignore decorate_name;
|
||||
%ignore gen_decorate_name;
|
||||
%ignore calc_bare_name;
|
||||
%ignore calc_cpp_name;
|
||||
%ignore predicate_t;
|
||||
%ignore choose_named_type;
|
||||
%ignore get_default_align;
|
||||
@ -131,6 +132,14 @@
|
||||
|
||||
%ignore type_pair_vec_t::add_names;
|
||||
|
||||
%ignore format_data_info_t;
|
||||
%ignore valinfo_t;
|
||||
%ignore print_c_data;
|
||||
%ignore format_c_data;
|
||||
%ignore format_c_number;
|
||||
%ignore get_enum_member_expr;
|
||||
%ignore extend_sign;
|
||||
|
||||
// Kernel-only symbols
|
||||
%ignore init_til;
|
||||
%ignore save_til;
|
||||
@ -161,6 +170,7 @@
|
||||
|
||||
%rename (load_til) load_til_wrap;
|
||||
%rename (get_type_size0) py_get_type_size0;
|
||||
%rename (idc_get_type_raw) py_idc_get_type_raw;
|
||||
%rename (unpack_object_from_idb) py_unpack_object_from_idb;
|
||||
%rename (unpack_object_from_bv) py_unpack_object_from_bv;
|
||||
%rename (pack_object_to_idb) py_pack_object_to_idb;
|
||||
@ -519,6 +529,19 @@ int idc_parse_types(const char *input, int flags)
|
||||
return parse_decls(idati, input, (flags & 2) == 0 ? msg : NULL, hti);
|
||||
}
|
||||
|
||||
PyObject *py_idc_get_type_raw(ea_t ea)
|
||||
{
|
||||
qtype type, fields;
|
||||
if (get_tinfo(ea, &type, &fields))
|
||||
{
|
||||
return Py_BuildValue("(ss)", (char *)type.c_str(), (char *)fields.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
char *idc_get_type(ea_t ea, char *buf, size_t bufsize)
|
||||
{
|
||||
qtype type, fnames;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#
|
||||
import glob
|
||||
import sys
|
||||
import os
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
def extract_docs(lines, out):
|
||||
@ -68,16 +69,28 @@ def extract_docs(lines, out):
|
||||
in_inline = True
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
def gen_docs(path = '../swig/', outfn = 'idaapi.py', mask = '*.i'):
|
||||
out = []
|
||||
for fn in glob.glob(path + mask):
|
||||
f = open(fn, 'r')
|
||||
def gen_docs_from(file, out):
|
||||
f = open(file, 'r')
|
||||
lines = f.readlines()
|
||||
f.close()
|
||||
extract_docs(lines, out)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
def gen_docs(path = '../swig/', outfn = 'idaapi.py', mask = '*.i'):
|
||||
out = []
|
||||
|
||||
# idaapi contains definitions used by other modules
|
||||
# handle it first
|
||||
idaapi_i = os.path.join(path, 'idaapi.i')
|
||||
gen_docs_from(idaapi_i, out)
|
||||
|
||||
for fn in glob.glob(path + mask):
|
||||
fn = fn.replace('\\', '/')
|
||||
if fn != idaapi_i:
|
||||
gen_docs_from(fn, out)
|
||||
|
||||
f = open(outfn, 'w')
|
||||
f.write('"""This is a placeholder module used to document all the IDA SDK functions that are wrapped manually. You still need to import \'idaapi\' and not this module to use the functions"""\n')
|
||||
# f.write('"""This is a placeholder module used to document all the IDA SDK functions that are wrapped manually. You still need to import \'idaapi\' (not this module) to use the functions"""\n')
|
||||
f.write('\n'.join(out))
|
||||
f.close()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user