Skip to content
This repository was archived by the owner on Dec 24, 2025. It is now read-only.

Commit db58b31

Browse files
author
elias.bachaalany@gmail.com
committed
- 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
1 parent ce06fdd commit db58b31

13 files changed

Lines changed: 3221 additions & 1928 deletions

File tree

BUILDING.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ Make sure all the needed tools (compiler, swig) are on the PATH.
4242
swigsdk-versions/x.y/ - A supported version of the IDA SDK
4343
idapython/ - IDAPython source code
4444

45+
Note: To build with Hex-Rays decompiler support, please copy hexrays.hpp from
46+
the decompiler SDK folder into IDA's include folder (in the SDK).
47+
4548
2. On Mac OS X copy libida.dylib from the IDA install directory to
4649
swigsdk-versions/x.y/lib/x86_mac_gcc_32/
4750
and libida64.dylib to

CHANGES.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
Please see http://code.google.com/p/idapython/source/list for a detailed list of changes.
22

3+
Changes from version 1.5.6 to 1.5.7
4+
------------------------------------
5+
- Added '--with-hexrays' switch to the build script so it wrap Hex-Rays Decompiler API
6+
- Experimental: integrated Hex-Rays Decompiler bindings that were contributed by EiNSTeiN:
7+
https://github.com/EiNSTeiN-/hexrays-python
8+
- Added one Hex-Rays decompiler sample: vds1.py
9+
- Fixed small mismatch between SWIG define and CL defines (/DNO_OBSOLETE_FUNCS)
10+
- Use print_type2() instead of the deprecated function print_type()
11+
312
Changes from version 1.5.5 to 1.5.6
413
------------------------------------
514
- IDA Pro 6.4 support

build.py

Lines changed: 70 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@
4545
# Find Python headers
4646
PYTHON_INCLUDE_DIRECTORY = sysconfig.get_config_var('INCLUDEPY')
4747

48+
S_EA64 = 'ea64'
49+
S_WITH_HEXRAYS = 'with-hexrays'
50+
S_NO_OPT = 'no-opt'
51+
4852
# Swig command-line parameters
4953
SWIG_OPTIONS = '-modern -python -c++ -w451 -shadow -D__GNUC__ -DNO_OBSOLETE_FUNCS'
5054

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

68+
# -----------------------------------------------------------------------
6469
# List files for the binary distribution
6570
BINDIST_MANIFEST = [
6671
"README.txt",
@@ -104,6 +109,7 @@
104109
"examples/ex_imports.py"
105110
]
106111

112+
# -----------------------------------------------------------------------
107113
# List files for the source distribution (appended to binary list)
108114
SRCDIST_MANIFEST = [
109115
"BUILDING.txt",
@@ -150,14 +156,31 @@
150156
"swig/xref.i",
151157
"swig/graph.i",
152158
"swig/fpro.i",
159+
"swig/hexrays.i",
153160
"tools/gendocs.py",
154161
]
155162

163+
# -----------------------------------------------------------------------
164+
def parse_options(args):
165+
"""Parse arguments and returned a dictionary of options"""
166+
167+
no_opt = '--' + S_NO_OPT in sys.argv
168+
ea64 = '--' + S_EA64 in sys.argv
169+
with_hexrays = '--' + S_WITH_HEXRAYS in sys.argv
170+
171+
return {
172+
S_EA64: ea64,
173+
S_WITH_HEXRAYS: with_hexrays,
174+
S_NO_OPT: no_opt
175+
}
176+
177+
# -----------------------------------------------------------------------
156178
class BuilderBase:
157179
""" Base class for builders """
158180
def __init__(self):
159181
pass
160182

183+
161184
def compile(self, source, objectname=None, includes=[], macros=[]):
162185
"""
163186
Compile the source file
@@ -187,6 +210,7 @@ def compile(self, source, objectname=None, includes=[], macros=[]):
187210
print cmdstring
188211
return os.system(cmdstring)
189212

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

219243

244+
# -----------------------------------------------------------------------
220245
class GCCBuilder(BuilderBase):
221246
""" Generic GCC compiler class """
222247
def __init__(self):
@@ -241,6 +266,7 @@ def linker_out_string(self, filename):
241266
return "-o %s" % filename
242267

243268

269+
# -----------------------------------------------------------------------
244270
class MSVCBuilder(BuilderBase):
245271
""" Generic Visual C compiler class """
246272
def __init__(self):
@@ -266,7 +292,7 @@ def compiler_out_string(self, filename):
266292
def linker_out_string(self, filename):
267293
return "/out:%s" % filename
268294

269-
295+
# -----------------------------------------------------------------------
270296
def build_distribution(manifest, distrootdir, ea64, nukeold):
271297
""" Create a distibution to a directory and a ZIP file """
272298
# (Re)create the output directory
@@ -307,7 +333,17 @@ def build_distribution(manifest, distrootdir, ea64, nukeold):
307333
zip.close()
308334

309335

310-
def build_plugin(platform, idasdkdir, plugin_name, ea64):
336+
# -----------------------------------------------------------------------
337+
def build_plugin(
338+
platform,
339+
idasdkdir,
340+
plugin_name,
341+
options):
342+
343+
# Get the arguments
344+
ea64 = options[S_EA64]
345+
with_hexrays = options[S_WITH_HEXRAYS]
346+
311347
global SWIG_OPTIONS
312348
""" Build the plugin from the SWIG wrapper and plugin main source """
313349
# Path to the IDA SDK headers
@@ -334,7 +370,8 @@ def build_plugin(platform, idasdkdir, plugin_name, ea64):
334370
ida_lib = "ida.lib"
335371
SWIG_OPTIONS += " -D__NT__ "
336372
extra_link_parameters = ""
337-
builder.compiler_parameters += " -Ox"
373+
if not options[S_NO_OPT]:
374+
builder.compiler_parameters += " -Ox"
338375
# Platform-specific settings for the Mac OS X build
339376
elif platform == "macosx":
340377
builder = GCCBuilder()
@@ -353,6 +390,11 @@ def build_plugin(platform, idasdkdir, plugin_name, ea64):
353390
if ea64:
354391
platform_macros.append("__EA64__")
355392

393+
# Build with Hex-Rays decompiler
394+
if with_hexrays:
395+
platform_macros.append("WITH_HEXRAYS")
396+
SWIG_OPTIONS += ' -DWITH_HEXRAYS '
397+
356398
platform_macros.append("NDEBUG")
357399

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

433+
# -----------------------------------------------------------------------
391434
def detect_platform(ea64):
392435
# Detect the platform
393436
system = platform.system()
@@ -410,7 +453,9 @@ def detect_platform(ea64):
410453

411454
return (system, platform_string, plugin_name)
412455

413-
def build_binary_package(ea64, nukeold):
456+
# -----------------------------------------------------------------------
457+
def build_binary_package(options, nukeold):
458+
ea64 = options[S_EA64]
414459
system, platform_string, plugin_name = detect_platform(ea64)
415460
BINDISTDIR = "idapython-%d.%d.%d_ida%d.%d_py%d.%d_%s" % (VERSION_MAJOR,
416461
VERSION_MINOR,
@@ -421,7 +466,7 @@ def build_binary_package(ea64, nukeold):
421466
PYTHON_MINOR_VERSION,
422467
platform_string)
423468
# Build the plugin
424-
build_plugin(platform_string, IDA_SDK, plugin_name, ea64)
469+
build_plugin(platform_string, IDA_SDK, plugin_name, options)
425470

426471
# Build the binary distribution
427472
binmanifest = []
@@ -436,6 +481,7 @@ def build_binary_package(ea64, nukeold):
436481
build_distribution(binmanifest, BINDISTDIR, ea64, nukeold)
437482

438483

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

497+
# -----------------------------------------------------------------------
451498
def gen_docs(z = False):
452499
print "Generating documentation....."
453500
old_dir = os.getcwd()
@@ -494,6 +541,7 @@ def gen_docs(z = False):
494541
os.chdir(old_dir)
495542
return
496543

544+
# -----------------------------------------------------------------------
497545
def usage():
498546
print """IDAPython build script.
499547
@@ -504,23 +552,36 @@ def usage():
504552
Used with '--doc' switch. It will compress the generated documentation
505553
--ea64:
506554
Builds also the 64bit version of the plugin
555+
--with-hexrays:
556+
Build with the Hex-Rays Decompiler wrappings
507557
--no-early-load:
508558
The plugin will be compiled as normal plugin
509559
This switch disables processor, plugin and loader scripts
510560
"""
511561

562+
# -----------------------------------------------------------------------
512563
def main():
513564
if '--help' in sys.argv:
514565
return usage()
515566
elif '--doc' in sys.argv:
516567
return gen_docs(z = '--zip' in sys.argv)
517568

518-
# Do 64-bit build?
519-
ea64 = '--ea64' in sys.argv
520-
build_binary_package(ea64=False, nukeold=True)
569+
# Parse options
570+
options = parse_options(sys.argv)
571+
ea64 = options[S_EA64]
572+
573+
# Always build the non __EA64__ version
574+
options[S_EA64] = False
575+
build_binary_package(options, nukeold=True)
576+
577+
# Rebuild package with __EA64__ if needed
521578
if ea64:
522-
build_binary_package(ea64=True, nukeold=False)
579+
options[S_EA64] = True
580+
build_binary_package(options, nukeold=False)
581+
582+
# Always build the source package
523583
build_source_package()
524584

585+
# -----------------------------------------------------------------------
525586
if __name__ == "__main__":
526587
main()

examples/vds1.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import idaapi
2+
3+
def main():
4+
if not idaapi.init_hexrays_plugin():
5+
return False
6+
7+
print "Hex-rays version %s has been detected" % idaapi.get_hexrays_version()
8+
9+
f = idaapi.get_func(idaapi.get_screen_ea());
10+
if f is None:
11+
print "Please position the cursor within a function"
12+
return True
13+
14+
cfunc = idaapi.decompile(f);
15+
if cfunc is None:
16+
print "Failed to decompile!"
17+
return True
18+
19+
sv = cfunc.get_pseudocode();
20+
for i in xrange(0, sv.size()):
21+
line = idaapi.tag_remove(str(sv[i]));
22+
print line
23+
24+
return True
25+
26+
if main():
27+
idaapi.term_hexrays_plugin();

idapython.vcxproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@
9797
<ClCompile>
9898
<Optimization>Disabled</Optimization>
9999
<AdditionalIncludeDirectories>.\pywraps;..\..\include;\python27\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
100-
<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>
100+
<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>
101101
<MinimalRebuild>true</MinimalRebuild>
102102
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
103103
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
@@ -302,6 +302,7 @@
302302
</Bscmake>
303303
</ItemDefinitionGroup>
304304
<ItemGroup>
305+
<None Include="build.py" />
305306
<None Include="BUILDING.txt" />
306307
<None Include="CHANGES.txt" />
307308
<None Include="obj\x86_win_vc_32\idaapi.py" />
@@ -346,6 +347,7 @@
346347
<None Include="swig\funcs.i" />
347348
<None Include="swig\gdl.i" />
348349
<None Include="swig\graph.i" />
350+
<None Include="swig\hexrays.i" />
349351
<None Include="swig\ida.i" />
350352
<None Include="swig\idaapi.i" />
351353
<None Include="swig\idd.i" />

idapython.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,12 @@
293293
<None Include="README.txt">
294294
<Filter>TEXT</Filter>
295295
</None>
296+
<None Include="swig\hexrays.i">
297+
<Filter>swig_i</Filter>
298+
</None>
299+
<None Include="build.py">
300+
<Filter>py</Filter>
301+
</None>
296302
</ItemGroup>
297303
<ItemGroup>
298304
<Filter Include="swig_i">

0 commit comments

Comments
 (0)