Skip to content

Commit

Permalink
- Experimental: integrated Hex-Rays Decompiler bindings that were con…
Browse files Browse the repository at this point in the history
…tributed 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
  • Loading branch information
elias.bachaalany@gmail.com committed Jul 3, 2013
1 parent ce06fdd commit db58b31
Show file tree
Hide file tree
Showing 13 changed files with 3,221 additions and 1,928 deletions.
3 changes: 3 additions & 0 deletions BUILDING.txt
Expand Up @@ -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
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
swigsdk-versions/x.y/lib/x86_mac_gcc_32/
and libida64.dylib to
Expand Down
9 changes: 9 additions & 0 deletions CHANGES.txt
@@ -1,5 +1,14 @@
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
------------------------------------
- IDA Pro 6.4 support
Expand Down
79 changes: 70 additions & 9 deletions build.py
Expand Up @@ -45,6 +45,10 @@
# Find Python headers
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_OPTIONS = '-modern -python -c++ -w451 -shadow -D__GNUC__ -DNO_OBSOLETE_FUNCS'

Expand All @@ -61,6 +65,7 @@
# Common includes for all compilations
COMMON_INCLUDES = [ ".", "swig" ]

# -----------------------------------------------------------------------
# List files for the binary distribution
BINDIST_MANIFEST = [
"README.txt",
Expand Down Expand Up @@ -104,6 +109,7 @@
"examples/ex_imports.py"
]

# -----------------------------------------------------------------------
# List files for the source distribution (appended to binary list)
SRCDIST_MANIFEST = [
"BUILDING.txt",
Expand Down Expand Up @@ -150,14 +156,31 @@
"swig/xref.i",
"swig/graph.i",
"swig/fpro.i",
"swig/hexrays.i",
"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:
""" Base class for builders """
def __init__(self):
pass


def compile(self, source, objectname=None, includes=[], macros=[]):
"""
Compile the source file
Expand Down Expand Up @@ -187,6 +210,7 @@ def compile(self, source, objectname=None, includes=[], macros=[]):
print cmdstring
return os.system(cmdstring)


def link(self, objects, outfile, libpaths=[], libraries=[], extra_parameters=None):
""" Link the binary from objects and libraries """
cmdstring = "%s %s %s" % (self.linker,
Expand Down Expand Up @@ -217,6 +241,7 @@ def _build_command_string(self, macros, argument_delimiter):
return macrostring


# -----------------------------------------------------------------------
class GCCBuilder(BuilderBase):
""" Generic GCC compiler class """
def __init__(self):
Expand All @@ -241,6 +266,7 @@ def linker_out_string(self, filename):
return "-o %s" % filename


# -----------------------------------------------------------------------
class MSVCBuilder(BuilderBase):
""" Generic Visual C compiler class """
def __init__(self):
Expand All @@ -266,7 +292,7 @@ def compiler_out_string(self, filename):
def linker_out_string(self, filename):
return "/out:%s" % filename


# -----------------------------------------------------------------------
def build_distribution(manifest, distrootdir, ea64, nukeold):
""" Create a distibution to a directory and a ZIP file """
# (Re)create the output directory
Expand Down Expand Up @@ -307,7 +333,17 @@ def build_distribution(manifest, distrootdir, ea64, nukeold):
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
""" Build the plugin from the SWIG wrapper and plugin main source """
# Path to the IDA SDK headers
Expand All @@ -334,7 +370,8 @@ def build_plugin(platform, idasdkdir, plugin_name, ea64):
ida_lib = "ida.lib"
SWIG_OPTIONS += " -D__NT__ "
extra_link_parameters = ""
builder.compiler_parameters += " -Ox"
if not options[S_NO_OPT]:
builder.compiler_parameters += " -Ox"
# Platform-specific settings for the Mac OS X build
elif platform == "macosx":
builder = GCCBuilder()
Expand All @@ -353,6 +390,11 @@ def build_plugin(platform, idasdkdir, plugin_name, ea64):
if 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")

if not '--no-early-load' in sys.argv:
Expand Down Expand Up @@ -388,6 +430,7 @@ def build_plugin(platform, idasdkdir, plugin_name, ea64):
extra_link_parameters)
assert res == 0, "Failed to link the plugin binary"

# -----------------------------------------------------------------------
def detect_platform(ea64):
# Detect the platform
system = platform.system()
Expand All @@ -410,7 +453,9 @@ def detect_platform(ea64):

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)
BINDISTDIR = "idapython-%d.%d.%d_ida%d.%d_py%d.%d_%s" % (VERSION_MAJOR,
VERSION_MINOR,
Expand All @@ -421,7 +466,7 @@ def build_binary_package(ea64, nukeold):
PYTHON_MINOR_VERSION,
platform_string)
# 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
binmanifest = []
Expand All @@ -436,6 +481,7 @@ def build_binary_package(ea64, nukeold):
build_distribution(binmanifest, BINDISTDIR, ea64, nukeold)


# -----------------------------------------------------------------------
def build_source_package():
""" Build a directory and a ZIP file with all the sources """
SRCDISTDIR = "idapython-%d.%d.%d" % (VERSION_MAJOR,
Expand All @@ -448,6 +494,7 @@ def build_source_package():
srcmanifest.extend([(x, "python") for x in "python/init.py", "python/idc.py", "python/idautils.py"])
build_distribution(srcmanifest, SRCDISTDIR, ea64=False, nukeold=True)

# -----------------------------------------------------------------------
def gen_docs(z = False):
print "Generating documentation....."
old_dir = os.getcwd()
Expand Down Expand Up @@ -494,6 +541,7 @@ def gen_docs(z = False):
os.chdir(old_dir)
return

# -----------------------------------------------------------------------
def usage():
print """IDAPython build script.
Expand All @@ -504,23 +552,36 @@ def usage():
Used with '--doc' switch. It will compress the generated documentation
--ea64:
Builds also the 64bit version of the plugin
--with-hexrays:
Build with the Hex-Rays Decompiler wrappings
--no-early-load:
The plugin will be compiled as normal plugin
This switch disables processor, plugin and loader scripts
"""

# -----------------------------------------------------------------------
def main():
if '--help' in sys.argv:
return usage()
elif '--doc' in sys.argv:
return gen_docs(z = '--zip' in sys.argv)

# Do 64-bit build?
ea64 = '--ea64' in sys.argv
build_binary_package(ea64=False, nukeold=True)
# Parse options
options = parse_options(sys.argv)
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:
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()

# -----------------------------------------------------------------------
if __name__ == "__main__":
main()
27 changes: 27 additions & 0 deletions examples/vds1.py
@@ -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();
4 changes: 3 additions & 1 deletion idapython.vcxproj
Expand Up @@ -97,7 +97,7 @@
<ClCompile>
<Optimization>Disabled</Optimization>
<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>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
Expand Down Expand Up @@ -302,6 +302,7 @@
</Bscmake>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="build.py" />
<None Include="BUILDING.txt" />
<None Include="CHANGES.txt" />
<None Include="obj\x86_win_vc_32\idaapi.py" />
Expand Down Expand Up @@ -346,6 +347,7 @@
<None Include="swig\funcs.i" />
<None Include="swig\gdl.i" />
<None Include="swig\graph.i" />
<None Include="swig\hexrays.i" />
<None Include="swig\ida.i" />
<None Include="swig\idaapi.i" />
<None Include="swig\idd.i" />
Expand Down
6 changes: 6 additions & 0 deletions idapython.vcxproj.filters
Expand Up @@ -293,6 +293,12 @@
<None Include="README.txt">
<Filter>TEXT</Filter>
</None>
<None Include="swig\hexrays.i">
<Filter>swig_i</Filter>
</None>
<None Include="build.py">
<Filter>py</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Filter Include="swig_i">
Expand Down

0 comments on commit db58b31

Please sign in to comment.