- Experimental: integrated Hex-Rays Decompiler bindings that were contributed by EiNSTeiN:

https://github.com/EiNSTeiN-/hexrays-python
- Added '--with-hexrays' switch to the build script so it wrap Hex-Rays Decompiler API
- Added one Hex-Rays decompiler sample: vds1.py
This commit is contained in:
elias.bachaalany@gmail.com 2013-07-03 01:40:54 +00:00
parent ce06fdd7d2
commit db58b31711
13 changed files with 3221 additions and 1928 deletions

View File

@ -42,6 +42,9 @@ Make sure all the needed tools (compiler, swig) are on the PATH.
swigsdk-versions/x.y/ - A supported version of the IDA SDK swigsdk-versions/x.y/ - A supported version of the IDA SDK
idapython/ - IDAPython source code idapython/ - IDAPython source code
Note: To build with Hex-Rays decompiler support, please copy hexrays.hpp from
the decompiler SDK folder into IDA's include folder (in the SDK).
2. On Mac OS X copy libida.dylib from the IDA install directory to 2. On Mac OS X copy libida.dylib from the IDA install directory to
swigsdk-versions/x.y/lib/x86_mac_gcc_32/ swigsdk-versions/x.y/lib/x86_mac_gcc_32/
and libida64.dylib to and libida64.dylib to

View File

@ -1,5 +1,14 @@
Please see http://code.google.com/p/idapython/source/list for a detailed list of changes. Please see http://code.google.com/p/idapython/source/list for a detailed list of changes.
Changes from version 1.5.6 to 1.5.7
------------------------------------
- Added '--with-hexrays' switch to the build script so it wrap Hex-Rays Decompiler API
- Experimental: integrated Hex-Rays Decompiler bindings that were contributed by EiNSTeiN:
https://github.com/EiNSTeiN-/hexrays-python
- Added one Hex-Rays decompiler sample: vds1.py
- Fixed small mismatch between SWIG define and CL defines (/DNO_OBSOLETE_FUNCS)
- Use print_type2() instead of the deprecated function print_type()
Changes from version 1.5.5 to 1.5.6 Changes from version 1.5.5 to 1.5.6
------------------------------------ ------------------------------------
- IDA Pro 6.4 support - IDA Pro 6.4 support

View File

@ -45,6 +45,10 @@ PYTHON_MINOR_VERSION = int(platform.python_version()[2])
# Find Python headers # Find Python headers
PYTHON_INCLUDE_DIRECTORY = sysconfig.get_config_var('INCLUDEPY') PYTHON_INCLUDE_DIRECTORY = sysconfig.get_config_var('INCLUDEPY')
S_EA64 = 'ea64'
S_WITH_HEXRAYS = 'with-hexrays'
S_NO_OPT = 'no-opt'
# Swig command-line parameters # Swig command-line parameters
SWIG_OPTIONS = '-modern -python -c++ -w451 -shadow -D__GNUC__ -DNO_OBSOLETE_FUNCS' SWIG_OPTIONS = '-modern -python -c++ -w451 -shadow -D__GNUC__ -DNO_OBSOLETE_FUNCS'
@ -61,6 +65,7 @@ COMMON_MACROS = [
# Common includes for all compilations # Common includes for all compilations
COMMON_INCLUDES = [ ".", "swig" ] COMMON_INCLUDES = [ ".", "swig" ]
# -----------------------------------------------------------------------
# List files for the binary distribution # List files for the binary distribution
BINDIST_MANIFEST = [ BINDIST_MANIFEST = [
"README.txt", "README.txt",
@ -104,6 +109,7 @@ BINDIST_MANIFEST = [
"examples/ex_imports.py" "examples/ex_imports.py"
] ]
# -----------------------------------------------------------------------
# List files for the source distribution (appended to binary list) # List files for the source distribution (appended to binary list)
SRCDIST_MANIFEST = [ SRCDIST_MANIFEST = [
"BUILDING.txt", "BUILDING.txt",
@ -150,14 +156,31 @@ SRCDIST_MANIFEST = [
"swig/xref.i", "swig/xref.i",
"swig/graph.i", "swig/graph.i",
"swig/fpro.i", "swig/fpro.i",
"swig/hexrays.i",
"tools/gendocs.py", "tools/gendocs.py",
] ]
# -----------------------------------------------------------------------
def parse_options(args):
"""Parse arguments and returned a dictionary of options"""
no_opt = '--' + S_NO_OPT in sys.argv
ea64 = '--' + S_EA64 in sys.argv
with_hexrays = '--' + S_WITH_HEXRAYS in sys.argv
return {
S_EA64: ea64,
S_WITH_HEXRAYS: with_hexrays,
S_NO_OPT: no_opt
}
# -----------------------------------------------------------------------
class BuilderBase: class BuilderBase:
""" Base class for builders """ """ Base class for builders """
def __init__(self): def __init__(self):
pass pass
def compile(self, source, objectname=None, includes=[], macros=[]): def compile(self, source, objectname=None, includes=[], macros=[]):
""" """
Compile the source file Compile the source file
@ -187,6 +210,7 @@ class BuilderBase:
print cmdstring print cmdstring
return os.system(cmdstring) return os.system(cmdstring)
def link(self, objects, outfile, libpaths=[], libraries=[], extra_parameters=None): def link(self, objects, outfile, libpaths=[], libraries=[], extra_parameters=None):
""" Link the binary from objects and libraries """ """ Link the binary from objects and libraries """
cmdstring = "%s %s %s" % (self.linker, cmdstring = "%s %s %s" % (self.linker,
@ -217,6 +241,7 @@ class BuilderBase:
return macrostring return macrostring
# -----------------------------------------------------------------------
class GCCBuilder(BuilderBase): class GCCBuilder(BuilderBase):
""" Generic GCC compiler class """ """ Generic GCC compiler class """
def __init__(self): def __init__(self):
@ -241,6 +266,7 @@ class GCCBuilder(BuilderBase):
return "-o %s" % filename return "-o %s" % filename
# -----------------------------------------------------------------------
class MSVCBuilder(BuilderBase): class MSVCBuilder(BuilderBase):
""" Generic Visual C compiler class """ """ Generic Visual C compiler class """
def __init__(self): def __init__(self):
@ -266,7 +292,7 @@ class MSVCBuilder(BuilderBase):
def linker_out_string(self, filename): def linker_out_string(self, filename):
return "/out:%s" % filename return "/out:%s" % filename
# -----------------------------------------------------------------------
def build_distribution(manifest, distrootdir, ea64, nukeold): def build_distribution(manifest, distrootdir, ea64, nukeold):
""" Create a distibution to a directory and a ZIP file """ """ Create a distibution to a directory and a ZIP file """
# (Re)create the output directory # (Re)create the output directory
@ -307,7 +333,17 @@ def build_distribution(manifest, distrootdir, ea64, nukeold):
zip.close() zip.close()
def build_plugin(platform, idasdkdir, plugin_name, ea64): # -----------------------------------------------------------------------
def build_plugin(
platform,
idasdkdir,
plugin_name,
options):
# Get the arguments
ea64 = options[S_EA64]
with_hexrays = options[S_WITH_HEXRAYS]
global SWIG_OPTIONS global SWIG_OPTIONS
""" Build the plugin from the SWIG wrapper and plugin main source """ """ Build the plugin from the SWIG wrapper and plugin main source """
# Path to the IDA SDK headers # Path to the IDA SDK headers
@ -334,6 +370,7 @@ def build_plugin(platform, idasdkdir, plugin_name, ea64):
ida_lib = "ida.lib" ida_lib = "ida.lib"
SWIG_OPTIONS += " -D__NT__ " SWIG_OPTIONS += " -D__NT__ "
extra_link_parameters = "" extra_link_parameters = ""
if not options[S_NO_OPT]:
builder.compiler_parameters += " -Ox" builder.compiler_parameters += " -Ox"
# Platform-specific settings for the Mac OS X build # Platform-specific settings for the Mac OS X build
elif platform == "macosx": elif platform == "macosx":
@ -353,6 +390,11 @@ def build_plugin(platform, idasdkdir, plugin_name, ea64):
if ea64: if ea64:
platform_macros.append("__EA64__") platform_macros.append("__EA64__")
# Build with Hex-Rays decompiler
if with_hexrays:
platform_macros.append("WITH_HEXRAYS")
SWIG_OPTIONS += ' -DWITH_HEXRAYS '
platform_macros.append("NDEBUG") platform_macros.append("NDEBUG")
if not '--no-early-load' in sys.argv: if not '--no-early-load' in sys.argv:
@ -388,6 +430,7 @@ def build_plugin(platform, idasdkdir, plugin_name, ea64):
extra_link_parameters) extra_link_parameters)
assert res == 0, "Failed to link the plugin binary" assert res == 0, "Failed to link the plugin binary"
# -----------------------------------------------------------------------
def detect_platform(ea64): def detect_platform(ea64):
# Detect the platform # Detect the platform
system = platform.system() system = platform.system()
@ -410,7 +453,9 @@ def detect_platform(ea64):
return (system, platform_string, plugin_name) return (system, platform_string, plugin_name)
def build_binary_package(ea64, nukeold): # -----------------------------------------------------------------------
def build_binary_package(options, nukeold):
ea64 = options[S_EA64]
system, platform_string, plugin_name = detect_platform(ea64) system, platform_string, plugin_name = detect_platform(ea64)
BINDISTDIR = "idapython-%d.%d.%d_ida%d.%d_py%d.%d_%s" % (VERSION_MAJOR, BINDISTDIR = "idapython-%d.%d.%d_ida%d.%d_py%d.%d_%s" % (VERSION_MAJOR,
VERSION_MINOR, VERSION_MINOR,
@ -421,7 +466,7 @@ def build_binary_package(ea64, nukeold):
PYTHON_MINOR_VERSION, PYTHON_MINOR_VERSION,
platform_string) platform_string)
# Build the plugin # Build the plugin
build_plugin(platform_string, IDA_SDK, plugin_name, ea64) build_plugin(platform_string, IDA_SDK, plugin_name, options)
# Build the binary distribution # Build the binary distribution
binmanifest = [] binmanifest = []
@ -436,6 +481,7 @@ def build_binary_package(ea64, nukeold):
build_distribution(binmanifest, BINDISTDIR, ea64, nukeold) build_distribution(binmanifest, BINDISTDIR, ea64, nukeold)
# -----------------------------------------------------------------------
def build_source_package(): def build_source_package():
""" Build a directory and a ZIP file with all the sources """ """ Build a directory and a ZIP file with all the sources """
SRCDISTDIR = "idapython-%d.%d.%d" % (VERSION_MAJOR, SRCDISTDIR = "idapython-%d.%d.%d" % (VERSION_MAJOR,
@ -448,6 +494,7 @@ def build_source_package():
srcmanifest.extend([(x, "python") for x in "python/init.py", "python/idc.py", "python/idautils.py"]) srcmanifest.extend([(x, "python") for x in "python/init.py", "python/idc.py", "python/idautils.py"])
build_distribution(srcmanifest, SRCDISTDIR, ea64=False, nukeold=True) build_distribution(srcmanifest, SRCDISTDIR, ea64=False, nukeold=True)
# -----------------------------------------------------------------------
def gen_docs(z = False): def gen_docs(z = False):
print "Generating documentation....." print "Generating documentation....."
old_dir = os.getcwd() old_dir = os.getcwd()
@ -494,6 +541,7 @@ def gen_docs(z = False):
os.chdir(old_dir) os.chdir(old_dir)
return return
# -----------------------------------------------------------------------
def usage(): def usage():
print """IDAPython build script. print """IDAPython build script.
@ -504,23 +552,36 @@ Available switches:
Used with '--doc' switch. It will compress the generated documentation Used with '--doc' switch. It will compress the generated documentation
--ea64: --ea64:
Builds also the 64bit version of the plugin Builds also the 64bit version of the plugin
--with-hexrays:
Build with the Hex-Rays Decompiler wrappings
--no-early-load: --no-early-load:
The plugin will be compiled as normal plugin The plugin will be compiled as normal plugin
This switch disables processor, plugin and loader scripts This switch disables processor, plugin and loader scripts
""" """
# -----------------------------------------------------------------------
def main(): def main():
if '--help' in sys.argv: if '--help' in sys.argv:
return usage() return usage()
elif '--doc' in sys.argv: elif '--doc' in sys.argv:
return gen_docs(z = '--zip' in sys.argv) return gen_docs(z = '--zip' in sys.argv)
# Do 64-bit build? # Parse options
ea64 = '--ea64' in sys.argv options = parse_options(sys.argv)
build_binary_package(ea64=False, nukeold=True) ea64 = options[S_EA64]
# Always build the non __EA64__ version
options[S_EA64] = False
build_binary_package(options, nukeold=True)
# Rebuild package with __EA64__ if needed
if ea64: if ea64:
build_binary_package(ea64=True, nukeold=False) options[S_EA64] = True
build_binary_package(options, nukeold=False)
# Always build the source package
build_source_package() build_source_package()
# -----------------------------------------------------------------------
if __name__ == "__main__": if __name__ == "__main__":
main() main()

27
examples/vds1.py Normal file
View File

@ -0,0 +1,27 @@
import idaapi
def main():
if not idaapi.init_hexrays_plugin():
return False
print "Hex-rays version %s has been detected" % idaapi.get_hexrays_version()
f = idaapi.get_func(idaapi.get_screen_ea());
if f is None:
print "Please position the cursor within a function"
return True
cfunc = idaapi.decompile(f);
if cfunc is None:
print "Failed to decompile!"
return True
sv = cfunc.get_pseudocode();
for i in xrange(0, sv.size()):
line = idaapi.tag_remove(str(sv[i]));
print line
return True
if main():
idaapi.term_hexrays_plugin();

View File

@ -97,7 +97,7 @@
<ClCompile> <ClCompile>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\pywraps;..\..\include;\python27\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>.\pywraps;..\..\include;\python27\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NO_OBSOLETE_FUNCS;_DEBUG;__NT__;__IDP__;MAXSTR=1024;WIN32;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;USE_STANDARD_FILE_FUNCTIONS;VER_MAJOR=1;VER_MINOR=5;VER_PATCH=3;PLUGINFIX;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WITH_HEXRAYS;NO_OBSOLETE_FUNCS;_DEBUG;__NT__;__IDP__;MAXSTR=1024;WIN32;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;USE_STANDARD_FILE_FUNCTIONS;VER_MAJOR=1;VER_MINOR=5;VER_PATCH=3;PLUGINFIX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild> <MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
@ -302,6 +302,7 @@
</Bscmake> </Bscmake>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<None Include="build.py" />
<None Include="BUILDING.txt" /> <None Include="BUILDING.txt" />
<None Include="CHANGES.txt" /> <None Include="CHANGES.txt" />
<None Include="obj\x86_win_vc_32\idaapi.py" /> <None Include="obj\x86_win_vc_32\idaapi.py" />
@ -346,6 +347,7 @@
<None Include="swig\funcs.i" /> <None Include="swig\funcs.i" />
<None Include="swig\gdl.i" /> <None Include="swig\gdl.i" />
<None Include="swig\graph.i" /> <None Include="swig\graph.i" />
<None Include="swig\hexrays.i" />
<None Include="swig\ida.i" /> <None Include="swig\ida.i" />
<None Include="swig\idaapi.i" /> <None Include="swig\idaapi.i" />
<None Include="swig\idd.i" /> <None Include="swig\idd.i" />

View File

@ -293,6 +293,12 @@
<None Include="README.txt"> <None Include="README.txt">
<Filter>TEXT</Filter> <Filter>TEXT</Filter>
</None> </None>
<None Include="swig\hexrays.i">
<Filter>swig_i</Filter>
</None>
<None Include="build.py">
<Filter>py</Filter>
</None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="swig_i"> <Filter Include="swig_i">

View File

@ -30,6 +30,12 @@
#include <diskio.hpp> #include <diskio.hpp>
#include <loader.hpp> #include <loader.hpp>
#include <kernwin.hpp> #include <kernwin.hpp>
#ifdef WITH_HEXRAYS
#include <hexrays.hpp>
hexdsp_t *hexdsp = NULL;
#endif
#include "pywraps.hpp" #include "pywraps.hpp"
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -1313,16 +1319,18 @@ static bool initsite(void)
{ {
PyObject *m; PyObject *m;
m = PyImport_ImportModule("site"); m = PyImport_ImportModule("site");
if (m == NULL) if ( m == NULL )
{ {
PyErr_Print(); PyErr_Print();
Py_Finalize(); Py_Finalize();
return false; return false;
} }
else { else
{
Py_DECREF(m); Py_DECREF(m);
}
return true; return true;
}
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -1418,8 +1426,14 @@ bool IDAPython_Init(void)
// Init the SWIG wrapper // Init the SWIG wrapper
init_idaapi(); init_idaapi();
#ifdef Py_DEBUG
msg("HexraysPython: Python compiled with DEBUG enabled.\n");
#endif
// Set IDAPYTHON_VERSION in Python // Set IDAPYTHON_VERSION in Python
qsnprintf(tmp, sizeof(tmp), qsnprintf(
tmp,
sizeof(tmp),
"IDAPYTHON_VERSION=(%d, %d, %d, '%s', %d)\n" "IDAPYTHON_VERSION=(%d, %d, %d, '%s', %d)\n"
"IDAPYTHON_REMOVE_CWD_SYS_PATH = %s\n", "IDAPYTHON_REMOVE_CWD_SYS_PATH = %s\n",
VER_MAJOR, VER_MAJOR,
@ -1428,6 +1442,7 @@ bool IDAPython_Init(void)
VER_STATUS, VER_STATUS,
VER_SERIAL, VER_SERIAL,
g_remove_cwd_sys_path ? "True" : "False"); g_remove_cwd_sys_path ? "True" : "False");
PyRun_SimpleString(tmp); PyRun_SimpleString(tmp);
// Install extlang. Needs to be done before running init.py // Install extlang. Needs to be done before running init.py
@ -1467,7 +1482,11 @@ bool IDAPython_Init(void)
parse_plugin_options(); parse_plugin_options();
// Register a RunPythonStatement() function for IDC // Register a RunPythonStatement() function for IDC
set_idc_func_ex(S_IDC_RUNPYTHON_STATEMENT, idc_runpythonstatement, idc_runpythonstatement_args, 0); set_idc_func_ex(
S_IDC_RUNPYTHON_STATEMENT,
idc_runpythonstatement,
idc_runpythonstatement_args,
0);
// A script specified on the command line is run // A script specified on the command line is run
if ( g_run_when == run_on_init ) if ( g_run_when == run_on_init )

View File

@ -709,6 +709,7 @@ def RunPythonStatement(stmt):
#</pydoc> #</pydoc>
*/ */
/*
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// qstrvec_t wrapper // qstrvec_t wrapper
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -812,7 +813,7 @@ static bool qstrvec_t_remove(PyObject *self, size_t idx)
sv->erase(sv->begin()+idx); sv->erase(sv->begin()+idx);
return true; return true;
} }
*/
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
//</inline(py_idaapi)> //</inline(py_idaapi)>

View File

@ -207,72 +207,72 @@ class PyIdc_cvt_int64__(pyidc_cvt_helper__):
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
# qstrvec_t clinked object # qstrvec_t clinked object
class qstrvec_t(py_clinked_object_t): # class qstrvec_t(py_clinked_object_t):
"""Class representing an qstrvec_t""" # """Class representing an qstrvec_t"""
def __init__(self, items=None): # def __init__(self, items=None):
py_clinked_object_t.__init__(self) # py_clinked_object_t.__init__(self)
# Populate the list if needed # # Populate the list if needed
if items: # if items:
self.from_list(items) # self.from_list(items)
def _create_clink(self): # def _create_clink(self):
return _idaapi.qstrvec_t_create() # return _idaapi.qstrvec_t_create()
def _del_clink(self, lnk): # def _del_clink(self, lnk):
return _idaapi.qstrvec_t_destroy(lnk) # return _idaapi.qstrvec_t_destroy(lnk)
def _get_clink_ptr(self): # def _get_clink_ptr(self):
return _idaapi.qstrvec_t_get_clink_ptr(self) # return _idaapi.qstrvec_t_get_clink_ptr(self)
def assign(self, other): # def assign(self, other):
"""Copies the contents of 'other' to 'self'""" # """Copies the contents of 'other' to 'self'"""
return _idaapi.qstrvec_t_assign(self, other) # return _idaapi.qstrvec_t_assign(self, other)
def __setitem__(self, idx, s): # def __setitem__(self, idx, s):
"""Sets string at the given index""" # """Sets string at the given index"""
return _idaapi.qstrvec_t_set(self, idx, s) # return _idaapi.qstrvec_t_set(self, idx, s)
def __getitem__(self, idx): # def __getitem__(self, idx):
"""Gets the string at the given index""" # """Gets the string at the given index"""
return _idaapi.qstrvec_t_get(self, idx) # return _idaapi.qstrvec_t_get(self, idx)
def __get_size(self): # def __get_size(self):
return _idaapi.qstrvec_t_size(self) # return _idaapi.qstrvec_t_size(self)
size = property(__get_size) # size = property(__get_size)
"""Returns the count of elements""" # """Returns the count of elements"""
def addressof(self, idx): # def addressof(self, idx):
"""Returns the address (as number) of the qstring at the given index""" # """Returns the address (as number) of the qstring at the given index"""
return _idaapi.qstrvec_t_addressof(self, idx) # return _idaapi.qstrvec_t_addressof(self, idx)
def add(self, s): # def add(self, s):
"""Add a string to the vector""" # """Add a string to the vector"""
return _idaapi.qstrvec_t_add(self, s) # return _idaapi.qstrvec_t_add(self, s)
def from_list(self, lst): # def from_list(self, lst):
"""Populates the vector from a Python string list""" # """Populates the vector from a Python string list"""
return _idaapi.qstrvec_t_from_list(self, lst) # return _idaapi.qstrvec_t_from_list(self, lst)
def clear(self, qclear=False): # def clear(self, qclear=False):
""" # """
Clears all strings from the vector. # Clears all strings from the vector.
@param qclear: Just reset the size but do not actually free the memory # @param qclear: Just reset the size but do not actually free the memory
""" # """
return _idaapi.qstrvec_t_clear(self, qclear) # return _idaapi.qstrvec_t_clear(self, qclear)
def insert(self, idx, s): # def insert(self, idx, s):
"""Insert a string into the vector""" # """Insert a string into the vector"""
return _idaapi.qstrvec_t_insert(self, idx, s) # return _idaapi.qstrvec_t_insert(self, idx, s)
def remove(self, idx): # def remove(self, idx):
"""Removes a string from the vector""" # """Removes a string from the vector"""
return _idaapi.qstrvec_t_remove(self, idx) # return _idaapi.qstrvec_t_remove(self, idx)
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
class PyIdc_cvt_refclass__(pyidc_cvt_helper__): class PyIdc_cvt_refclass__(pyidc_cvt_helper__):

1111
swig/hexrays.i Normal file

File diff suppressed because it is too large Load Diff

View File

@ -100,6 +100,9 @@ static PyObject *type##_get_clink_ptr(PyObject *self)
#include "fpro.h" #include "fpro.h"
#include <map> #include <map>
#include "graph.hpp" #include "graph.hpp"
#ifdef WITH_HEXRAYS
#include "hexrays.hpp"
#endif
#include "pywraps.hpp" #include "pywraps.hpp"
//<code(py_idaapi)> //<code(py_idaapi)>
@ -2308,72 +2311,72 @@ class PyIdc_cvt_int64__(pyidc_cvt_helper__):
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
# qstrvec_t clinked object # qstrvec_t clinked object
class qstrvec_t(py_clinked_object_t): # class qstrvec_t(py_clinked_object_t):
"""Class representing an qstrvec_t""" # """Class representing an qstrvec_t"""
def __init__(self, items=None): # def __init__(self, items=None):
py_clinked_object_t.__init__(self) # py_clinked_object_t.__init__(self)
# Populate the list if needed # # Populate the list if needed
if items: # if items:
self.from_list(items) # self.from_list(items)
def _create_clink(self): # def _create_clink(self):
return _idaapi.qstrvec_t_create() # return _idaapi.qstrvec_t_create()
def _del_clink(self, lnk): # def _del_clink(self, lnk):
return _idaapi.qstrvec_t_destroy(lnk) # return _idaapi.qstrvec_t_destroy(lnk)
def _get_clink_ptr(self): # def _get_clink_ptr(self):
return _idaapi.qstrvec_t_get_clink_ptr(self) # return _idaapi.qstrvec_t_get_clink_ptr(self)
def assign(self, other): # def assign(self, other):
"""Copies the contents of 'other' to 'self'""" # """Copies the contents of 'other' to 'self'"""
return _idaapi.qstrvec_t_assign(self, other) # return _idaapi.qstrvec_t_assign(self, other)
def __setitem__(self, idx, s): # def __setitem__(self, idx, s):
"""Sets string at the given index""" # """Sets string at the given index"""
return _idaapi.qstrvec_t_set(self, idx, s) # return _idaapi.qstrvec_t_set(self, idx, s)
def __getitem__(self, idx): # def __getitem__(self, idx):
"""Gets the string at the given index""" # """Gets the string at the given index"""
return _idaapi.qstrvec_t_get(self, idx) # return _idaapi.qstrvec_t_get(self, idx)
def __get_size(self): # def __get_size(self):
return _idaapi.qstrvec_t_size(self) # return _idaapi.qstrvec_t_size(self)
size = property(__get_size) # size = property(__get_size)
"""Returns the count of elements""" # """Returns the count of elements"""
def addressof(self, idx): # def addressof(self, idx):
"""Returns the address (as number) of the qstring at the given index""" # """Returns the address (as number) of the qstring at the given index"""
return _idaapi.qstrvec_t_addressof(self, idx) # return _idaapi.qstrvec_t_addressof(self, idx)
def add(self, s): # def add(self, s):
"""Add a string to the vector""" # """Add a string to the vector"""
return _idaapi.qstrvec_t_add(self, s) # return _idaapi.qstrvec_t_add(self, s)
def from_list(self, lst): # def from_list(self, lst):
"""Populates the vector from a Python string list""" # """Populates the vector from a Python string list"""
return _idaapi.qstrvec_t_from_list(self, lst) # return _idaapi.qstrvec_t_from_list(self, lst)
def clear(self, qclear=False): # def clear(self, qclear=False):
""" # """
Clears all strings from the vector. # Clears all strings from the vector.
@param qclear: Just reset the size but do not actually free the memory # @param qclear: Just reset the size but do not actually free the memory
""" # """
return _idaapi.qstrvec_t_clear(self, qclear) # return _idaapi.qstrvec_t_clear(self, qclear)
def insert(self, idx, s): # def insert(self, idx, s):
"""Insert a string into the vector""" # """Insert a string into the vector"""
return _idaapi.qstrvec_t_insert(self, idx, s) # return _idaapi.qstrvec_t_insert(self, idx, s)
def remove(self, idx): # def remove(self, idx):
"""Removes a string from the vector""" # """Removes a string from the vector"""
return _idaapi.qstrvec_t_remove(self, idx) # return _idaapi.qstrvec_t_remove(self, idx)
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
class PyIdc_cvt_refclass__(pyidc_cvt_helper__): class PyIdc_cvt_refclass__(pyidc_cvt_helper__):
@ -2677,6 +2680,9 @@ NW_REMOVE = 0x0010
%include "fixup.i" %include "fixup.i"
%include "frame.i" %include "frame.i"
%include "funcs.i" %include "funcs.i"
#ifdef WITH_HEXRAYS
%include "hexrays.i"
#endif
%inline %{ %inline %{
@ -2780,6 +2786,7 @@ def RunPythonStatement(stmt):
#</pydoc> #</pydoc>
*/ */
/*
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// qstrvec_t wrapper // qstrvec_t wrapper
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -2883,7 +2890,7 @@ static bool qstrvec_t_remove(PyObject *self, size_t idx)
sv->erase(sv->begin()+idx); sv->erase(sv->begin()+idx);
return true; return true;
} }
*/
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -1,3 +1,21 @@
//---------------------------------------------------------------------
%typemap(out) uint64 {
$result = PyLong_FromUnsignedLongLong((unsigned long long) $1);
}
//---------------------------------------------------------------------
%typemap(in) uint64
{
uint64 $1_temp;
if ( !PyW_GetNumber($input, &$1_temp) )
{
PyErr_SetString(PyExc_TypeError, "Expected an uint64 type");
return NULL;
}
$1 = $1_temp;
}
//---------------------------------------------------------------------
%ignore wchar2char; %ignore wchar2char;
%ignore hit_counter_t; %ignore hit_counter_t;
%ignore reg_hit_counter; %ignore reg_hit_counter;
@ -6,10 +24,8 @@
%ignore print_all_counters; %ignore print_all_counters;
%ignore incrementer_t; %ignore incrementer_t;
%ignore reloc_info_t; // swig under mac chokes on this %ignore reloc_info_t; // swig under mac chokes on this
%ignore qstrvec_t;
%ignore qmutex_create; %ignore qmutex_create;
%ignore qiterator; %ignore qiterator;
%ignore qrefcnt_t;
%ignore qmutex_free; %ignore qmutex_free;
%ignore qmutex_lock; %ignore qmutex_lock;
%ignore qmutex_t; %ignore qmutex_t;
@ -38,8 +54,6 @@
%ignore qstrstr; %ignore qstrstr;
%ignore qstrchr; %ignore qstrchr;
%ignore qstrrchr; %ignore qstrrchr;
%ignore qstring;
%ignore qvector;
%ignore bytevec_t; %ignore bytevec_t;
%ignore reloc_info_t; %ignore reloc_info_t;
%ignore relobj_t; %ignore relobj_t;
@ -96,4 +110,27 @@
%ignore qstrupr; %ignore qstrupr;
%include "pro.h" %include "pro.h"
SWIG_DECLARE_PY_CLINKED_OBJECT(qstrvec_t) //---------------------------------------------------------------------
%template(uvalvec_t) qvector<uval_t>; // vector of unsigned values
%template(intvec_t) qvector<int>; // vector of integers
%template(qstrvec_t) qvector<qstring>; // vector of strings
%template(boolvec_t) qvector<bool>; // vector of bools
//---------------------------------------------------------------------
class qstring {
public:
const char *c_str() const { return self->c_str(); }
};
//---------------------------------------------------------------------
// for obscure reasons swig can't get past this one on its own, it needs a dummy declaration.
class strvec_t {
public:
qstring& at(int _idx) { return self->at(_idx).line; }
size_t size() const { return self->size(); }
};
class qtype {
public:
const uchar *c_str() const { return self->c_str(); }
};

View File

@ -1,3 +1,4 @@
//---------------------------------------------------------------------
// Convert an incoming Python list to a tid_t[] array // Convert an incoming Python list to a tid_t[] array
%typemap(in) tid_t[ANY](tid_t temp[$1_dim0]) { %typemap(in) tid_t[ANY](tid_t temp[$1_dim0]) {
int i, len; int i, len;
@ -27,16 +28,21 @@
$1 = &temp[0]; $1 = &temp[0];
} }
//---------------------------------------------------------------------
%define %cstring_output_maxstr_none(TYPEMAP, SIZE) %define %cstring_output_maxstr_none(TYPEMAP, SIZE)
%typemap (default) SIZE { %typemap (default) SIZE {
$1 = MAXSTR; $1 = MAXSTR;
} }
%typemap(in,numinputs=0) (TYPEMAP, SIZE) { %typemap(in,numinputs=0) (TYPEMAP, SIZE) {
$1 = ($1_ltype) qalloc(MAXSTR+1); $1 = ($1_ltype) qalloc(MAXSTR+1);
} }
%typemap(out) ssize_t { %typemap(out) ssize_t {
/* REMOVING ssize_t return value in $symname */ /* REMOVING ssize_t return value in $symname */
} }
%typemap(argout) (TYPEMAP,SIZE) { %typemap(argout) (TYPEMAP,SIZE) {
if (result > 0) if (result > 0)
{ {
@ -51,6 +57,7 @@
} }
%enddef %enddef
//---------------------------------------------------------------------
%define %cstring_bounded_output_none(TYPEMAP,MAX) %define %cstring_bounded_output_none(TYPEMAP,MAX)
%typemap(in, numinputs=0) TYPEMAP(char temp[MAX+1]) { %typemap(in, numinputs=0) TYPEMAP(char temp[MAX+1]) {
$1 = ($1_ltype) temp; $1 = ($1_ltype) temp;
@ -72,6 +79,7 @@
} }
%enddef %enddef
//---------------------------------------------------------------------
%define %binary_output_or_none(TYPEMAP, SIZE) %define %binary_output_or_none(TYPEMAP, SIZE)
%typemap (default) SIZE { %typemap (default) SIZE {
$1 = MAXSPECSIZE; $1 = MAXSPECSIZE;
@ -96,6 +104,7 @@
} }
%enddef %enddef
//---------------------------------------------------------------------
%define %binary_output_with_size(TYPEMAP, SIZE) %define %binary_output_with_size(TYPEMAP, SIZE)
%typemap (default) SIZE { %typemap (default) SIZE {
size_t ressize = MAXSPECSIZE; size_t ressize = MAXSPECSIZE;
@ -121,7 +130,8 @@
} }
%enddef %enddef
// Check that the argument is a callable Python object //---------------------------------------------------------------------
// Check that the argument is a callable Python object
%typemap(in) PyObject *pyfunc { %typemap(in) PyObject *pyfunc {
if (!PyCallable_Check($input)) { if (!PyCallable_Check($input)) {
PyErr_SetString(PyExc_TypeError, "Expected a callable object"); PyErr_SetString(PyExc_TypeError, "Expected a callable object");