Compare commits

...

338 Commits

Author SHA1 Message Date
Tamir Bahar
0028bac297 Added a flag to enable debug info generation on Windows. 2015-07-02 11:58:14 +03:00
Elias Bachaalany
a2c4f50f31 Merge pull request #1 from aundro/ida68
IDA Pro 6.8 support
2015-04-20 22:30:05 -07:00
Arnaud Diederen
f9f3ccb63b IDA Pro 6.8 support
What's new: https://www.hex-rays.com/products/ida/6.8/index.shtml
2015-04-20 14:26:30 +02:00
Elias Bachaalany
2fa1f9a64b - added previous releases
binaries + sources
2015-03-14 13:31:51 -07:00
elias.bachaalany@gmail.com
081b988a03 fix: python processor modules were not working 2015-03-02 15:54:20 +00:00
elias.bachaalany@gmail.com
3e9ea5f503 minor mod: turned off build debug flag 2015-02-08 03:07:57 +00:00
elias.bachaalany@gmail.com
bbf628d3a3 IDA Pro 6.7 support 2015-02-08 02:59:53 +00:00
elias.bachaalany@gmail.com
49dcdc5ed3 added idautils.IsBatchMode() 2014-11-21 22:12:14 +00:00
elias.bachaalany@gmail.com
960a670de9 minor mods 2014-07-28 18:11:34 +00:00
elias.bachaalany@gmail.com
fbb5bfabd6 IDA Pro 6.6 support
What's new:
- added the decompiler bindings
- Expose simpleline_t type to IDAPython. That lets the user to set the bgcolor & text for each line in the decompilation.
- Wrapped new functions from the IDA SDK

Various fixes:
for non-code locations, idc.GetOpnd() would create instructions instead of returning empty result
- idb_event::area_cmt_changed was never received in IDB_Hooks (and descendants)
- idb_event::ti_changed, and idb_event::op_ti_changed notifications were not accessible in IDAPython
- op_t.value was truncated to 32 bits under IDA64.
- print_tinfo() wouldn't return a valid string.
- readsel2() was not usable.
- read_selection() was buggy for 64-bit programs.
- StructMembers() considered holes in structures, and didn't properly iterate through the whole structure definition.
- There was no way to call calc_switch_cases() from IDAPython.
- when using multi-select/multi-edit choosers, erroneous event codes could be sent at beginning & end of batch deletion of lines.
- When, in a PluginForm#OnCreate, the layout of IDA was requested to change (for example by starting a debugging session), that PluginForm could be deleted and create an access violation.
- tinfo_t objects created from IDAPython could cause an assertion failure at exit time.
- Usage of IDAPython's DropdownListControl was broken.
2014-07-04 22:02:42 +00:00
elias.bachaalany@gmail.com
1c6752de40 - Fixed idaapi.read_selection() 2014-04-08 00:11:43 +00:00
elias.bachaalany@gmail.com
866e631dc7 Added IDA Pro 6.1 SP1 changes (thanks to Arnaud from Hex-Rays) 2014-02-04 02:31:52 +00:00
elias.bachaalany@gmail.com
78c79f85b9 IDA Pro 6.5 support
What's new:
- Proper multi-threaded support 
- Better PyObject reference counting with ref_t and newref_t helper classes
- Improved the pywraps/deployment script
- Added IDAViewWrapper class and example
- Added idc.GetDisasmEx()
- Added idc.AddSegEx()
- Added idc.GetLocalTinfo()
- Added idc.ApplyType()
- Updated type information implementation
- Introduced the idaapi.require() - see http://www.hexblog.com/?p=749
- set REMOVE_CWD_SYS_PATH=1 by default in python.cfg (remove current directory from the import search path).

Various bugfixes:
- fixed various memory leaks
- asklong/askaddr/asksel (and corresponding idc.py functions) were returning results truncated to 32 bits in IDA64
- fix wrong documentation for idc.SizeOf
- GetFloat/GetDouble functions did not take into account endianness of the processor
- idaapi.NO_PROCESS was not defined, and was causing GetProcessPid() to fail
- idc.py: insert escape characters to string parameter when call Eval()
- idc.SaveFile/savefile were always overwriting an existing file instead of writing only the new data
- PluginForm.Close() wasn't passing its arguments to the delegate function, resulting in an error.
2013-12-30 01:34:23 +00:00
elias.bachaalany@gmail.com
c88a77e809 Contributed by EiNSTeiN_:
- added support for 'long' addresses 
- updated copyright notice in hexrays.i
- added methods to remove or insert elements in the qlist<cinsn_t> list
- added support for ctree_visitor_t / ctree_parentee_t / cfunc_parentee_t / user_lvar_visitor_t
- updated vds3 sample
- added vds4 and vds7 python samples (ported from their C++ counter parts)
2013-07-16 23:09:33 +00:00
elias.bachaalany@gmail.com
7eb6d04c6e Contributed by EiNSTeiN_:
- Fixed compilation error on Linux
- Minor bugfix in hexrays.i
- Added two more samples: vds3.py and vds_xrefs.py
2013-07-05 23:12:04 +00:00
elias.bachaalany@gmail.com
db58b31711 - 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
2013-07-03 01:40:54 +00:00
elias.bachaalany@gmail.com
ce06fdd7d2 Added VS2012 solution files 2013-06-28 22:32:32 +00:00
elias.bachaalany@gmail.com
4e295155bb Fixed compilation bugs:
- Fixed small mismatch between SWIG define and CL defines (/DNO_OBSOLETE_FUNCS)
- Use print_type2() instead of the deprecated function print_type()
2013-06-28 01:32:56 +00:00
elias.bachaalany@gmail.com
21cd5a95eb - applied patchs for IDA 6.4 SP from Hex-Rays
- fixed idc.CommentEx()
- minor mods
2013-03-08 19:33:51 +00:00
elias.bachaalany@gmail.com
223e4a5268 Applied patches from Hex-Rays:
- added MakeYword
- wrap obsolete IDA API functions too, so that old scripts continue to work
- added debugger trace related functions in idc.py
BUGFIX: IDAPython would fail with a cryptic error message if there was no free space on the current disk
BUGFIX: site-packages directory was missing from sys.path
BUGFIX: functions for working with additional lines (LineA/LineB etc) were broken
BUGFIX: GetFixup* functions from idc.py were broken
BUGFIX: IDA could not start if another python27.dll was present in PATH and importing site.py for that Python installation failed
BUGFIX: SaveBase() was broken
BUGFIX: IDAPython would fail with a cryptic error message if there was no free space on the current disk
BUGFIX: IDAPython: site-packages directory was missing from sys.path
BUGFIX: IDAPython: functions for working with additional lines (LineA/LineB etc) were broken
BUGFIX: IDAPython: GetFixup* functions from idc.py were broken
BUGFIX: IDAPython: IDA could not start if another python27.dll was present in PATH and importing site.py for that Python installation failed
BUGFIX: IDAPython: SaveBase() was broken
BUGFIX: Dbg/Idp hooks automatically unhook when hook object is not referenced anymore

note: these patches are already applied in IDAPython that comes with IDA Pro 6.4
2013-03-06 07:44:10 +00:00
elias.bachaalany
69d5c83d28 - 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
2012-06-24 20:49:11 +00:00
elias.bachaalany@gmail.com
4d21b10dc4 removed dead code 2012-04-04 07:45:15 +00:00
skochinsky@gmail.com
0282e67982 IDAPython 1.5.4
- fix for Python autorun script vulnerability reported by Greg MacManus
- remove current directory from sys.path during initialization
2012-03-26 13:39:09 +00:00
elias.bachaalany@gmail.com
06f0ff19d5 bugfixes:
- op_t.is_reg() was buggy
- build.py: build.py was putting duplicate files into the .zip
- added backed wrapped version of get_ascii_contents()
- misc changes...
2011-12-02 15:42:36 +00:00
elias.bachaalany@gmail.com
930d7cbcd4 added PyWraps sources. This will facilitate deployment, development and debugging of IDAPython additions 2011-12-02 15:40:11 +00:00
skochinsky@gmail.com
1258fab948 IDAPython 1.5.3
- IDA Pro 6.2 support
- added set_idc_func_ex(): it is now possible to add new IDC functions using Python
- added visit_patched_bytes() (see ex_patch.py)
- added support for the multiline text input control in the Form class
- added support for the editable/readonly dropdown list control in the Form class
- added execute_sync() to register a function call into the UI message queue
- added execute_ui_requests() / check ex_uirequests.py
- added add_hotkey() / del_hotkey() to bind Python methods to hotkeys
- added register_timer()/unregister_timer(). Check ex_timer.py
- added the IDC (Arrays) netnode manipulation layer into idc.py
- added idautils.Structs() and StructMembers() generator functions
- removed the "Run Python Statement" menu item. IDA now has a unified dialog. 
  Use RunPlugin("python", 0) to invoke it manually.
- better error messages for script plugins, loaders and processor modules
- bugfix: Dbg_Hooks.dbg_run_to() was receiving wrong input
- bugfix: A few Enum related functions were not properly working in idc.py
- bugfix: GetIdaDirectory() and GetProcessName() were broken in idc.py
- bugfix: idaapi.get_item_head() / idc.ItemHead() were not working
2011-10-14 14:24:38 +00:00
elias.bachaalany@gmail.com
96cd02db6c - fixed idc.ItemHead()
- update some IDC functions documentation
2011-08-08 15:42:25 +00:00
elias.bachaalany@gmail.com
7bd77d534c vuln bugfix: check for swig_runtime_dataN.py was not done properly (MSVR-11-0084)
The bug is due to the following faulty line: http://code.google.com/p/idapython/source/browse/tags/build-1.5.1/swig/idaapi.i#611
2011-07-27 08:51:29 +00:00
elias.bachaalany@gmail.com
8413f9f791 - GetIdaDirectory() was broken
- some function comments were wrong
- other fixes
2011-07-04 13:19:36 +00:00
elias.bachaalany
f5ec434bf7 IDAPython 1.5.2
- added ui_term/ui_save/ui_saved/ui_get_ea_hint UI notifications
- added ph_get_operand_info() to retrieve operand information while debugging
- added PteDump.py script
- some code refactoring
- bugfix: idaapi.netnode.getblob() was limited to MAXSPECSIZE
- bugfix: idc.GetString()/idaapi.get_ascii_contents()/idautils.Strings() were limited to MAXSTR string length
- bugfix: idaapi.del_menu_item() was failing to delete some menu items
- bugfix: dbg_bpt was called instead of dbg_trace for a DBG_Hooks class implementation (old bug from 0.9.x)
- bugfix: Form.GetControlValue() was not working with numeric controls
- bugfix: SetBptCnd() was broken
- bugfix: idaapi.get_func_cmt() was memory leaking
2011-06-10 15:21:21 +00:00
elias.bachaalany
88aa875c55 bugfixes:
- ph_get_operand_info() would crash IDA sometimes
- idc.SetBptCond() was broken
- idc.GetFunctionCmt() was memory leaking
- Form.GetFieldValue() was failing for numeric controls
- Exceptions originating from the director classes will be displayed

And other minor mods...
2011-06-10 14:54:03 +00:00
elias.bachaalany
c29e1ef2da - added ph_get_operand_info() 2011-05-23 15:54:27 +00:00
elias.bachaalany
2327aada40 bugfix: dbg_bpt was called instead of dbg_trace for a DBG_Hooks class implementation
(old bug from version < 1.0)
2011-05-23 13:01:22 +00:00
elias.bachaalany
7e63ea0747 - bugfix: idaapi.del_menu_item() was failing to delete some menu items 2011-05-19 15:06:49 +00:00
elias.bachaalany
a12974b66c - bugfix: idc.GetString()/idaapi.get_ascii_contents()/idautils.Strings() were limited to MAXSTR string length
- minor mods
2011-05-19 15:06:31 +00:00
elias.bachaalany
c94f5c10bb bugfix: IDAPython: get_blob() was returning a buffer with at most MAXSPECSIZE bytes 2011-05-19 15:03:01 +00:00
elias.bachaalany
a52b90c771 bugfix: Previous implementation set_script_timeout() was causing the script wait dialog box to open and never close upon the invocation of callbacks (add_menu_item callback or other callbacks) that take longer than the timeout value. 2011-05-09 10:29:08 +00:00
elias.bachaalany
7179b2c654 - Choose2.Show(modal=True) was broken 2011-05-09 10:22:44 +00:00
elias.bachaalany
50b66d0264 - added VirusTotal script. Check http://www.hexblog.com/?p=324 2011-05-09 10:21:32 +00:00
elias.bachaalany
47f7f2e48b forgot to add python.cfg to SVN 2011-04-21 14:28:37 +00:00
elias.bachaalany
8375368d6d IDAPython 1.5.1
- Introduced the CLI '?' pseudo-command to retrieve doc strings
- Introduced the CLI '!' pseudo-command to shell execute a command
- Added IDP/assemble notification event
- bugfix: High 64 bit addresses were not parsed correctly in IDA64
- bugfix: AskUsingForm() C function was not wrapped by SWIG
- NextHead()/PrevHead() have optional 2nd parameter now
2011-04-21 14:23:46 +00:00
elias.bachaalany
58a002ce5b bugfix: High 64 bit addresses were not parsed correctly in IDA64 2011-04-18 16:14:58 +00:00
elias.bachaalany
109158fabb - IDA Pro 6.1 support
- Added AskUsingForm() with embedded forms support (check ex_askusingform.py example and formchooser.py in the SDK)
- Added idautils.DecodePreviousInstruction() / DecodePrecedingInstruction()
- Added idc.BeginTypeUpdating() / EndTypeUpdating() for fast batch type update operations
- Added more IDP callbacks
- Added UI_Hooks with a few notification events
- Added idaapi.process_ui_action() / idc.ProcessUiAction()
- Added netnode.index() to get netnode number
- Better handling of ea_t values with bitwise negation
- Execute statement hotkey (Ctrl-F3), script timeout, and other options are now configurable with Python.cfg
- bugfix: idaapi.msg() / error() and warning() so they don't accept vararg
- bugfix: processor_t.id constants were incorrect
- bugfix: get_debug_names() was broken with IDA64
- Various bugfixes
2011-04-18 16:07:00 +00:00
elias.bachaalany
63b22d00d5 - Fixed issue 59
- Fixed idaapi.msg() / error() and warning() so they don't accept vararg
- Fixed processor_t.id constants
- idaapi.BasicBlock and FlowChart are now new-style classes
2010-12-17 16:50:35 +00:00
ero.carrera
1bd58bda60 Fixed the docstring of DataRefsFrom/To. The example was copy-pasted from the CodeRefs* functions and included the "flow" argument. 2010-11-29 15:19:24 +00:00
elias.bachaalany
197a94f5d7 Added PySide and PyQt examples 2010-11-10 14:05:29 +00:00
elias.bachaalany
ac5d88a83b IDAPython 1.4.3:
- IDA 6.0 support
- Python CLI now prints expression evaluation result (no need to use print())
- Changed Alt-8 to Ctrl-F3 (because it conflicts with window switching key Alt+n)
- Added get_highlighted_identifier()
- Added PluginForm class to allow UI development with either PyQt4 or PySide
- Added idautils.Entries() to enumerate entrypoints
- idc / AddConst() was broken
- Minor fixes
2010-11-10 13:58:08 +00:00
elias.bachaalany
1d2f1d1f07 Committed last updates to IDAPython 1.4.2 2010-10-07 09:47:04 +00:00
ero.carrera@gmail.com
faf5063818 Fixed a bug in GetIdbPath() when working in an IDA instance that has dealt with more than one IDB.
idaapi.cvar.database_idb seems to point to a realloc'ed buffer. When IDA is working on an IDB stored in a directory with a long path and a second IDB with a shorter path is loaded, the buffer will be overwritten with the new path to the IDB, which will end in "\x00" and the leftovers of the older, longer path will follow.
The problem with GetIdbPath() is that it returns the whole bufer, NULL and "leftovers" included, which leads to trouble in Python. Specifically some functions like os.path.splitext which will look for the extension starting from the end of the buffer and will return an invalid split.
The patch simply post-processes the contents of idaapi.cvar.database_idb returning a Python string with all characters up to the "\x00"
2010-09-23 18:57:37 +00:00
elias.bachaalany
80896bc1d9 Minor modifications:
- function documentation update
- removed some white spaces
2010-09-17 12:06:30 +00:00
elias.bachaalany
36c814331a Some Appcall methods would fail if passed addresses with value zero 2010-09-17 12:04:27 +00:00
elias.bachaalany
0f64f33981 Command completion was broken after last changes 2010-09-17 12:03:24 +00:00
elias.bachaalany
930b333d3b bugfix: idaapi.enable_extlang_python() could not be called from init.py 2010-09-11 09:34:14 +00:00
elias.bachaalany
2d763844ed idc.py: added GetManyBytes() and ItemHead() 2010-09-11 08:47:45 +00:00
elias.bachaalany
40d46c34a9 command completion will propose '(' for callables and '[' for iterables 2010-08-17 12:32:59 +00:00
elias.bachaalany
67c94b2f02 idaapi.dbg_get_registers() was crashing with registers that had a custom format 2010-08-17 12:31:36 +00:00
elias.bachaalany
2c33ce00c5 fixed issue 55 2010-08-14 15:43:09 +00:00
elias.bachaalany
4867b405a9 idc.py: Til2Idb() was broken 2010-08-10 11:45:36 +00:00
elias.bachaalany
f216eb9a6d - IDAPython 1.4.2: should work now with Python 2.7
- Hide the Python plugin from the plugins menu (it already installs the run statement functionality in the File menu)
2010-08-10 11:44:59 +00:00
elias.bachaalany
9858aae998 updated AUTHORS files 2010-08-10 11:40:01 +00:00
elias.bachaalany
c1d87c0c7c fix for the $PATH issue on OSX by setting proper home path (thanks to igorsk) 2010-08-10 11:36:40 +00:00
elias.bachaalany
15a72289f7 fixed issue 54 2010-08-02 14:13:48 +00:00
elias.bachaalany
686e018bdc - 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
2010-07-27 14:44:31 +00:00
elias.bachaalany
97a9805336 added command completion 2010-07-19 13:00:33 +00:00
elias.bachaalany
d76ccd7b1e updated CHANGES.txt 2010-07-16 12:11:19 +00:00
elias.bachaalany
6b0dfd84c0 IDAPython 1.4.1:
- added AUTHORS.txt and changed the banner
- IDAPython_ExecFile() will print script execution errors to the log window too
- added 'ph' into idaapi. It is a replacement for idaapi.cvar.ph
- added runscript to init.py for backward compatibility
- added cli_t support
2010-07-16 12:07:49 +00:00
elias.bachaalany
8495e5205b - renamed pywraps related utility functions to PyW_
- refactored some code
- fixed some potential PyObject leaks
- added cli_t support
2010-07-13 16:43:53 +00:00
elias.bachaalany
4b1c3cd4c4 GetFchunkAttr() is reimplemented using idaapi rather than Eval() and IDC (issue 52) 2010-07-02 16:10:30 +00:00
elias.bachaalany
5b59791156 added dbg_is_loaded() 2010-06-29 10:49:28 +00:00
elias.bachaalany
3a5063330c IDAPython 1.4.0 - IDA Pro 5.7 support 2010-06-28 12:36:40 +00:00
elias.bachaalany
5f2262fad9 fixed issue 51 2010-06-04 15:02:33 +00:00
elias.bachaalany
8ecfe8b218 dbghooks / dbg_request_error was broken 2010-06-04 15:01:51 +00:00
elias.bachaalany
7da6dd916c idd.i: dbg_can_query() was returning false when called from a bpt condition
idc.py: AskStr() was calling idaapi.askstr w/ wrong parameter
2010-05-13 09:36:56 +00:00
elias.bachaalany
5cede13626 graph.i: AddCommand() was broken
- updated the ex_graph.py sample
- updated function usage comments
2010-05-06 07:56:25 +00:00
elias.bachaalany
f4b1a7d87c handle_python_error() was leaking an object 2010-05-06 07:51:36 +00:00
elias.bachaalany
69e35391a5 idd.i: added dbg_get_name() to get the current debugger's name 2010-05-05 13:11:36 +00:00
elias.bachaalany
ff7ab3f1dc idc.py: added SendDbgCommand() 2010-05-05 13:05:53 +00:00
ero.carrera@gmail.com
f09375cf70 - bugfix: According to their docstrings a few functions should be returning 0 or -1 to indicate errors but were returning instead None 2010-04-27 13:42:41 +00:00
elias.bachaalany
0c6b9b31b9 graph.i: OnDeactivate() was not being called. 2010-04-27 13:28:26 +00:00
gergely.erdelyi
6112217cab Updated copyright dates and email address 2010-04-26 20:13:11 +00:00
gergely.erdelyi
1157ea1487 kernwin.i: simplecustviewer_t removed from the non-Windows builds 2010-04-26 19:56:52 +00:00
gergely.erdelyi
1757dec387 idc.py: Default strtype argument in GetString no longer breaks the whole script 2010-04-26 19:51:58 +00:00
elias.bachaalany
dc20f63143 fix [issue 48]: customviewer is now enabled for Windows builds only 2010-04-26 08:02:20 +00:00
elias.bachaalany
0dfdad1f42 Manually wrapped run_plugin() and load_plugin()
(No need to have swig generate a class for plugin_t)
2010-04-23 10:55:20 +00:00
elias.bachaalany
0acf7aa44a Applied patch (issue47) by humeafo 2010-04-23 10:52:53 +00:00
elias.bachaalany
3e0343daf5 bugfix: unpack_object_from_bv() and unpack_object_from_idb() were leaking objects 2010-04-23 10:51:49 +00:00
elias.bachaalany
ecb4232040 Added default parameter to GetString() 2010-04-23 10:49:21 +00:00
ero.carrera@gmail.com
53d99a141a - Fixed a really subtle bug in some of the uses of _IDC_SetAttr(). In a couple of locations the call is made as part of the condition of an IF. But _IDC_SetAttr() will always return None ( "return setattr(obj, attrmap[attroffs][1], value)" ), leading to the value being properly set in the instance but never updated in the IDB. Which led to mysterious behavior because of "vanishing" attributes 2010-04-12 17:12:23 +00:00
elias.bachaalany
4bd83af5a3 Custom Viewer:
- renamed customview to customviewer
- added GetCurrentWord()
2010-03-25 11:52:03 +00:00
elias.bachaalany
0c11d8f170 minor code style modification 2010-03-22 14:22:17 +00:00
elias.bachaalany
ab81000187 - added GetInstructionList() and GetRegisterList() to idautils.py
- ignored processor_t and ph global variable
2010-03-22 14:21:43 +00:00
elias.bachaalany
729084a1ff added Custom Viewer support 2010-03-22 14:19:43 +00:00
elias.bachaalany
f57af01a21 bugfix: import enumeration did not handle imports by ordinal properly 2010-03-17 11:30:28 +00:00
elias.bachaalany
ee8fab6c4c Changed version to 1.3.2 and uploaded a precompiled version for Windows and IDA Pro 5.6 2010-03-05 11:45:44 +00:00
elias.bachaalany
8e78513e91 - minor code cleanup
- updated CHANGES.txt
- nalt.i: forgot to release reference for callback result (in py_import_enum_cb())
2010-03-05 11:35:28 +00:00
elias.bachaalany
57d37a638a Added import enumeration support. Check exmples\ex_imports.py 2010-03-05 11:18:25 +00:00
elias.bachaalany
b935e24aba - some code cleanup
- added idaapi. struct_unpack / copy_bits / as_signed utility functions
- added pywraps.hpp utility header
2010-03-05 11:16:27 +00:00
elias.bachaalany
33c93df0cf GetDouble() and GetFloat() now use idaapi.get_many_bytes() 2010-03-05 10:59:23 +00:00
elias.bachaalany
7d32ff30f0 Added get_many_bytes(ea, size) -> String | None 2010-03-05 10:20:42 +00:00
elias.bachaalany
42a2f7f630 bugfix: linput_t was accessing uninitialized variable in some cases 2010-02-16 15:21:49 +00:00
elias.bachaalany
8b7625f145 qfile_t._from_fp was broken 2010-02-15 11:58:44 +00:00
elias.bachaalany
06e8cad773 bugfix: IDAPython_extlang_create_object may cause exceptions to be reported to the running Python script if called with an invalid object name
minor changes: removed trailing spaces from files
2010-02-12 13:16:37 +00:00
elias.bachaalany
e056f5670f bugfix: string conversion routine was returning size+1
this was true when only VT_STR existed
2010-02-12 12:56:14 +00:00
elias.bachaalany
bbabb3d6fa creating opaque types to be used with extlang may crash sometimes:
it is bad to keep a reference to add_idc_class() better use find_idc_class() instead
2010-02-12 12:45:10 +00:00
gergely.erdelyi
dd5273fee9 init.py: modules loaded by user scripts are now unloaded when the script finishes. No more reload() needed. Thanks to cbwhiz for the idea. 2010-02-04 20:58:38 +00:00
gergely.erdelyi
e1298031ac Alt-7 uses runscript() to run scripts 2010-02-04 20:44:37 +00:00
gergely.erdelyi
5ec97ef3aa idautils.py: Functions() will return the correct list of functions even in large binaries 2010-02-04 20:29:50 +00:00
elias.bachaalany
ea4cd26a6a MakeArray and GetStringType: were using an old type name
GetLongPrm and SetLongPrm were not working with INF_PROCNAME
2010-01-27 09:52:22 +00:00
elias.bachaalany
a39ada9fb6 idapython menus would duplicate each time a database is opened 2010-01-18 10:56:36 +00:00
elias.bachaalany
d7c6f94f08 bugfix: SetRegEx and GetReg were only working with x86 segment registers 2010-01-18 10:55:33 +00:00
elias.bachaalany
277facf240 IDAPython 1.3.0 / IDA Pro 5.6
(For older versions please use the 1.2.90 branch)
2010-01-05 18:24:04 +00:00
elias.bachaalany
ab7a03431e idc.py: RefreshDebuggerMemory() was broken 2009-11-13 12:24:06 +00:00
elias.bachaalany
0e9f53eaad bytes.i: wrapped nextthat/prevthat() 2009-10-30 14:18:28 +00:00
elias.bachaalany
01601d7eea idapython: it is possible to load IdaPython at an early stage and keep it loaded as long as IDA is running.
(One needs to pass the "--early-load" switch to build.py)
2009-10-29 11:37:24 +00:00
elias.bachaalany
7970f9696d added from_cobject method to both loader_input_t and qfile_t python classes 2009-10-29 11:31:53 +00:00
elias.bachaalany
b9465ab7f6 diskio.i: wrapped enumerate_files and enumerate_system_files 2009-10-21 11:51:31 +00:00
elias.bachaalany
06e3f4f80f minor changes 2009-10-21 11:50:51 +00:00
elias.bachaalany
62b9382ee8 diskio.i: wrapped linput_t* related functions into loader_input_t python class 2009-10-21 11:49:41 +00:00
elias.bachaalany
608c8f0eb8 wrapped qfile related functions in a qfile_t class 2009-10-21 11:44:43 +00:00
elias.bachaalany
dac4a0629e minor changes 2009-10-21 08:49:53 +00:00
elias.bachaalany
a4627a6d36 ida.i: fixed %ignore so we ignore functions from the idainfo class 2009-10-21 08:49:38 +00:00
elias.bachaalany
3862f05f3f build.py: slightly modified the build.py script so that it can be imported and used from other build scripts 2009-10-19 07:21:22 +00:00
elias.bachaalany
99c60a82de idautils.py: added procregs to identify registers and modified DecodeInstruction().
It is now possible to identify the registers of a decoded instruction with:

cmd = DecodeInstruction(here())
if cmd[0].is_reg(proc_regs.eax): print "EAX is used"

or something like:

if cmd[1].is_reg(proc_regs.al): print "al is used"
2009-10-19 07:17:22 +00:00
gergely.erdelyi
c21a932cec idc.py: Whitespace and indentation fixes 2009-10-17 21:12:15 +00:00
gergely.erdelyi
cb57938dcc idc.py: Fixed RunTo() and GetExceptionQty() 2009-10-17 21:08:36 +00:00
gergely.erdelyi
9d3fb35f87 has_key() is slowly getting deprecated. Might make sense to stop using it. 2009-10-17 20:54:08 +00:00
gergely.erdelyi
bbf6b2e547 idautils.py: Rearranged function order to be more logical 2009-10-17 20:46:51 +00:00
gergely.erdelyi
2edeeae88b idautils.py: Classes are all newskool. Fixed a pylint warning. 2009-10-17 20:43:09 +00:00
gergely.erdelyi
8e66e14588 idautils.py: Small whitespace and indentation fixes 2009-10-17 20:38:40 +00:00
gergely.erdelyi
9c80378afe idautils.py: Added missing self 2009-10-17 20:33:09 +00:00
elias.bachaalany
2f31ce656b build.py: now build.py will use the "IDA" environment variable (if it exists) to tell where the SDK is.
(for example if IDA=$HOME/idasdk, then build will use $IDA/include and $IDA/libXXXXX)
2009-10-16 12:07:18 +00:00
elias.bachaalany
b09eea4de8 idapython was not compiling since r239 (it was using an unpublished API) 2009-10-12 11:13:25 +00:00
elias.bachaalany
9917459559 idautils.py: Added Threads() iterator to enum threads 2009-10-05 10:35:27 +00:00
elias.bachaalany
4191b186d9 kernwin.i: added code markers to choose2 wrapper code (for easier maintenance) 2009-10-05 10:34:29 +00:00
elias.bachaalany
5fe579530a dbg.i/idd.i: wrapped some functions from the dbg/debugger_t class: get_manual_regions/dbg_get_memory_info/dbg_get_registers/dbg_get_thread_sreg_base/dbg_read_memory/dbg_write_memory/dbg_can_query 2009-10-05 10:30:50 +00:00
elias.bachaalany
e2a0ee8204 graph.i: fixed a small bug with gettext / background color
- removed some whitespaces
- added some code markers
2009-10-05 10:28:01 +00:00
elias.bachaalany
7ea3709021 graph.i: added graph support (works only with the GUI version) 2009-10-02 17:40:26 +00:00
elias.bachaalany
d278419064 added Choose2() support 2009-09-24 14:20:29 +00:00
elias.bachaalany
56f6dc02be kernwin.i: fixed a reference leak 2009-09-24 10:43:25 +00:00
elias.bachaalany
9f4df6991f idautils.py: GetDataList() was not working with 64bit addresses 2009-09-24 10:42:09 +00:00
elias.bachaalany
45099f4ad4 idautils.py: added qword support for GetDataList() 2009-09-23 07:03:16 +00:00
elias.bachaalany
5e0deab556 typeinf.i: fixed %rename directive for load_til_header() 2009-09-22 15:39:50 +00:00
elias.bachaalany
8bf3e2054d kernwin.i: added add_menu_item to ignore list (it was being wrapped twice (as overloaded function)) 2009-09-22 15:38:57 +00:00
elias.bachaalany
4e02442b9a idp.i: added AssembleLine() which is similar to assemble() but assembles into a buffer instead
idautils.py: added Assemble() utility function
2009-09-22 14:36:55 +00:00
elias.bachaalany
910f88f6b7 - added NearestName class 2009-09-17 11:48:18 +00:00
elias.bachaalany
3ea31d70c7 - wrapped get_debug_names() (check ex_debug_names.py) 2009-09-17 11:46:35 +00:00
gergely.erdelyi
38b7c484f3 gdl.i: Small typo and whitespace fixes 2009-09-16 19:01:45 +00:00
elias.bachaalany
e27524cca5 idautils: added Strings class to enumerate strings (check ex_strings.py)
gdl.i: added FlowChart and BasicBlock classes (check examples / ex_gdl_qflow_chart)
idc.py : fixed MakeName() and AnalyseArea() (they were not returning return values)
2009-09-16 14:00:31 +00:00
gergely.erdelyi
e51eb69e3a idautils.py: Small docstring formatting fixes. 2009-09-13 17:37:43 +00:00
gergely.erdelyi
5e93f49c97 python.cpp: More places allow breaking of long-running scripts. Thanks Elias for the patch! 2009-09-13 17:37:04 +00:00
gergely.erdelyi
08ea62d8fa kernwin.i: Copying strings with strcpy is baad. Thanks Elias for the patch! 2009-09-13 17:36:05 +00:00
gergely.erdelyi
39d692c258 idc.py: Removed redundant definition of OpFloat() 2009-09-07 17:16:06 +00:00
gergely.erdelyi
e48d6a99ff bytes.i: Added invalidate_dbgmem_config() and invalidate_dbgmem_contents(). Thanks to Elias Bachaalany for the patch. 2009-09-07 17:14:21 +00:00
gergely.erdelyi
fb507d9f85 idautils.py: Added FuncItems() and DecodeInstruction(). Thanks to Elias Bachaalany for the patch. 2009-09-07 17:08:30 +00:00
gergely.erdelyi
5b0260c301 idaapi.i: Added typedef for error_t 2009-08-30 12:18:15 +00:00
gergely.erdelyi
02c6a5519e idc.py: IDC wrapper brought up to par with IDA 5.5 2009-08-30 12:17:50 +00:00
gergely.erdelyi
88f7e089aa init.py: Removed obsolete warning filtering 2009-08-30 11:15:41 +00:00
gergely.erdelyi
ab34ed6573 init.py: runscript() now works on Python 2.6 too. Thanks to Christian Blichmann for the patch. 2009-08-28 17:03:59 +00:00
gergely.erdelyi
013546b569 init.py: idaapi is now imported by default to the main namespace 2009-07-21 19:47:00 +00:00
gergely.erdelyi
a01b3fbde0 Removed few FIXMEs 2009-07-21 19:43:19 +00:00
gergely.erdelyi
1a4a43a389 structure.py: Use -1 instead of BADADDR is IDC mandates 2009-07-21 19:42:58 +00:00
gergely.erdelyi
860c96daf3 STATUS.txt: Updated the wrapping status 2009-07-21 19:41:47 +00:00
gergely.erdelyi
2395fd6b1d funcs.i: Added get_sig_filename() and get_idasgn_title() 2009-07-21 19:31:06 +00:00
gergely.erdelyi
573ffccc4e idd.i: The char member is now converted, for real. No syntax errors. 2009-07-21 19:29:15 +00:00
gergely.erdelyi
b9f442ee1d idd.i: register_info_t.dtyp is now converted to an integer 2009-07-21 18:55:07 +00:00
gergely.erdelyi
b22d629990 build.py: Version bumped to 1.2.90 2009-07-21 18:49:56 +00:00
gergely.erdelyi
b184767ba0 ua.i: insn_t char members are converted to integers 2009-07-21 18:45:58 +00:00
gergely.erdelyi
3eb4d4710a ua.i: op_t char member (n, offb, etc.) are now correctly converted to integers 2009-07-21 18:38:51 +00:00
gergely.erdelyi
9530fbacfa init.py: Replace non-printable characters in stdout/stderr going to the message window 2009-07-21 18:10:02 +00:00
gergely.erdelyi
9876c4ffa7 init.py: __file__ path is properly set for scripts run with Alt-9 2009-07-19 17:22:21 +00:00
gergely.erdelyi
b0d8723ccb idc.py: AddStrucMember() and SetMemberType() switched to native IDC implementation 2009-07-17 17:58:57 +00:00
gergely.erdelyi
09ead310b7 Updated the changelog 2009-07-12 16:03:43 +00:00
gergely.erdelyi
c25f1a0121 build.py: Version bumped to 1.2.0 2009-07-12 15:20:51 +00:00
gergely.erdelyi
e64fdf16b3 idc.py: GetFchunkAttr() now calls the IDC implementation and should return identical results 2009-07-12 15:05:49 +00:00
gergely.erdelyi
5cb6044277 idautils.py: Clarified the note in Functions() 2009-07-12 14:35:13 +00:00
gergely.erdelyi
700dcef6cd idautils.py: Added notes about Functions()'s behaviour when a function has chunks in multiple segments 2009-07-12 14:31:03 +00:00
gergely.erdelyi
b5f3edf5fc idautils.py: Functions() now work properly if start is not inside a defined function 2009-06-25 16:11:17 +00:00
gergely.erdelyi
dadf628feb Small batch of IDA 5.5 compatibility fixes. 2009-06-20 13:51:07 +00:00
gergely.erdelyi
2cc8e934f6 Readme and changelog updates 2009-05-23 16:56:26 +00:00
gergely.erdelyi
e0de735f3d build.py: 64-bit building is now really optional 2009-05-23 16:55:49 +00:00
gergely.erdelyi
7d468f3b94 Intentation consistency and misc formatting fixes 2009-05-23 16:35:50 +00:00
gergely.erdelyi
f2e422d208 idc.py: Fixed a wrong copy & paste 2009-05-23 16:35:07 +00:00
gergely.erdelyi
d197df5653 idc.py: Added 64-bit versions of constants 2009-05-23 15:33:25 +00:00
gergely.erdelyi
3fbe778385 init.py: Banner now includes if the plugin is a 64-bit build 2009-05-23 15:33:03 +00:00
gergely.erdelyi
dec108c25b build.py: Removed a bit of dead code 2009-05-23 14:41:26 +00:00
gergely.erdelyi
5a66395061 64-bit build support. Thanks to Ariel Shiftan and Itai Shaham for the initial patch. 2009-05-23 14:40:01 +00:00
gergely.erdelyi
05e10a0f25 python.cpp: Small cleanups and formatting fixes 2009-05-22 20:05:36 +00:00
gergely.erdelyi
ef9921587b python.cpp: Indentation consistency and misc formatting fixes 2009-05-22 15:59:38 +00:00
gergely.erdelyi
260c813f05 build.py: Removed unnecessary link parameters 2009-05-21 19:32:16 +00:00
gergely.erdelyi
097a6ae4b0 python.cpp: Importing binary Python extensions now works more reliably on Linux. Thanks to Phil Ashby for the patch! 2009-05-21 19:28:13 +00:00
gergely.erdelyi
791fde6af7 Fixed netnode::getblob() 2009-05-04 19:07:51 +00:00
gergely.erdelyi
9b6a6eda86 netnode.i: netnode::hashval with the netnode_idx argument is now called hashval_idx to make the other version work 2009-05-04 19:06:16 +00:00
gergely.erdelyi
b4d2b3f813 idapythonrc.py: Added example for setting the script run timeout 2009-05-04 19:04:33 +00:00
gergely.erdelyi
6d6f4f70fc Long-running scripts can now be cancelled (in the GUI version) . Thanks to Igor Skochinsky for the original patch. 2009-05-03 20:26:47 +00:00
gergely.erdelyi
78ca9145bf build.py: Version bumped to 1.1.91 2009-05-03 20:25:07 +00:00
gergely.erdelyi
b21e3b5230 idc.py: Added OpFloat()
idc.py: Stricter type check in SetRegValue(). Thanks to Igor Skochinsky for the patches.
2009-04-28 16:13:57 +00:00
gergely.erdelyi
d26536abd4 idautils.py: Heads() and Functions() now used inf.minEA and inf.maxEA as default parameters
idautils.py: Heads() will not yield a head at 'start' if there is none
2009-04-27 18:20:02 +00:00
gergely.erdelyi
769e9d70f4 idautils.py: Many functions converted to generators 2009-04-27 18:05:14 +00:00
gergely.erdelyi
864165a44c Added support for retrieving large local types 2009-04-27 17:38:17 +00:00
gergely.erdelyi
5e1871f485 build.py: Fix for building under Vista. Thanks to Itai Shaham for the report! 2009-04-26 18:36:35 +00:00
gergely.erdelyi
1c4a240cfb Updated year in copyright strings 2009-04-26 18:28:59 +00:00
gergely.erdelyi
5876f4324f pro.i: Updated %ignore list 2009-04-26 18:25:57 +00:00
gergely.erdelyi
252fcf8052 idc.py: A batch of docstring fixes. Thanks to Ange Albertini for the patch! 2009-04-25 17:55:37 +00:00
gergely.erdelyi
f9f30154d2 Fixed build script to work on x86_64 Linux. Thanks to Christian Blichmann for the patch! 2009-04-21 16:48:47 +00:00
gergely.erdelyi
8f69725171 Removed obsolete patch copy from build script. Thanks to Itai Shaham for the report. 2009-04-21 15:52:43 +00:00
gergely.erdelyi
a91da72224 Removed obsolete IDA 5.3 SDK patch. 5.4 does not need any special patches 2009-03-29 17:09:36 +00:00
gergely.erdelyi
56476d656a %feature("compactdefaultargs") is now global
Added support for void * + len input/output buffers (many netnodes function use it)
2009-03-29 16:55:31 +00:00
gergely.erdelyi
265db07b35 Added type definition binary_output_or_none to accept void * output buffers with size 2009-03-29 16:54:13 +00:00
gergely.erdelyi
a447822586 build.py: Version bumped to 1.1.90 2009-03-29 16:51:49 +00:00
gergely.erdelyi
f4f5aa0441 idc.py: Fixed GetOpType() and GetOperandValue() to use decode_insn() so they are not destructive
idc.py: Fixed MakeCode() to use the new create_insn()
2009-03-22 15:27:46 +00:00
gergely.erdelyi
927ccec772 idp.i: Simplified the assemble() implementation 2009-03-22 15:16:45 +00:00
gergely.erdelyi
f352f77edf idp.i: Added assemble() function to idaapi. Thanks to Ero Carrera for the patch. 2009-03-22 14:58:07 +00:00
gergely.erdelyi
b961ced412 idc.py: Fixed GetDebuggerEvent(). 2009-03-02 17:23:47 +00:00
gergely.erdelyi
32654c9ee8 build.py: Added alternative SDK location (commented by default) 2009-01-27 18:10:42 +00:00
gergely.erdelyi
e4aaf2b166 README.txt: Updated location of user init script 2009-01-27 18:09:47 +00:00
gergely.erdelyi
419a08135a Added example user init script 2009-01-27 18:09:23 +00:00
gergely.erdelyi
f703a5fb3c ScriptBox_instance renamed to scriptbox 2009-01-27 18:08:54 +00:00
gergely.erdelyi
48301d9703 python.cpp: Added error handling to return_python_result()
python.cpp: Added plugin arguments to enable/disable exlang_python
python.cpp: Patch by Igor Skochinsky
2009-01-27 17:52:36 +00:00
gergely.erdelyi
b97846eeae idc.py: Block write access to read-only attributes
idc.py: Added debug event-related functions
idc.py: Added local type manipulation functions
idc.py: Patches by Igor Skochinsky
2009-01-27 17:48:50 +00:00
gergely.erdelyi
0b812262a7 typeinf.i: Added IDC wrappers for local type manipulations. Patch by Igor Skochinsky. 2009-01-27 17:46:33 +00:00
gergely.erdelyi
9a8f92ac52 funcs.i: Added wrapper get_fchunk_referer(). Patch by Igor Skochinsky. 2009-01-27 17:39:16 +00:00
gergely.erdelyi
e9f1e04519 idautils.py: CPU registers are now accessible as cpu.EAX (bot read and write). Patch by Igor Skochinsky 2009-01-27 17:37:10 +00:00
gergely.erdelyi
d3ac331e36 idd.i: Wrapper functions to access debug_event_t. Patch by Igor Skochinsky 2009-01-27 17:27:54 +00:00
gergely.erdelyi
00224b8e40 init.py: Reformatted plugin init banner 2009-01-25 19:03:46 +00:00
gergely.erdelyi
c1e87cc17b build.py: Version bumped to 1.1.0 2009-01-25 16:36:07 +00:00
gergely.erdelyi
98240e2ee9 loader.i: Added database_flags 2009-01-25 16:35:31 +00:00
gergely.erdelyi
599d1c3c29 allins.i: Removed uneeded hack 2009-01-25 16:34:53 +00:00
gergely.erdelyi
0bc9d6477c expr.i: Merge from Ilfak: Wrapped calcexpr() and calc_idc_expr() 2009-01-25 16:34:08 +00:00
gergely.erdelyi
04492e420c idc.py: Merge from Ilfak. Implemented and fixed Eval(), SaveBase(), MakeData(), FirstSeg(), GetNextSeg(), SegCreate(), SetFChunkAttr(), SetLocalType(), GetFchunkReferer() 2009-01-25 16:32:58 +00:00
gergely.erdelyi
43af79132f python.cpp: Proper extlang implementation from Ilfak
python.cpp: Cleanups and fixes from Ilfak
2009-01-25 16:30:05 +00:00
gergely.erdelyi
1a45b5952a python.cpp: Removed trailing whitespaces 2009-01-25 15:57:53 +00:00
gergely.erdelyi
507ea15b7a idc.py: Removed FIXME from PatchByte()
idc.py: Removed trailing whitspaces
2009-01-25 14:12:59 +00:00
gergely.erdelyi
473bd07bdb idc.py: Many updates to bring the wrapper up to IDA 5.4 2009-01-22 18:57:20 +00:00
gergely.erdelyi
f8c34bd805 Updated SDK patch for IDA 5.3 2009-01-20 22:02:33 +00:00
gergely.erdelyi
bb99a7076e idaapi.i: Added 64-bit BADADDR and BADSEL 2009-01-20 22:00:51 +00:00
gergely.erdelyi
b687523dd9 CLI interface is activated only for IDA 5.4 or newer 2009-01-20 22:00:05 +00:00
gergely.erdelyi
f59fbb02fe Added rudimentary support for the new interactive command-line in IDA 5.4 2009-01-19 20:38:59 +00:00
gergely.erdelyi
1da716734e Updated symbol ignores for SDK version 5.4 2009-01-19 19:41:24 +00:00
gergely.erdelyi
9fe2d0048b idaapi.i: Added BADNODE constant
idaapi.i: Added empty CASSERT define
idaapi.i: Added uval_array type
2009-01-19 19:40:14 +00:00
gergely.erdelyi
867940ae80 build.py: Version bumped to 1.0.51
build.py: Default SDK version changed to 5.4
2009-01-19 19:38:02 +00:00
gergely.erdelyi
c03dd84eef kernwin.i: ulong changed to uint32 2009-01-19 19:35:20 +00:00
gergely.erdelyi
d05ef16b13 kernwin.i: %ignore statements moved to top
kernwin.i: Ignoring cli_t (for IDA 5.4)
2009-01-18 15:45:52 +00:00
gergely.erdelyi
e0e7d9d56c idc.py: Fixed the name of GetMemberName(). Thanks forgot! 2008-12-21 10:52:45 +00:00
gergely.erdelyi
e8df46dc30 idc.py: Fixed high FF_* constants to be unsigned
idc.py: Fixed isByte() .. isAlign() functions
2008-12-10 14:55:11 +00:00
gergely.erdelyi
ef61a9bac7 kernwin.i: Fixed modal chooser constant 2008-12-10 14:17:23 +00:00
gergely.erdelyi
caecd08a77 kernwin.i: Added workaround for Choose() sometimes crashing with non-modal choosers 2008-12-10 14:12:23 +00:00
gergely.erdelyi
97213fabb4 kernwin.i: Title is now correctly displayed
kernwin.i: Chooser properly lists non-string items also
2008-12-10 11:30:58 +00:00
gergely.erdelyi
ca5ed24ff0 idc.py: SetColor() now updated the colours properly. Thanks to google at simon.user.lysator.liu.se for the report. 2008-11-16 16:05:00 +00:00
gergely.erdelyi
7d0f743143 idc.py: Implemented many debugging-related functions
idc.py: Misc fixes and cleanups
2008-11-16 15:22:09 +00:00
gergely.erdelyi
23dcd0a165 Added separate interface file for idd.hpp 2008-11-02 18:34:05 +00:00
gergely.erdelyi
0b8d39d230 gdl.i: Removed setup_graph_subsystem() 2008-11-02 18:33:31 +00:00
gergely.erdelyi
b499990614 Wrapped gdl.hpp 2008-11-02 15:00:52 +00:00
gergely.erdelyi
919b3d9987 idautils.py: Replaced GetInputFileMD5 with a call to the IDC version 2008-11-02 08:37:57 +00:00
gergely.erdelyi
c8f6c02147 idc.py: IDC wrapper merged with 5.3 changes. Not everything is implemented yet. 2008-10-11 13:33:26 +00:00
gergely.erdelyi
490fa999c4 python.cpp: Added float support for extlang_python
python.cpp: Proper error reporting implemented
2008-10-11 09:09:46 +00:00
gergely.erdelyi
ec4d2f7a06 idaapi.i: Added enable_extlang_python() to enable the Python external evaluator 2008-10-07 17:21:58 +00:00
gergely.erdelyi
1844d89d34 python.cpp: Rudimentary support for Python as external evaluation language 2008-10-07 17:21:01 +00:00
gergely.erdelyi
91df782723 Ignoring definitions that break the build. 2008-10-04 12:38:29 +00:00
gergely.erdelyi
ee137adaa6 build.py: Replaced patch name in source package 2008-10-04 12:36:48 +00:00
gergely.erdelyi
8d9869b527 idc.py: Fixed isLoaded() 2008-10-02 14:34:12 +00:00
gergely.erdelyi
b4552cb676 Added hotkey example script 2008-10-01 15:42:09 +00:00
gergely.erdelyi
6449172afe Removed 5.1 SDK patch. 2008-10-01 15:41:40 +00:00
gergely.erdelyi
2d4662a3c3 Added SDK patch for IDA 5.3 2008-10-01 15:41:16 +00:00
gergely.erdelyi
2c09e0e429 CHANGES.txt: Updated changes from 1.0 branch 2008-10-01 15:38:47 +00:00
gergely.erdelyi
b6a6513dec Initial changes for the IDA 5.3 build. 2008-10-01 15:03:57 +00:00
gergely.erdelyi
e994bd9d11 build.py: More example scripts are copied to the distribution 2008-09-28 08:56:48 +00:00
gergely.erdelyi
70e5a9a55c idc.py: Fixed GetMemberStrId(). Thanks to nobodyzzz for the report. 2008-09-27 13:35:56 +00:00
gergely.erdelyi
a7726cbbd6 More doc updates 2008-09-01 18:55:03 +00:00
gergely.erdelyi
b6864df344 Updated the SDK patch 2008-09-01 18:39:48 +00:00
gergely.erdelyi
17a5eca7a6 Small doc updates 2008-09-01 18:32:22 +00:00
gergely.erdelyi
e0186f450a build.py: Version bumped to 0.9.61 2008-08-31 19:17:35 +00:00
gergely.erdelyi
358d85ac46 idaapi.py: Added sel_array()
idaapi.py: Renamed *Array to *_array 
idautils.py: Renamed *Array to *_array 
idc.py: Renamed *Array to *_array
2008-08-31 17:58:56 +00:00
gergely.erdelyi
e3a0a26f16 idaapi.i: Added sel_array() 2008-08-31 17:54:16 +00:00
gergely.erdelyi
ab13c8b983 idaapi.i: Added sel_pointer() 2008-08-31 17:46:06 +00:00
gergely.erdelyi
d39feebe72 segment.i: Added getn_selector() and *_segment_translations() 2008-08-31 17:45:20 +00:00
gergely.erdelyi
b4e25f451a idc.py: Minor docstring fixes 2008-08-31 17:43:05 +00:00
gergely.erdelyi
565a80c62e idc.py: Fixed AskSelector() and FindSelector() 2008-08-31 17:36:41 +00:00
gergely.erdelyi
187f75d329 init.py: Minor cleanups 2008-08-30 17:39:07 +00:00
gergely.erdelyi
8bac109f3b idautils.py: Small refactoring 2008-08-30 16:10:00 +00:00
gergely.erdelyi
76aa24fecd idc.py: Fixed a number of problems uncovered by pylint 2008-08-30 14:48:03 +00:00
gergely.erdelyi
3656585dd8 Implemented add_menu_item() and the required callbacks. Big thanks to Ross Kinder for the patch. 2008-08-17 17:45:06 +00:00
gergely.erdelyi
9498c80547 build.py: Small formatting fixes 2008-08-15 20:59:06 +00:00
gergely.erdelyi
d06fa3e155 build.py: Make ZIP archives of the builds 2008-08-15 20:51:16 +00:00
gergely.erdelyi
29187c6f53 init.py: Added watchdog reset to runscript() 2008-08-15 20:42:09 +00:00
gergely.erdelyi
e4d97c7261 idc.py: Removed duplicate MakeUnkn() 2008-08-15 19:46:15 +00:00
gergely.erdelyi
a73663582e idc.py: Added note to MakeData() exception 2008-08-02 20:00:34 +00:00
gergely.erdelyi
61796a5623 idc.py: Implemented GetString()
idc.py: Definition updated to match IDA 5.1 idc.idc
2008-08-02 19:44:42 +00:00
gergely.erdelyi
9450a528fd init.py: Implemented a simple watchdog to catch runaway scripts 2008-07-26 10:18:28 +00:00
gergely.erdelyi
79493bdb4f Version bumped to 0.9.60 2008-07-26 09:34:55 +00:00
gergely.erdelyi
ea7daef522 netnode.i: Ignoring class WatchDog(): 2008-07-26 09:33:30 +00:00
gergely.erdelyi
353b4f9f92 nalt.i: Ignoring a couple of kernel-only symbols. 2008-07-22 18:23:32 +00:00
gergely.erdelyi
a0beaefd26 Initial wrapping of netnode.hpp. Still needs a lot of work.. 2008-07-22 18:23:05 +00:00
ero.carrera@gmail.com
2a77375c0e Fixed missing reference to idaapi module on two usages of E_PREV and E_NEXT 2008-07-19 13:45:37 +00:00
gergely.erdelyi
08f81d8b96 Updated changlelog 2008-07-17 18:51:55 +00:00
gergely.erdelyi
86d9408b93 Added interface file for allins.hpp 2008-07-17 18:49:35 +00:00
gergely.erdelyi
1a7b765989 Version bumped to 0.9.58 2008-07-17 18:47:30 +00:00
gergely.erdelyi
af27d1a6dd Wrapped allins.hpp, which contains all the instruction type codes 2008-07-17 18:46:46 +00:00
gergely.erdelyi
a8f6676623 Added small test scripts for colours. 2008-06-27 21:21:38 +00:00
gergely.erdelyi
9b2a2fd02d Added a small test script for structures. 2008-06-27 21:05:02 +00:00
gergely.erdelyi
9c4907d76c chooser.py: Fixed chooser example and added a proper header 2008-06-27 20:41:37 +00:00
gergely.erdelyi
a33eeef018 Added small script to generate function cross reference with epydoc 2008-06-25 21:03:38 +00:00
gergely.erdelyi
04af0d20f5 init.py: Added isatty() to the dummy stdout file object 2008-06-25 21:02:31 +00:00
gergely.erdelyi
40846fe7c9 idautils.py: Return copies of the xref class instances so they are storable 2008-06-16 18:47:02 +00:00
gergely.erdelyi
ee564d8a03 build.py: Version bumped to 0.9.58 2008-06-15 18:07:13 +00:00
gergely.erdelyi
c947c3f759 CHANGES.txt: Updated changelog 2008-06-15 18:06:36 +00:00
gergely.erdelyi
c026c32dc7 python.cpp: Remove menu items when unloading the plugin 2008-06-15 17:33:58 +00:00
gergely.erdelyi
e2f6ba10dc STATUS.txt: Updated IDC layer status 2008-06-15 17:08:47 +00:00
gergely.erdelyi
0315608029 idc.py: Fixed GetOperandValue() 2008-06-15 16:53:55 +00:00
gergely.erdelyi
375606cefd idc.py: Fixed SEARCH_UP in FindBinary() 2008-06-15 16:22:37 +00:00
gergely.erdelyi
754622e1c4 segment.i: Added get_defsr() and set_defsr() 2008-06-15 16:07:51 +00:00
gergely.erdelyi
c6444d4ff5 idc.py: Implemented segment register support for {Get|Set}SegmentAttr() 2008-06-15 15:44:36 +00:00
gergely.erdelyi
0065fdce94 idc.py: Whitespace conversion fixes 2008-06-15 15:23:53 +00:00
gergely.erdelyi
398ffdae3a Tabs converted to 4 spaces in Python sources. 2008-06-15 14:39:43 +00:00
gergely.erdelyi
921d57098a idc.py: Implemented OpStroff() 2008-06-15 12:12:18 +00:00
gergely.erdelyi
a979882e50 idc.py: Implemented rotate_left() 2008-06-15 12:09:46 +00:00
gergely.erdelyi
ae694a52ba idc.py: Removed a typo 2008-06-15 10:13:27 +00:00
gergely.erdelyi
9216f83c87 Updated year in copyright strings. 2008-06-15 10:03:53 +00:00
gergely.erdelyi
f103d84c83 STATUS.txt: Updated status file 2008-06-15 10:00:04 +00:00
gergely.erdelyi
e94a201897 idc.py: Deprecated XrefType() 2008-06-15 09:49:02 +00:00
gergely.erdelyi
c4830f3e81 idautils.py: Added Xref*() functions for convenient xref handling. 2008-06-15 09:36:30 +00:00
gergely.erdelyi
d0e3a964d8 idautils.py: Added Chunk() to list function chunks. Thanks to Ero Carrera for the patch. 2008-06-13 20:29:05 +00:00
gergely.erdelyi
52f26ecf67 STATUS.txt: Small update for 0.9.57 2008-05-07 10:14:32 +00:00
gergely.erdelyi
52d048cf5b Added small test script for debug event notification hooks 2008-05-04 09:43:57 +00:00
gergely.erdelyi
471191088b build.py: Version bumped to 0.9.57 2008-05-04 05:26:29 +00:00
gergely.erdelyi
b500b41661 dbg.i: First implementation of debug event callback 2008-05-04 05:08:38 +00:00
gergely.erdelyi
f9e166c69c idc.py: Added missing idaapi. to GetMemberStrId(). Thanks to abuse007 for the report and fix. 2008-04-28 19:23:05 +00:00
gergely.erdelyi
6ac2bb185d build.py: Version bumped to 0.9.56 2008-04-12 10:27:30 +00:00
gergely.erdelyi
4762f325d9 CHANGES.txt: Updated changes 2008-04-12 10:27:01 +00:00
gergely.erdelyi
c08d06ab82 expr.i: Ignoring optional _getname argument to CompileLine() 2008-04-12 10:11:14 +00:00
gergely.erdelyi
6b739548fc idc.py: Implemented Compile() 2008-04-12 09:08:37 +00:00
gergely.erdelyi
18b7a6b0ad idautils.py Do not import all symbols from idaapi to keep the namespace clean
init.py: Import the required symbols from idaapi
2008-04-12 09:08:11 +00:00
gergely.erdelyi
a24d2753ec expr.i: Fixed Compile* function to return proper error messages 2008-04-12 08:45:01 +00:00
gergely.erdelyi
d99b2eb64b python.cpp: Added RunPythonStatement() function to IDC 2008-04-12 07:32:34 +00:00
gergely.erdelyi
bab52674ca expr.i: Added CompileEx() Compile() and CompileLine() 2008-04-12 07:30:46 +00:00
gergely.erdelyi
45b614fff0 idaapi.i: Added sval_pointer() type 2008-04-10 19:43:44 +00:00
gergely.erdelyi
4059c6ec72 idc.py: Fixed documentation for GetMarkedPos(), returns BADADDR on error 2008-04-05 10:26:43 +00:00
gergely.erdelyi
ef44c5f123 idc.py: Removed UNIMPLEMENTED marker from atoa() 2008-04-05 10:25:25 +00:00
gergely.erdelyi
fc25932632 Removed extra parameter from Get{First|Next}Member(). Thanks Rodrigo Bogossian Wang for the report. 2008-02-26 20:00:41 +00:00
259 changed files with 70390 additions and 9556 deletions

27
AUTHORS.txt Normal file
View File

@ -0,0 +1,27 @@
The IDAPython Team:
* Gergely Erdelyi - http://d-dome.net/idapython/
Original IDAPython author - The IDAPython Guy -
* Hex-Rays - http://www.hex-rays.com/ - <support@hex-rays.com>
Hex-Rays joined the IDAPython project in September 2009 and started contributing.
It is primarily maintained, updated and improved by Arnaud Diederen of Hex-Rays.
* Elias Bachaalany - elias.bachaalany@gmail.com
Maintains IDAPython online source code repository and coordinates patches/updates/contributions from Hex-Rays and 3rd party contributors
* Ero Carrera - http://dkbza.org/
Project contributor
* Special thanks to the following people for their contribution, suggestions and bug fixes:
Igor Skochinsky
Sebastian Muniz
cbwhiz
Arnaud Diederen

View File

@ -1,63 +1,78 @@
----------------------------------------------------------
IDAPython - Python plugin for Interactive Disassembler Pro
----------------------------------------------------------
Building From Source
--------------------
REQUIREMENTS
[Tested versions are in brackets]
- IDA and IDA SDK [5.1]
http://www.datarescue.com/idabase/
- Python [2.4.4, 2.5.1]
http://www.python.org/
- Simplified Wrapper Interface Generator (SWIG) [1.3.31]
http://www.swig.org/
- Unix utilities (GNU patch on Windows):
http://www.research.att.com/sw/tools/uwin/ or
http://unxutils.sourceforge.net/ or
http://www.cygwin.com/
- GCC on Linux and Mac OS X [4.1.3]
Comes with your distribution
- Microsoft Visual C on Windows [Microsoft Visual C++ 2005 Express Edition]
http://msdn.microsoft.com/vstudio/express/visualc/
BUILDING
Make sure all the needed tools (compiler, swig) are on the PATH.
1, Unpack the IDAPython source and IDA Pro SDK into the following
directory structure:
swigsdk-versions/5.1/ - version 5.1 of the IDA Pro SDK
idapython/ - IDAPython source code
2, Patch the SDK using GNU Patch with one of patches from patches/ directory.
You will have to use the -P option depending on which directory you
patch from.
3, On Mac OS X copy libida.dylib from the IDA install directory to
swigsdk-versions/5.1/libgcc32.mac/
4, Build the plugin
python build.py
It is possible to build the plugin for different Python versions by
running build.py with the corresponding Python binary.
5, Install the components as described in README.txt
See build.py for build details and possible tweaks.
-------------------------------------------------------------------------------
Copyright (c) 2004-2007 Gergely Erdelyi <dyce@d-dome.net>. All rights reserved.
-------------------------------------------------------------------------------
------------------------------------------------------
IDAPython - Python plugin for Interactive Disassembler
------------------------------------------------------
Building From Source
--------------------
REQUIREMENTS
------------
[Tested versions are in brackets]
- IDA and IDA SDK [> 5.6]
http://www.hex-rays.com/idapro/
- Python [2.5.1, 2.6.1, 2.7]
http://www.python.org/
- Simplified Wrapper Interface Generator (SWIG) [2.0.12]
http://www.swig.org/
Hex-Rays cannot guarantee support for IDAPython
versions built with other versions of SWIG.
- Unix utilities (GNU patch on Windows):
http://www.research.att.com/sw/tools/uwin/ or
http://unxutils.sourceforge.net/ or
http://www.cygwin.com/
- GCC on Linux and Mac OS X [4.0.1, 4.1.3]
Comes with your distribution
- Microsoft Visual C on Windows [Microsoft Visual C++ 2008 Express Edition]
http://msdn.microsoft.com/vstudio/express/visualc/
BUILDING
--------
Make sure all the needed tools (compiler, swig) are on the PATH.
1. Unpack the IDAPython source and IDA SDK into the following
directory structure:
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
swigsdk-versions/x.y/lib/x86_mac_gcc_64/
3. Build the plugin
python build.py
It is possible to build the plugin for different Python versions by
running build.py with the corresponding Python binary.
Run 'build.py --help' for more information.
4. Install the components as described in README.txt
See build.py for build details and possible tweaks.
On 64 bits distributions, you may need to compile Python to generate a 32bit
version of the interpreter:
1. tar xvf Python-2.6.6.tar.bz2
2. cd Python-2.6.6
3. CC="gcc -m32" CXX="c++ -m32" ./configure --prefix=/path/to/py32 --enable-shared
4. make
5. make install
6. cd /path/to/py32/lib
7. ln -s libpython2.6.so.1.0 libpython2.6.so.1
8. PYTHONHOME=/path/to/py32 LD_LIBRARY_PATH=/path/to/py32/lib idaq

View File

@ -1,72 +1,229 @@
Changes from version 0.9.0 to 0.9.53
------------------------------------
- Upgraded IDA Pro base version to 5.1
- Experimental Mac OS X support
- Improved IDC coverage
- Cleanups and fixes
Changes from version 0.8.0 to 0.9.0
-----------------------------------
- Upgraded base version to IDA Pro 5.0
- Works with IDA Pro 5.1
- Python 2.4 and 2.5 supported
- Close to complete IDC compatbility layer (in sync with 4.9)
- Significatnly improved IDA SDK API covergage (see STATUS.txt for details)
- IDA SDK patch size reduced to less than half
- Simplified installation (plugins.cfg modification not needed)
- Evaluation window content is saved over IDA restarts (in the database)
- Windows version is built with Microsoft Visual C++ Express Edition
- Build makefile replaced with a Python script
- Cleanups and small fixes
Changes from version 0.7.0 to 0.8.0
-----------------------------------
- Added support for IDA Pro 4.9
- Dropped support for IDA Pro 4.7
- NOTE: Windows version is linked against Python 2.4.
- New wrappers: search.hpp, dbg.hpp, loader.hpp, diskio.hpp, nalt.hpp
- idc.py synced up to IDA 4.8
- Added 38 IDC functions
- Fixed asklong(), askseg() and askaddr()
- Automatically generated cross reference documentation (epydoc)
- User-specific init file support (see README,txt)
- Deprecated some functions that have direct Python equivalents (see idc.py)
- Fixed exception in ScriptBox when invoked empty.
- Lots of cleanups and small fixes
Changes from version 0.6.0 to 0.7.0
-----------------------------------
- Batch execution support (use the option -OIDAPython:yourscript.py)
- Added ScriptBox - lists previously run scripts (Hotkey:Alt-7)
- Added support for IDA Pro 4.8 (both Linux and Windows)
- Dropped support for IDA Pro 4.6 and 4.6SP1 versions
- Wrapped the list chooser (see examples/choose.py)
- A dozen or so IDC functions added
- Lots of char * API calls wrapped
- Added Python error handling in the plugin C layer
- Bunch of misc small cleanups and fixes
- For more details see CHANGES-SWIG.txt and CHANGES-Plugin.txt
- API CHANGE: {Next|Prev}Function() return BADADDR instead of -1
Changes from version 0.5.0 to 0.6.0
-----------------------------------
- Added support for IDA Pro 4.7 (both Linux and Windows)
- Dropped support for IDA Pro 4.6SP1 beta on Linux
- Lots of IDC wrapper additions and fixes:
- Added 30+ new wrappers to idc.py
- Most Find*, Ask* and Seg* are now wrapped
- Fixed broken NextAddr(), PrevAddr(), MakeFunction() and MakeName()
- Fixes to the makefile
- Cleanups for the idaapi wrapper
- Bunch of misc small cleanups and fixes
- For more details see CHANGES-SWIG.txt and CHANGES-Plugin.txt
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
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
------------------------------------
- fix for Python autorun script vulnerability reported by Greg MacManus
- remove current directory from sys.path during initialization
- added PyWraps sources. This will facilitate deployment, development and
debugging of IDAPython additions
- bugfix: op_t.is_reg() was buggy
- bugfix: build.py was putting duplicate files into the .zip
- bugfix: added back wrapped version of get_ascii_contents()
Changes from version 1.5.2 to 1.5.3
------------------------------------
- IDA Pro 6.2 support
- added set_idc_func_ex(): it is now possible to add new IDC functions using Python
- added visit_patched_bytes() (see ex_patch.py)
- added support for the multiline text input control in the Form class
- added support for the editable/readonly dropdown list control in the Form class
- added execute_sync() to register a function call into the UI message queue
- added execute_ui_requests() / check ex_uirequests.py
- added add_hotkey() / del_hotkey() to bind Python methods to hotkeys
- added register_timer()/unregister_timer(). Check ex_timer.py
- added the IDC (Arrays) netnode manipulation layer into idc.py
- added idautils.Structs() and StructMembers() generator functions
- removed the "Run Python Statement" menu item. IDA now has a unified dialog.
Use RunPlugin("python", 0) to invoke it manually.
- better error messages for script plugins, loaders and processor modules
- bugfix: Dbg_Hooks.dbg_run_to() was receiving wrong input
- bugfix: A few Enum related functions were not properly working in idc.py
- bugfix: GetIdaDirectory() and GetProcessName() were broken in idc.py
- bugfix: idaapi.get_item_head() / idc.ItemHead() were not working
Changes from version 1.5.1 to 1.5.2
------------------------------------
- added ui_term/ui_save/ui_saved/ui_get_ea_hint UI notifications
- added ph_get_operand_info() to retrieve operand information while debugging
- added PteDump.py script
- bugfix: read/write_dbg_memory() and dbg_get_thread_sreg_base() were not working with all debugger modules
- bugfix: idaapi.netnode.getblob() was limited to MAXSPECSIZE
- bugfix: idc.GetString()/idaapi.get_ascii_contents()/idautils.Strings() were limited to MAXSTR string length
- bugfix: idaapi.del_menu_item() was failing to delete some menu items
- bugfix: dbg_bpt was called instead of dbg_trace for a DBG_Hooks class implementation (old bug from 0.9.x)
- bugfix: Form.GetControlValue() was not working with numeric controls
- bugfix: SetBptCnd() was broken
- bugfix: idaapi.get_func_cmt() was memory leaking
Changes from version 1.5.0 to 1.5.1
------------------------------------
- Introduced the CLI '?' pseudo-command to retrieve doc strings
- Introduced the CLI '!' pseudo-command to shell execute a command
- bugfix: High 64 bit addresses were not parsed correctly in IDA64
- Added IDP/assemble notification event
- bugfix: AskUsingForm() C function was not wrapped by SWIG
- NextHead()/PrevHead() have optional 2nd parameter now
Changes from version 1.4.3 to 1.5.0
------------------------------------
- IDA Pro 6.1 support
- Added AskUsingForm() with embedded forms support (check ex_askusingform.py example and formchooser.py in the SDK)
- Added idautils.DecodePreviousInstruction() / DecodePrecedingInstruction()
- Added idc.BeginTypeUpdating() / EndTypeUpdating() for fast batch type update operations
- Added more IDP callbacks
- Added UI_Hooks with a few notification events
- Added idaapi.process_ui_action() / idc.ProcessUiAction()
- Added netnode.index() to get netnode number
- Better handling of ea_t values with bitwise negation
- Execute statement hotkey (Ctrl-F3), script timeout, and other options are now configurable with Python.cfg
- bugfix: idaapi.msg() / error() and warning() so they don't accept vararg
- bugfix: processor_t.id constants were incorrect
- bugfix: get_debug_names() was broken with IDA64
- Various bugfixes
- Added Scripts folder containing various IDAPython scripts
Changes from version 1.4.2 to 1.4.3
------------------------------------
- IDA Pro 6.0 support
- Python CLI now prints expression evaluation result (no need to use print())
- Changed Alt-8 to Ctrl-F3 (because it conflicts with window switching key Alt+n)
- Added get_highlighted_identifier()
- Added PluginForm class to allow UI development with either PyQt4 or PySide
- Added idautils.Entries() to enum entrypoints
Changes from version 1.4.1 to 1.4.2
------------------------------------
- Added command completion
- Added necessary changes so it compiles with Python 2.7
- Wrapped set_user_defined_prefix()
Changes from version 1.4.0 to 1.4.1
------------------------------------
- Added cli_t
- Added idaapi.ph to access current process fields
- Changed the copyright string to IDAPython Team
- Some platform dependant classes are present but useable only where applicable
Changes from version 1.3.0 to 1.4.0
------------------------------------
- IDA Pro 5.7 support
- idaapi.cvar.cmd is now accessible via idapi.cmd instead
- Python statement (Alt-8) is now 16kb long
- Dropped script box and File/Python file. IDA has this functionality now.
- Refactored the code
- It is possible to turn off script timeout
- All scripts are executed via 'IDAPython_ExecScript' (check idaapi.i)
- Added '--doc' switch to "build.py" script
- Documented all manually wrapped functions (check 'pywraps' module in the docs)
- Lots of cleanups and fixes
Changes from version 1.2.0 to 1.3.0
------------------------------------
- IDA Pro 5.6 support
- Added Appcall mechanism
- Added procregs to idautils.py (r254)
- Lots of cleanups and fixes
Changes from version 1.1.0 to 1.2.0
------------------------------------
- 64-bit support (largely untested)
- IDA Pro 5.5 support
- Long running (or inifinitely looping) scripts can now be stopped
- Host of IDC updates and fixes
- netnode.hpp is now mostly wrapped
- idautils use generators instead of lists
- Functions() and GetFchunkAttr() now work properly
- Lots of cleanups and fixes
Changes from version 0.9.0 to 1.0.0
-----------------------------------
- Upgraded IDA Pro base version to 5.1
- Dropped Python 2.4 support
- Mac OS X support
- IDC compatibility layer is now complete and up to date for IDA 5.1
- INCOMPATIBLE CHANGE: the idaapi module needs to be imported manually
- Support for IDB and debug notification hooks
- Support for GUI hotkeys (see examples/hotkey.py)
- Simple two-way calling mechanism between IDC and IDAPython
- Significantly better IDA API coverage
- Support for IDB and debug event hooks
- get_current_instruction() deprecated, use the idaapi.cvar.cmd variable
- Tons of IDC fixes
- Tons of other misc fixes
Changes from version 0.8.0 to 0.9.0
-----------------------------------
- Upgraded base version to IDA Pro 5.0
- Works with IDA Pro 5.1
- Python 2.4 and 2.5 supported
- Close to complete IDC compatbility layer (in sync with 4.9)
- Significatnly improved IDA SDK API covergage (see STATUS.txt for details)
- IDA SDK patch size reduced to less than half
- Simplified installation (plugins.cfg modification not needed)
- Evaluation window content is saved over IDA restarts (in the database)
- Windows version is built with Microsoft Visual C++ Express Edition
- Build makefile replaced with a Python script
- Cleanups and small fixes
Changes from version 0.7.0 to 0.8.0
-----------------------------------
- Added support for IDA Pro 4.9
- Dropped support for IDA Pro 4.7
- NOTE: Windows version is linked against Python 2.4.
- New wrappers: search.hpp, dbg.hpp, loader.hpp, diskio.hpp, nalt.hpp
- idc.py synced up to IDA 4.8
- Added 38 IDC functions
- Fixed asklong(), askseg() and askaddr()
- Automatically generated cross reference documentation (epydoc)
- User-specific init file support (see README,txt)
- Deprecated some functions that have direct Python equivalents (see idc.py)
- Fixed exception in ScriptBox when invoked empty.
- Lots of cleanups and small fixes
Changes from version 0.6.0 to 0.7.0
-----------------------------------
- Batch execution support (use the option -OIDAPython:yourscript.py)
- Added ScriptBox - lists previously run scripts (Hotkey:Alt-7)
- Added support for IDA Pro 4.8 (both Linux and Windows)
- Dropped support for IDA Pro 4.6 and 4.6SP1 versions
- Wrapped the list chooser (see examples/choose.py)
- A dozen or so IDC functions added
- Lots of char * API calls wrapped
- Added Python error handling in the plugin C layer
- Bunch of misc small cleanups and fixes
- For more details see CHANGES-SWIG.txt and CHANGES-Plugin.txt
- API CHANGE: {Next|Prev}Function() return BADADDR instead of -1
Changes from version 0.5.0 to 0.6.0
-----------------------------------
- Added support for IDA Pro 4.7 (both Linux and Windows)
- Dropped support for IDA Pro 4.6SP1 beta on Linux
- Lots of IDC wrapper additions and fixes:
- Added 30+ new wrappers to idc.py
- Most Find*, Ask* and Seg* are now wrapped
- Fixed broken NextAddr(), PrevAddr(), MakeFunction() and MakeName()
- Fixes to the makefile
- Cleanups for the idaapi wrapper
- Bunch of misc small cleanups and fixes
- For more details see CHANGES-SWIG.txt and CHANGES-Plugin.txt

View File

@ -1,27 +1,27 @@
Copyright (c) 2004-2007 Gergely Erdelyi <dyce@d-dome.net>. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
Copyright (c) 2004-2010 Gergely Erdelyi <gergely.erdelyi@d-dome.net>. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.

View File

@ -1,70 +1,114 @@
----------------------------------------------------------
IDAPython - Python plugin for Interactive Disassembler Pro
----------------------------------------------------------
WHAT IS IDAPTYHON?
IDAPython is an IDA plugin which makes it possible to write scripts
for IDA in the Python programming language. IDAPython provides full
access to both the IDA API and any installed Python module.
Check the scripts in the examples directory to get an quick glimpse.
AVAILABILITY
Latest versions of IDAPython are available from
http://www.d-dome.net/idapython/
INSTALLATION FROM BINARIES
1, Install Python 2.4 or 2.5 from http://www.python.org/
2, Copy the directory python\ to the IDA install directory
3. Copy the plugin to the %IDADIR%\plugins\
USAGE
The plugin has three hotkeys:
- Run script (Alt-9)
- Execute Python statement(s) (Alt-8)
- Run previously executed script again (Alt-7)
Batch mode execution:
Start IDA with the following command line options:
-A -OIDAPython:yourscript.py file_to_work_on
If you want fully unattended execution mode, make sure your script
exits with a qexit() call.
User init file:
You can place your custom settings to a file called 'idapythonrc.py'
that should be placed to
${HOME}/.idapro/
or
C:\Documents and Settings\%USER%\Application Data\Datarescue\IDA Pro
The user init file is read and executed at the end of the init process.
THANKS
This project is sponsored by F-Secure Corporation by allowing me to
use some company time and resources for development. Please note that
F-Secure is only sponsoring the project, the company does not provide
any formal support for this software. Questions, comments, bug reports
should be directed to the author.
F-Secure Corporation's website is located at
http://www.F-Secure.com/
------------------------------------------------------
IDAPython - Python plugin for Interactive Disassembler
------------------------------------------------------
What is IDAPython?
------------------
IDAPython is an IDA plugin which makes it possible to write scripts
for IDA in the Python programming language. IDAPython provides full
access to both the IDA API and any installed Python module.
Check the scripts in the examples directory to get an quick glimpse.
Availability
------------
Latest stable versions of IDAPython are available from
http://code.google.com/p/idapython/downloads/list
Development builds are available from
http://code.google.com/p/idapython/
Resources
---------
The full function cross-reference is readable online at
http://www.hex-rays.com/idapro/idapython_docs/
Bugs and enhancement requests should be submitted to
http://code.google.com/p/idapython/issues/list
Mailing list for the project is hosted by Google Groups at
http://groups.google.com/group/idapython
Installation from binaries
--------------------------
1. Install 2.6 or 2.7 from http://www.python.org/
2. Copy the whole "python" directory to %IDADIR%
3. Copy the contents of the "plugins" directory to the %IDADIR%\plugins\
4. Copy "python.cfg" to %IDADIR%\cfg
Usage
-----
- Run script: File / Script file (Alt-F7)
- Execute Python statement(s) (Ctrl-F3)
- Run previously executed script again: View / Recent Scripts (Alt+F9)
* Batch mode execution:
Start IDA with the following command line options:
-A -OIDAPython:yourscript.py file_to_work_on
or
-Syourscript.py
or
-S"yourscript.py arg1 arg2 arg3"
(Please see http://www.hexblog.com/?p=128)
If you want fully unattended execution mode, make sure your script
exits with a qexit() call.
By default scripts run after the database is opened. Extended option
format is:
-OIDAPython:[N;]script.py
Where N can be:
0: run script after opening database (default)
1: run script when UI is ready
2: run script immediately on plugin load (shortly after IDA starts and before processor modules and loaders)
* User init file
You can place your custom settings to a file called 'idapythonrc.py'
that should be placed to
${HOME}/.idapro/
or
%AppData%\Hex-Rays\IDA Pro
The user init file is read and executed at the end of the init process.
Please note that IDAPython can be configured with "python.cfg" file.
* Invoking Python from IDC
The IDAPython plugin exposes a new IDC function "RunPythonStatement(string idc_code)" that allows execution
of Python code from IDC
* Invoking IDC from Python
It is possible to use the idc.Eval() to evaluate IDC expressions from Python
* Making Python the default language
By default, IDA will use IDC to evaluate expressions. It is possible to change the default language to use
Python instead of IDC.
In order to do that, please use the following IDC code:
RunPlugin("python", 3)
To disable Python language and revert back to IDC:
RunPlugin("python", 4)

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBHE7IKZaxJ/axd7pgRAk5YAJ9y6CTRsu4ZG0sHD+TyqyGyGAS0CwCgl1+2
vcxrUd1VhMXr2XVxoKWrGsE=
=oFqa
-----END PGP SIGNATURE-----

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBHE7ITZaxJ/axd7pgRAtZ9AJ41pJYymOYkP7redeJJpcqYTmSAKgCeMFIw
v0tfXhFTmr39EJCwUjOdrec=
=3cbr
-----END PGP SIGNATURE-----

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBHV/eIZaxJ/axd7pgRAiFZAKCiLDVs0vzFNuS5ZgZh3CL5n56qMACfeos+
3c2kfbIV+Q4qCpbz8Cw8Cyg=
=dvct
-----END PGP SIGNATURE-----

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBHV/eTZaxJ/axd7pgRAlKiAJ0a9mjI9eGfsqPb/WdObb4XAFBDugCgjByQ
YcbaQN3tk2VxdmpD+Tqltbw=
=6fP6
-----END PGP SIGNATURE-----

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBHV/ebZaxJ/axd7pgRAjTFAJ9f3SRhFNp2SvFz68SbjmxeEWToSwCfX/Y7
8cHoxcACw6/gEM/mzKrjuv8=
=zX9g
-----END PGP SIGNATURE-----

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBIAI/1ZaxJ/axd7pgRAhDEAJ4rYUPd3x7hkRKwJcMHQXgVQBy74gCeM7jj
zdYiv5B/0xj1AN4IhJqd4LQ=
=yfc/
-----END PGP SIGNATURE-----

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBIIYK0ZaxJ/axd7pgRApsYAJwORF9/az2CXhmK5PXKrsq+UxJW7gCeKH+J
5Ius8QbqouoDuro9/zHrzm4=
=5GuH
-----END PGP SIGNATURE-----

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBIIYLKZaxJ/axd7pgRAlieAJoDVm1O67aD7sEPUtKkknMudhh18wCePZGZ
9MGQK7mKI1IEQO0OzMx4E+s=
=T+6A
-----END PGP SIGNATURE-----

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBIIYLjZaxJ/axd7pgRAu/+AKCaii6AeImJVnsHzvCoWSwjcNNhrwCcDW0p
Pp2/23GBZO9+ibd7OgzZ6n0=
=XMWh
-----END PGP SIGNATURE-----

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBIVVv9ZaxJ/axd7pgRAvYfAKCK3Vmm702tiF/h1K8g7ZXWyU5CHwCfYnqY
h9ZBFhpl8RtK74kIOr4I9TU=
=S0SV
-----END PGP SIGNATURE-----

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBKGC63ZaxJ/axd7pgRAjrwAJ9KKGQN1sPVCSJmSAoNSn5CzCruUQCfeEhm
DMqahOYRKgV8w9V1AOFjxBg=
=g8BL
-----END PGP SIGNATURE-----

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBKGC7KZaxJ/axd7pgRAr5tAJwMo4EkBm6eB0X9sGoEofBRl9tgnACfTft/
fpd3BdtPWOdGWKuJPvS4vd8=
=0ZxF
-----END PGP SIGNATURE-----

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBKGC7KZaxJ/axd7pgRAr5tAJwMo4EkBm6eB0X9sGoEofBRl9tgnACfTft/
fpd3BdtPWOdGWKuJPvS4vd8=
=0ZxF
-----END PGP SIGNATURE-----

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBKGC7SZaxJ/axd7pgRApyBAKCcHSb4RH7uj+W6wjOy9tXI9r21mwCeNqnx
4vsxNx32RwrvDXtZQLO6T0I=
=VZ2O
-----END PGP SIGNATURE-----

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBKWgHmZaxJ/axd7pgRAuwHAJ47RV5xqKSsxlrAgSC/2EreBvJbLgCfUaLg
9f720rZUvhKfNDHUkLD9IHw=
=vd7I
-----END PGP SIGNATURE-----

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBKWgHvZaxJ/axd7pgRAgw7AJ9suUEB71dLbr+baldwnNfHVLU2ZQCeMLf8
d5zK7g95mypV9ZAaLPXcAsw=
=666W
-----END PGP SIGNATURE-----

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBI4QXlZaxJ/axd7pgRAl0EAKCXX5dPLjozMgOgma7adf9iHWuQ7QCgmgA9
Cyy6dkras6IWTlMA4rDVfc4=
=50Nz
-----END PGP SIGNATURE-----

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
iD8DBQBKWgYSZaxJ/axd7pgRAlJOAKCMMltS5iwpiM6UYF0BbRUWPZKrXQCgo3gs
E3b+tP+ZyDN3a/U1szIJ0pA=
=EV5g
-----END PGP SIGNATURE-----

Binary file not shown.

Binary file not shown.

View File

@ -1,72 +1,66 @@
Status of the IDC wrapper
-------------------------
6 function unimplemented out of 434 (98% coverage):
rotate_left
XRefType
SetMemberType
GetType
GuessType
SetType
Status of IDA API wrappers
--------------------------
COMPLETE: all possible functions wrapped, no SWIG ifdefs
INCOMPLETE: some wrapping or SWIG ifdefs still left
EXCLUDED: will not be wrapped
allins.hpp - COMPLETE
area.hpp - INCOMPLETE (SWIGdefs left)
auto.hpp - COMPLETE
bytes.hpp - INCOMPLETE (no SWIGs, some unwrapped)
compress.hpp - EXCLUDED
dbg.hpp - INCOMPLETE (SWIGs and lot of fixing to do)
demangle.hpp - EXCLUDED
diskio.hpp - INCOMPLETE (no SWIGs, some unwrapped)
entry.hpp - COMPLETE
enum.hpp - INCOMPLETE (no SWIGs, one FIXME)
err.h - EXCLUDED
exehdr.h - EXCLUDED
expr.hpp - INCOMPLETE (wrapped, needs testing)
fixup.hpp - COMPLETE
fpro.h - EXCLUDED
frame.hpp - COMPLETE
funcs.hpp - INCOMPLETE (some SWIGs, few FIXMEs)
gdl.hpp - EXCLUDED
graph.hpp - EXCLUDED
help.h - EXCLUDED
ida.hpp - INCOMPLETE (SWIGs)
idd.hpp - INCOMPLETE (SWIGs)
idp.hpp - INCOMPLETE (SWIGs)
ieee.h - EXCLUDED
intel.hpp - EXCLUDED
ints.hpp - INCOMPLETE (SWIGs)
kernwin.hpp - INCOMPLETE (SWIGs and lot of fixing to do)
lex.hpp - EXCLUDED
lines.hpp - INCOMPLETE (few FIXMEs)
llong.hpp - EXCLUDED
loader.hpp - INCOMPLETE (few FIXMEs)
md5.h - EXCLUDED
moves.hpp - COMPLETE (some needed SWIGs)
nalt.hpp - INCOMPLETE (SWIGs and lot of fixing to do)
name.hpp - INCOMPLETE (few FIXMEs)
netnode.hpp - INCOMPLETE (not wrapped at all)
offset.hpp - COMPLETE
prodir.h - EXCLUDED
pro.h - COMPLETE (some needed SWIGs)
queue.hpp - INCOMPLETE (one FIXME)
regex.h - EXCLUDED
search.hpp - INCOMPLETE (one FIXME)
segment.hpp - INCOMPLETE (no SWIGs, few FIXMEs)
sistack.hpp - EXCLUDED
srarea.hpp - INCOMPLETE (not wrapped at all)
strlist.hpp - COMPLETE
struct.hpp - COMPLETE
typeinf.hpp - INCOMPLETE (no SWIGs, lot of fixing to do)
ua.hpp - INCOMPLETE (SWIGs and lot of fixing to do)
va.hpp - EXCLUDED
vm.hpp - EXCLUDED
xref.hpp - COMPLETE
Status of the IDC layer
-----------------------
The IDC emulation layer is complete and at par with IDA 5.1,
although it would benefit from more testing.
Status of IDA API wrappers
--------------------------
COMPLETE: all possible functions wrapped, no SWIG ifdefs
INCOMPLETE: some wrapping or SWIG ifdefs still left
EXCLUDED: will not be wrapped
allins.hpp - COMPLETE
area.hpp - COMPLETE (necessary SWIGdefs)
auto.hpp - COMPLETE
bytes.hpp - COMPLETE (some minor unwrapped)
compress.hpp - EXCLUDED
dbg.hpp - INCOMPLETE (SWIGs and lot of fixing to do)
demangle.hpp - EXCLUDED
diskio.hpp - INCOMPLETE (no SWIGs, some unwrapped)
entry.hpp - COMPLETE
enum.hpp - COMPLETE
err.h - EXCLUDED
exehdr.h - EXCLUDED
expr.hpp - COMPLETE (necessary SWIGs)
fixup.hpp - COMPLETE
fpro.h - EXCLUDED
frame.hpp - COMPLETE
funcs.hpp - COMPLETE (necessary SWIGs, minor FIXME)
gdl.hpp - EXCLUDED
graph.hpp - INCOMPLETE
help.h - EXCLUDED
ida.hpp - COMPLETE
idd.hpp - COMPLETE (necessary SWIGs)
idp.hpp - COMPLETE
ieee.h - EXCLUDED
intel.hpp - EXCLUDED
ints.hpp - COMPLETE
kernwin.hpp - INCOMPLETE (SWIGs and lot of fixing to do)
lex.hpp - EXCLUDED
lines.hpp - INCOMPLETE (few FIXMEs)
llong.hpp - EXCLUDED
loader.hpp - INCOMPLETE (few FIXMEs)
md5.h - EXCLUDED
moves.hpp - COMPLETE (some needed SWIGs)
nalt.hpp - INCOMPLETE (SWIGs and lot of fixing to do)
name.hpp - INCOMPLETE (few FIXMEs)
netnode.hpp - COMPLETE
offset.hpp - COMPLETE
prodir.h - EXCLUDED
pro.h - COMPLETE (some needed SWIGs)
queue.hpp - INCOMPLETE (one FIXME)
regex.h - EXCLUDED
search.hpp - COMPLETE
segment.hpp - COMPLETE
sistack.hpp - EXCLUDED
srarea.hpp - INCOMPLETE (not wrapped at all)
strlist.hpp - COMPLETE
struct.hpp - COMPLETE
typeinf.hpp - INCOMPLETE (no SWIGs, lot of fixing to do)
ua.hpp - INCOMPLETE (SWIGs and lot of fixing to do)
va.hpp - EXCLUDED
vm.hpp - EXCLUDED
xref.hpp - COMPLETE

156
Scripts/3rd/BboeVt.py Normal file
View File

@ -0,0 +1,156 @@
"""
Original code by Bryce Boe: http://www.bryceboe.com/2010/09/01/submitting-binaries-to-virustotal/
Modified by Elias Bachaalany <elias at hex-rays.com>
"""
import hashlib, httplib, mimetypes, os, pprint, simplejson, sys, urlparse
# -----------------------------------------------------------------------
DEFAULT_TYPE = 'application/octet-stream'
FILE_REPORT_URL = 'https://www.virustotal.com/api/get_file_report.json'
SCAN_URL = 'https://www.virustotal.com/api/scan_file.json'
API_KEY = "" # Put API key here. Register an account in VT Community
# -----------------------------------------------------------------------
# The following function is modified from the snippet at:
# http://code.activestate.com/recipes/146306/
def _encode_multipart_formdata(fields, files=()):
"""
fields is a dictionary of name to value for regular form fields.
files is a sequence of (name, filename, value) elements for data to be
uploaded as files.
Return (content_type, body) ready for httplib.HTTP instance
"""
BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
CRLF = '\r\n'
L = []
for key, value in fields.items():
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"' % key)
L.append('')
L.append(value)
for (key, filename, value) in files:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"; filename="%s"' %
(key, filename))
content_type = mimetypes.guess_type(filename)[0] or DEFAULT_TYPE
L.append('Content-Type: %s' % content_type)
L.append('')
L.append(value)
L.append('--' + BOUNDARY + '--')
L.append('')
body = CRLF.join(L)
content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
return content_type, body
# -----------------------------------------------------------------------
def _post_multipart(url, fields, files=()):
"""
url is the full to send the post request to.
fields is a dictionary of name to value for regular form fields.
files is a sequence of (name, filename, value) elements for data to be
uploaded as files.
Return body of http response.
"""
content_type, data = _encode_multipart_formdata(fields, files)
url_parts = urlparse.urlparse(url)
if url_parts.scheme == 'http':
h = httplib.HTTPConnection(url_parts.netloc)
elif url_parts.scheme == 'https':
h = httplib.HTTPSConnection(url_parts.netloc)
else:
raise Exception('Unsupported URL scheme')
path = urlparse.urlunparse(('', '') + url_parts[2:])
h.request('POST', path, data, {'content-type':content_type})
return h.getresponse().read()
# -----------------------------------------------------------------------
def set_apikey(key, dbg = False):
"""
Set the VT API key
"""
global API_KEY
API_KEY = key
if dbg:
httplib.HTTPConnection.debuglevel = 1
# -----------------------------------------------------------------------
def scan_file(filename):
"""
Uploads a file for scanning.
@param filename: The filename to upload
@return: - None if upload failed
- scan_id value if upload succeeds
- raises an exception on IO failures
"""
files = [('file', filename, open(filename, 'rb').read())]
json = _post_multipart(SCAN_URL, {'key':API_KEY}, files)
data = simplejson.loads(json)
return str(data['scan_id']) if data['result'] == 1 else None
# -----------------------------------------------------------------------
def get_file_md5_hash(filename):
f = open(filename, 'rb')
r = hashlib.md5(f.read()).hexdigest()
f.close()
return r
# -----------------------------------------------------------------------
def get_file_report(filename=None, md5sum=None):
"""
Returns an report for a file or md5su.
@param filename: File name to get report. The file is used just
to compute its MD5Sum
@param md5sum: MD5sum string (in case filename was not passed)
@return: - None: if file was not previously analyzed
- A dictionary if report exists: key=scanner, value=reported name
"""
if filename is None and md5sum is None:
raise Exception('Either filename or md5sum should be passed!')
# Filename passed? Compute its MD5
if filename:
global LAST_FILE_HASH
LAST_FILE_HASH = md5sum = get_file_md5_hash(filename)
# Form the request
json = _post_multipart(FILE_REPORT_URL, {'resource':md5sum, 'key':API_KEY})
data = simplejson.loads(json)
if data['result'] != 1:
# No results
return None
else:
# date, result_dict = data['report']
return data['report'][1]
# -----------------------------------------------------------------------
def pretty_print(obj):
pprint.pprint(obj)
# -----------------------------------------------------------------------
if __name__ == '__main__':
if len(sys.argv) != 2:
print('Usage: %s filename' % sys.argv[0])
sys.exit(1)
filename = sys.argv[1]
if not os.path.isfile(filename):
print('%s is not a valid file' % filename)
sys.exit(1)
get_file_report(filename=filename)

216
Scripts/AsmViewer.py Normal file
View File

@ -0,0 +1,216 @@
# -----------------------------------------------------------------------
# This is an example illustrating how to use customview in Python
# The sample will allow you to open an assembly file and display it in color
# (c) Hex-Rays
#
import idaapi
import idautils
import idc
import os
# ----------------------------------------------------------------------
class asm_colorizer_t(object):
def is_id(self, ch):
return ch == '_' or ch.isalpha() or '0' <= ch <= '9'
def get_identifier(self, line, x, e):
i = x
is_digit = line[i].isdigit()
while i < e:
ch = line[i]
if not self.is_id(ch):
if ch != '.' or not is_digit:
break
i += 1
return (i, line[x:i])
def get_quoted_string(self, line, x, e):
quote = line[x]
i = x + 1
while i < e:
ch = line[i]
if ch == '\\' and line[i+1] == quote:
i += 1
elif ch == quote:
i += 1 # also take the quote
break
i += 1
return (i, line[x:i])
def colorize(self, lines):
for line in lines:
line = line.rstrip()
if not line:
self.add_line()
continue
x = 0
e = len(line)
s = ""
while x < e:
ch = line[x]
# String?
if ch == '"' or ch == "'":
x, w = self.get_quoted_string(line, x, e)
s += self.as_string(w)
# Tab?
elif ch == '\t':
s += ' ' * 4
x += 1
# Comment?
elif ch == ';':
s += self.as_comment(line[x:])
# Done with this line
break
elif ch == '.' and x + 1 < e:
x, w = self.get_identifier(line, x + 1, e)
s += self.as_directive(ch + w)
# Identifiers?
elif self.is_id(ch):
x, w = self.get_identifier(line, x, e)
# Number?
if ch.isdigit():
s += self.as_num(w)
# Other identifier
else:
s += self.as_id(w)
# Output as is
else:
s += ch
x += 1
self.add_line(s)
# -----------------------------------------------------------------------
class asmview_t(idaapi.simplecustviewer_t, asm_colorizer_t):
def Create(self, fn):
# Create the customview
if not idaapi.simplecustviewer_t.Create(self, "Viewing file - %s" % os.path.basename(fn)):
return False
self.instruction_list = idautils.GetInstructionList()
self.instruction_list.extend(["ret"])
self.register_list = idautils.GetRegisterList()
self.register_list.extend(["eax", "ebx", "ecx", "edx", "edi", "esi", "ebp", "esp"])
self.fn = fn
if not self.reload_file():
return False
self.id_refresh = self.AddPopupMenu("Refresh")
self.id_close = self.AddPopupMenu("Close")
return True
def reload_file(self):
if not self.colorize_file(self.fn):
self.Close()
return False
return True
def colorize_file(self, fn):
try:
f = open(fn, "r")
lines = f.readlines()
f.close()
self.ClearLines()
self.colorize(lines)
return True
except:
return False
def add_line(self, s=None):
if not s:
s = ""
self.AddLine(s)
def as_comment(self, s):
return idaapi.COLSTR(s, idaapi.SCOLOR_RPTCMT)
def as_id(self, s):
t = s.lower()
if t in self.register_list:
return idaapi.COLSTR(s, idaapi.SCOLOR_REG)
elif t in self.instruction_list:
return idaapi.COLSTR(s, idaapi.SCOLOR_INSN)
else:
return s
def as_string(self, s):
return idaapi.COLSTR(s, idaapi.SCOLOR_STRING)
def as_num(self, s):
return idaapi.COLSTR(s, idaapi.SCOLOR_NUMBER)
def as_directive(self, s):
return idaapi.COLSTR(s, idaapi.SCOLOR_KEYWORD)
def OnPopupMenu(self, menu_id):
"""
A context (or popup) menu item was executed.
@param menu_id: ID previously registered with AddPopupMenu()
@return: Boolean
"""
if self.id_refresh == menu_id:
return self.reload_file()
elif self.id_close == menu_id:
self.Close()
return True
return False
def OnKeydown(self, vkey, shift):
"""
User pressed a key
@param vkey: Virtual key code
@param shift: Shift flag
@return Boolean. True if you handled the event
"""
# ESCAPE
if vkey == 27:
self.Close()
elif vkey == ord('H'):
lineno = self.GetLineNo()
if lineno is not None:
line, fg, bg = self.GetLine(lineno)
if line and line[0] != idaapi.SCOLOR_INV:
s = idaapi.SCOLOR_INV + line + idaapi.SCOLOR_INV
self.EditLine(lineno, s, fg, bg)
self.Refresh()
elif vkey == ord('C'):
self.ClearLines()
self.Refresh()
elif vkey == ord('S'):
print "Selection (x1, y1, x2, y2) = ", self.GetSelection()
elif vkey == ord('I'):
print "Position (line, x, y) = ", self.GetPos(mouse = 0)
else:
return False
return True
# -----------------------------------------------------------------------
class asmviewplg(idaapi.plugin_t):
flags = idaapi.PLUGIN_KEEP
comment = "ASM viewer"
help = "This is help"
wanted_name = "ASM file viewer"
wanted_hotkey = "Alt-F8"
def __init__(self):
self.view = None
def init(self):
return idaapi.PLUGIN_KEEP
def run(self, arg):
if self.view:
self.Close()
fn = idc.AskFile(0, "*.asm", "Select ASM file to view")
if not fn:
return
self.view = asmview_t()
if not self.view.Create(fn):
return
self.view.Show()
def term(self):
if self.view:
self.view.Close()
def PLUGIN_ENTRY():
return asmviewplg()

175
Scripts/CallStackWalk.py Normal file
View File

@ -0,0 +1,175 @@
"""
A script that tries to determine the call stack
Run the application with the debugger, suspend the debugger, select a thread and finally run the script.
Copyright (c) 1990-2009 Hex-Rays
ALL RIGHTS RESERVED.
v1.0 - initial version
v1.0.1 - added stack segment bitness detection, thus works with 64bit processes too
"""
import idaapi
import idc
import idautils
# -----------------------------------------------------------------------
# class to take a copy of a segment_t
class Seg():
def __init__(self, s):
self.startEA = s.startEA
self.endEA = s.endEA
self.perm = s.perm
self.bitness = s.bitness
def __cmp__(self, other):
return cmp(self.startEA, other.startEA)
# -----------------------------------------------------------------------
# each item described as:
# [ delta, [ opcode(s) ] ]
#FF10 call d,[eax]
#FF5000 call d,[eax][0]
#FF9044332211 call d,[eax][011223344]
#FF1500000100 call d,[000010000]
#FF9300000000 call d,[ebx][0]
#FF10 call d,[eax]
CallPattern = \
[
[-2, [0xFF] ],
[-3, [0xFF] ],
[-5, [0xE8] ],
[-6, [0xFF] ],
]
# -----------------------------------------------------------------------
def IsPrevInsnCall(ea):
"""
Given a return address, this function tries to check if previous instruction
is a CALL instruction
"""
global CallPattern
if ea == idaapi.BADADDR or ea < 10:
return None
for delta, opcodes in CallPattern:
# assume caller's ea
caller = ea + delta
# get the bytes
bytes = [x for x in GetDataList(caller, len(opcodes), 1)]
# do we have a match? is it a call instruction?
if bytes == opcodes and idaapi.is_call_insn(caller):
return caller
return None
# -----------------------------------------------------------------------
def CallStackWalk(nn):
class Result:
"""
Class holding the result of one call stack item
Each call stack item instance has the following attributes:
caller = ea of caller
displ = display string
sp = stack pointer
"""
def __init__(self, caller, sp):
self.caller = caller
self.sp = sp
f = idaapi.get_func(caller)
self.displ = "%08x: " % caller
if f:
self.displ += idc.GetFunctionName(caller)
t = caller - f.startEA
if t > 0: self.displ += "+" + hex(t)
else:
self.displ += hex(caller)
self.displ += " [" + hex(sp) + "]"
def __str__(self):
return self.displ
# get stack pointer
sp = cpu.Esp
seg = idaapi.getseg(sp)
if not seg:
return (False, "Could not locate stack segment!")
stack_seg = Seg(seg)
word_size = 2 ** (seg.bitness + 1)
callers = []
sp = cpu.Esp - word_size
while sp < stack_seg.endEA:
sp += word_size
ptr = idautils.GetDataList(sp, 1, word_size).next()
seg = idaapi.getseg(ptr)
# only accept executable segments
if (not seg) or ((seg.perm & idaapi.SEGPERM_EXEC) == 0):
continue
# try to find caller
caller = IsPrevInsnCall(ptr)
# we have no recognized caller, skip!
if caller is None:
continue
# do we have a debug name that is near?
if nn:
ret = nn.find(caller)
if ret:
ea = ret[0]
# function exists?
f = idaapi.get_func(ea)
if not f:
# create function
idc.MakeFunction(ea, idaapi.BADADDR)
# get the flags
f = idc.GetFlags(caller)
# no code there?
if not isCode(f):
MakeCode(caller)
callers.append(Result(caller, sp))
#
return (True, callers)
# -----------------------------------------------------------------------
# Chooser class
class CallStackWalkChoose(Choose):
def __init__(self, list, title):
Choose.__init__(self, list, title)
self.width = 250
def enter(self, n):
o = self.list[n-1]
idc.Jump(o.caller)
# -----------------------------------------------------------------------
def main():
if not idaapi.is_debugger_on():
idc.Warning("Please run the process first!")
return
if idaapi.get_process_state() != -1:
idc.Warning("Please suspend the debugger first!")
return
# only avail from IdaPython r232
if hasattr(idaapi, "NearestName"):
# get all debug names
dn = idaapi.get_debug_names(idaapi.cvar.inf.minEA, idaapi.cvar.inf.maxEA)
# initiate a nearest name search (using debug names)
nn = idaapi.NearestName(dn)
else:
nn = None
ret, callstack = CallStackWalk(nn)
if ret:
title = "Call stack walker (thread %X)" % (GetCurrentThreadId())
idaapi.close_chooser(title)
c = CallStackWalkChoose(callstack, title)
c.choose()
else:
idc.Warning("Failed to walk the stack:" + callstack)
# -----------------------------------------------------------------------
main()

101
Scripts/DbgCmd.py Normal file
View File

@ -0,0 +1,101 @@
# -----------------------------------------------------------------------
# Debugger command prompt with CustomViewers
# (c) Hex-Rays
#
import idaapi
import idc
from idaapi import simplecustviewer_t
def SendDbgCommand(cmd):
"""Sends a command to the debugger and returns the output string.
An exception will be raised if the debugger is not running or the current debugger does not export
the 'SendDbgCommand' IDC command.
"""
s = Eval('SendDbgCommand("%s");' % cmd)
if s.startswith("IDC_FAILURE"):
raise Exception, "Debugger command is available only when the debugger is active!"
return s
# -----------------------------------------------------------------------
class dbgcmd_t(simplecustviewer_t):
def Create(self):
# Form the title
title = "Debugger command window"
# Create the customview
if not simplecustviewer_t.Create(self, title):
return False
self.last_cmd = ""
self.menu_clear = self.AddPopupMenu("Clear")
self.menu_cmd = self.AddPopupMenu("New command")
self.ResetOutput()
return True
def IssueCommand(self):
s = idaapi.askstr(0, self.last_cmd, "Please enter a debugger command")
if not s:
return
# Save last command
self.last_cmd = s
# Add it using a different color
self.AddLine("debugger>" + idaapi.COLSTR(s, idaapi.SCOLOR_VOIDOP))
try:
r = SendDbgCommand(s).split("\n")
for s in r:
self.AddLine(idaapi.COLSTR(s, idaapi.SCOLOR_LIBNAME))
except:
self.AddLine(idaapi.COLSTR("Debugger is not active or does not export SendDbgCommand()", idaapi.SCOLOR_ERROR))
self.Refresh()
def ResetOutput(self):
self.ClearLines()
self.AddLine(idaapi.COLSTR("Please press INS to enter command; X to clear output", idaapi.SCOLOR_AUTOCMT))
self.Refresh()
def OnKeydown(self, vkey, shift):
# ESCAPE?
if vkey == 27:
self.Close()
# VK_INSERT
elif vkey == 45:
self.IssueCommand()
elif vkey == ord('X'):
self.ResetOutput()
else:
return False
return True
def OnPopupMenu(self, menu_id):
if menu_id == self.menu_clear:
self.ResetOutput()
elif menu_id == self.menu_cmd:
self.IssueCommand()
else:
# Unhandled
return False
return True
# -----------------------------------------------------------------------
def show_win():
x = dbgcmd_t()
if not x.Create():
print "Failed to create debugger command line!"
return None
x.Show()
return x
try:
# created already?
dbgcmd
dbgcmd.Close()
del dbgcmd
except:
pass
dbgcmd = show_win()
if not dbgcmd:
del dbgcmd

105
Scripts/DrvsDispatch.py Normal file
View File

@ -0,0 +1,105 @@
"""
A script to demonstrate how to send commands to the debugger and then parse and use the output in IDA
Copyright (c) 1990-2009 Hex-Rays
ALL RIGHTS RESERVED.
"""
import re
from idaapi import Choose
# -----------------------------------------------------------------------
def CmdDriverList():
s = Eval('WinDbgCommand("lm o");')
if "IDC_FAILURE" in s: return False
return s
# -----------------------------------------------------------------------
def CmdDrvObj(drvname, flag=2):
return Eval('WinDbgCommand("!drvobj %s %d");' % (drvname, flag))
# -----------------------------------------------------------------------
def CmdReloadForce():
s = Eval('WinDbgCommand(".reload /f");')
if "IDC_FAILURE" in s: return False
return True
# -----------------------------------------------------------------------
# class to hold dispatch entry information
class DispatchEntry:
def __init__(self, addr, name):
self.addr = addr
self.name = name
def __repr__(self):
return "%08X: %s" % (self.addr, self.name)
# -----------------------------------------------------------------------
def GetDriverDispatch():
# return a list of arrays of the form: [addr, name]
ret_list = []
# build the RE for parsing output from the "lm o" command
re_drv = re.compile('^[a-f0-9]+\s+[a-f0-9]+\s+(\S+)', re.I)
# build the RE for parsing output from the "!drvobj DRV_NAME 2" command
re_tbl = re.compile('^\[\d{2}\]\s+IRP_MJ_(\S+)\s+([0-9a-f]+)', re.I)
# force reloading of module symbols
if not CmdReloadForce():
print "Could not communicate with WinDbg, make sure the debugger is running!"
return None
# get driver list
lm_out = CmdDriverList()
if not lm_out:
return "Failed to get driver list!"
# for each line
for line in lm_out.split("\n"):
# parse
r = re_drv.match(line)
if not r: continue
# extract driver name
drvname = r.group(1).strip()
# execute "drvobj" command
tbl_out = CmdDrvObj(drvname)
if not tbl_out:
print "Failed to get driver object for", drvname
continue
# for each line
for line in tbl_out.split("\n"):
# parse
r = re_tbl.match(line)
if not r: continue
disp_addr = int(r.group(2), 16) # convert hex string to number
disp_name = "Dispatch" + r.group(1)
ret_list.append(DispatchEntry(disp_addr, drvname + "_" + disp_name))
return ret_list
# -----------------------------------------------------------------------
# Chooser class
class DispatchChoose(Choose):
def __init__(self, list, title):
Choose.__init__(self, list, title)
self.width = 250
def enter(self, n):
o = self.list[n-1]
idc.Jump(o.addr)
# -----------------------------------------------------------------------
# main
r = GetDriverDispatch()
if r:
c = DispatchChoose(r, "Dispatch table browser")
c.choose()
else:
print "Failed to retrieve dispatchers list!"

52
Scripts/ExchainDump.py Normal file
View File

@ -0,0 +1,52 @@
"""
This script shows how to send debugger commands and use the result in IDA
Copyright (c) 1990-2009 Hex-Rays
ALL RIGHTS RESERVED.
"""
import idc
import re
# class to store parsed results
class exchain:
def __init__(self, m):
self.name = m.group(1)
self.addr = int(m.group(2), 16)
def __str__(self):
return "%x: %s" % (self.addr, self.name)
# Chooser class
class MyChoose(Choose):
def __init__(self, list, title):
Choose.__init__(self, list, title)
self.width = 250
def enter(self, n):
o = self.list[n-1]
idc.Jump(o.addr)
# main
def main():
s = idc.Eval('SendDbgCommand("!exchain")')
if "IDC_FAILURE" in s:
return (False, "Cannot execute the command")
matches = re.finditer(r'[^:]+: ([^\(]+) \(([^\)]+)\)\n', s)
L = []
for x in matches:
L.append(exchain(x))
if not L:
return (False, "Nothing to display: Could parse the result!")
# Get a Choose instance
chooser = MyChoose(L, "Exchain choose")
# Run the chooser
chooser.choose()
return (True, "Success!")
ok, r = main()
if not ok:
print r

139
Scripts/FindInstructions.py Normal file
View File

@ -0,0 +1,139 @@
"""
FindInstructions.py: A script to help you find desired opcodes/instructions in a database
The script accepts opcodes and assembly statements (which will be assembled) separated by semicolon
The general syntax is:
find(asm or opcodes, x=Bool, asm_where=ea)
* Example:
find("asm_statement1;asm_statement2;de ea dc 0d e0;asm_statement3;xx yy zz;...")
* To filter-out non-executable segments pass x=True
find("jmp dword ptr [esp]", x=True)
* To specify in which context the instructions should be assembled, pass asm_where=ea:
find("jmp dword ptr [esp]", asm_where=here())
Copyright (c) 1990-2009 Hex-Rays
ALL RIGHTS RESERVED.
v1.0 - initial version
"""
import idaapi
import idautils
import idc
# -----------------------------------------------------------------------
def FindInstructions(instr, asm_where=None):
"""
Finds instructions/opcodes
@return: Returns a tuple(True, [ ea, ... ]) or a tuple(False, "error message")
"""
if not asm_where:
# get first segment
asm_where = FirstSeg()
if asm_where == idaapi.BADADDR:
return (False, "No segments defined")
# regular expression to distinguish between opcodes and instructions
re_opcode = re.compile('^[0-9a-f]{2} *', re.I)
# split lines
lines = instr.split(";")
# all the assembled buffers (for each instruction)
bufs = []
for line in lines:
if re_opcode.match(line):
# convert from hex string to a character list then join the list to form one string
buf = ''.join([chr(int(x, 16)) for x in line.split()])
else:
# assemble the instruction
ret, buf = Assemble(asm_where, line)
if not ret:
return (False, "Failed to assemble:"+line)
# add the assembled buffer
bufs.append(buf)
# join the buffer into one string
buf = ''.join(bufs)
# take total assembled instructions length
tlen = len(buf)
# convert from binary string to space separated hex string
bin_str = ' '.join(["%02X" % ord(x) for x in buf])
# find all binary strings
print "Searching for: [%s]" % bin_str
ea = MinEA()
ret = []
while True:
ea = FindBinary(ea, SEARCH_DOWN, bin_str)
if ea == idaapi.BADADDR:
break
ret.append(ea)
Message(".")
ea += tlen
if not ret:
return (False, "Could not match [%s]" % bin_str)
Message("\n")
return (True, ret)
# -----------------------------------------------------------------------
# Chooser class
class SearchResultChoose(Choose):
def __init__(self, list, title):
Choose.__init__(self, list, title)
self.width = 250
def enter(self, n):
o = self.list[n-1]
Jump(o.ea)
# -----------------------------------------------------------------------
# class to represent the results
class SearchResult:
def __init__(self, ea):
self.ea = ea
if not isCode(GetFlags(ea)):
MakeCode(ea)
t = idaapi.generate_disasm_line(ea)
if t:
line = idaapi.tag_remove(t)
else:
line = ""
func = GetFunctionName(ea)
self.display = hex(ea) + ": "
if func:
self.display += func + ": "
else:
n = SegName(ea)
if n: self.display += n + ": "
self.display += line
def __str__(self):
return self.display
# -----------------------------------------------------------------------
def find(s=None, x=False, asm_where=None):
b, ret = FindInstructions(s, asm_where)
if b:
# executable segs only?
if x:
results = []
for ea in ret:
seg = idaapi.getseg(ea)
if (not seg) or (seg.perm & idaapi.SEGPERM_EXEC) == 0:
continue
results.append(SearchResult(ea))
else:
results = [SearchResult(ea) for ea in ret]
title = "Search result for: [%s]" % s
idaapi.close_chooser(title)
c = SearchResultChoose(results, title)
c.choose()
else:
print ret
# -----------------------------------------------------------------------
print "Please use find('asm_stmt1;xx yy;...', x=Bool,asm_where=ea) to search for instructions or opcodes. Specify x=true to filter out non-executable segments"

69
Scripts/ImpRef.py Normal file
View File

@ -0,0 +1,69 @@
# -----------------------------------------------------------------------
# This is an example illustrating how to enumerate all addresses
# that refer to all imported functions in a given module
#
# (c) Hex-Rays
#
import idaapi
import idc
import idautils
import re
# -----------------------------------------------------------------------
def find_imported_funcs(dllname):
def imp_cb(ea, name, ord):
if not name:
name = ''
imports.append([ea, name, ord])
return True
imports = []
nimps = idaapi.get_import_module_qty()
for i in xrange(0, nimps):
name = idaapi.get_import_module_name(i)
if re.match(dllname, name, re.IGNORECASE) is None:
continue
idaapi.enum_import_names(i, imp_cb)
return imports
# -----------------------------------------------------------------------
def find_import_ref(dllname):
imports = find_imported_funcs(dllname)
R = dict()
for i, (ea, name,_) in enumerate(imports):
#print "%x -> %s" % (ea, name)
for xref in idautils.XrefsTo(ea):
# check if referrer is a thunk
ea = xref.frm
f = idaapi.get_func(ea)
if f and (f.flags & idaapi.FUNC_THUNK) != 0:
imports.append([f.startEA, idaapi.get_func_name(f.startEA), 0])
#print "\t%x %s: from a thunk, parent added %x" % (ea, name, f.startEA)
continue
# save results
if not R.has_key(i):
R[i] = []
R[i].append(ea)
return (imports, R)
# -----------------------------------------------------------------------
def main():
dllname = idc.AskStr('kernel32', "Enter module name")
if not dllname:
print("Cancelled")
return
imports, R = find_import_ref(dllname)
for k, v in R.items():
print(imports[k][1])
for ea in v:
print("\t%x" % ea)
# -----------------------------------------------------------------------
main()

View File

@ -0,0 +1,124 @@
# -----------------------------------------------------------------------
# This is an example illustrating how to:
# - enumerate imports
# - enumerate entrypoints
# - Use PluginForm class
# - Use PySide with PluginForm to create a Python UI
#
# (c) Hex-Rays
#
import idaapi
import idautils
from idaapi import PluginForm
from PySide import QtGui, QtCore
# --------------------------------------------------------------------------
class ImpExpForm_t(PluginForm):
def imports_names_cb(self, ea, name, ord):
self.items.append((ea, '' if not name else name, ord))
# True -> Continue enumeration
return True
def BuildImports(self):
tree = {}
nimps = idaapi.get_import_module_qty()
for i in xrange(0, nimps):
name = idaapi.get_import_module_name(i)
if not name:
continue
# Create a list for imported names
self.items = []
# Enum imported entries in this module
idaapi.enum_import_names(i, self.imports_names_cb)
if name not in tree:
tree[name] = []
tree[name].extend(self.items)
return tree
def BuildExports(self):
return list(idautils.Entries())
def PopulateTree(self):
# Clear previous items
self.tree.clear()
# Build imports
root = QtGui.QTreeWidgetItem(self.tree)
root.setText(0, "Imports")
for dll_name, imp_entries in self.BuildImports().items():
imp_dll = QtGui.QTreeWidgetItem(root)
imp_dll.setText(0, dll_name)
for imp_ea, imp_name, imp_ord in imp_entries:
item = QtGui.QTreeWidgetItem(imp_dll)
item.setText(0, "%s [0x%08x]" %(imp_name, imp_ea))
# Build exports
root = QtGui.QTreeWidgetItem(self.tree)
root.setText(0, "Exports")
for exp_i, exp_ord, exp_ea, exp_name in self.BuildExports():
item = QtGui.QTreeWidgetItem(root)
item.setText(0, "%s [#%d] [0x%08x]" % (exp_name, exp_ord, exp_ea))
def OnCreate(self, form):
"""
Called when the plugin form is created
"""
# Get parent widget
self.parent = self.FormToPySideWidget(form)
# Create tree control
self.tree = QtGui.QTreeWidget()
self.tree.setHeaderLabels(("Names",))
self.tree.setColumnWidth(0, 100)
# Create layout
layout = QtGui.QVBoxLayout()
layout.addWidget(self.tree)
self.PopulateTree()
# Populate PluginForm
self.parent.setLayout(layout)
def OnClose(self, form):
"""
Called when the plugin form is closed
"""
global ImpExpForm
del ImpExpForm
print "Closed"
def Show(self):
"""Creates the form is not created or focuses it if it was"""
return PluginForm.Show(self,
"Imports / Exports viewer",
options = PluginForm.FORM_PERSIST)
# --------------------------------------------------------------------------
def main():
global ImpExpForm
try:
ImpExpForm
except:
ImpExpForm = ImpExpForm_t()
ImpExpForm.Show()
# --------------------------------------------------------------------------
main()

85
Scripts/PteDump.py Normal file
View File

@ -0,0 +1,85 @@
import idaapi
import idc
from idaapi import Choose2
def parse_pte(str):
try:
parse_pte.re
except:
parse_pte.re = re.compile('PDE at ([0-9a-f]+)\s*PTE at ([0-9a-f]+)\ncontains ([0-9a-f]+)\s*contains ([0-9a-f]+)\npfn ([0-9]+)\s*([^ ]+)\s*pfn ([0-9a-f]+)\s*([^\r\n]+)', re.I | re.M)
parse_pte.items = ('pde', 'pte', 'pdec', 'ptec', 'pdepfn', 'pdepfns', 'ptepfn', 'ptepfns')
m = parse_pte.re.search(s)
r = {}
for i in range(0, len(parse_pte.items)):
r[parse_pte.items[i]] = m.group(i+1)
return r
class MyChoose2(Choose2):
def __init__(self, title, ea1, ea2):
Choose2.__init__(self, title, [ ["VA", 10], ["PTE attr", 30] ])
self.ea1 = ea1
self.ea2 = ea2
self.n = 0
self.icon = 5
self.items = []
self.Refresh()
self.selcount = 0
def OnGetLine(self, n):
print("getline %d" % n)
return self.items[n]
def OnGetSize(self):
n = len(self.items)
self.Refresh()
return n
def OnRefresh(self, n):
print("refresh %d" % n)
return n
def Refresh(self):
items = []
PG = 0x1000
ea1 = self.ea1
npages = (self.ea2 - ea1) / PG
for i in range(npages):
r = idc.SendDbgCommand("!pte %x" % ea1)
if not r:
return False
r = parse_pte(r)
items.append([hex(ea1), r['ptepfns']])
ea1 += PG
self.items = items
print(self.items)
return True
@staticmethod
def Execute(ea1, ea2):
c = MyChoose2("PTE Viewer [%x..%x]" % (ea1, ea2), ea1, ea2)
return (c, c.Show())
def DumpPTE(ea1, ea2):
items = []
PG = 0x1000
npages = (ea2 - ea1) / PG
for i in range(npages):
r = idc.SendDbgCommand("!pte %x" % ea1)
if not r:
return False
print r
r = parse_pte(r)
print("VA: %08X PTE: %s PDE: %s" % (ea1, r['ptepfns'], r['pdepfns']))
ea1 += PG
def DumpSegPTE(ea):
DumpPTE(idc.SegStart(ea), idc.SegEnd(ea))
DumpSegPTE(here())
#MyChoose2.Execute(0xF718F000, 0xF718F000+0x1000)

149
Scripts/SEHGraph.py Normal file
View File

@ -0,0 +1,149 @@
"""
A script that graphs all the exception handlers in a given process
It will be easy to see what thread uses what handler and what handlers are commonly used between threads
Copyright (c) 1990-2009 Hex-Rays
ALL RIGHTS RESERVED.
v1.0 - initial version
"""
import idaapi
import idautils
import idc
from idaapi import GraphViewer
# -----------------------------------------------------------------------
# Since Windbg debug module does not support get_thread_sreg_base()
# we will call the debugger engine "dg" command and parse its output
def WindbgGetRegBase(tid):
s = idc.Eval('WinDbgCommand("dg %x")' % cpu.fs)
if "IDC_FAILURE" in s:
return 0
m = re.compile("[0-9a-f]{4} ([0-9a-f]{8})")
t = m.match(s.split('\n')[-2])
if not t:
return 0
return int(t.group(1), 16)
# -----------------------------------------------------------------------
def GetFsBase(tid):
idc.SelectThread(tid)
base = idaapi.dbg_get_thread_sreg_base(tid, cpu.fs)
if base != 0:
return base
return WindbgGetRegBase(tid)
# -----------------------------------------------------------------------
# Walks the SEH chain and returns a list of handlers
def GetExceptionChain(tid):
fs_base = GetFsBase(tid)
exc_rr = Dword(fs_base)
result = []
while exc_rr != 0xffffffff:
prev = Dword(exc_rr)
handler = Dword(exc_rr + 4)
exc_rr = prev
result.append(handler)
return result
# -----------------------------------------------------------------------
class SEHGraph(GraphViewer):
def __init__(self, title, result):
GraphViewer.__init__(self, title)
self.result = result
self.names = {} # ea -> name
def OnRefresh(self):
self.Clear()
addr_id = {}
for (tid, chain) in self.result.items():
# Each node data will contain a tuple of the form: (Boolean->Is_thread, Int->Value, String->Label)
# For threads the is_thread will be true and the value will hold the thread id
# For exception handlers, is_thread=False and Value=Handler address
# Add the thread node
id_parent = self.AddNode( (True, tid, "Thread %X" % tid) )
# Add each handler
for handler in chain:
# Check if a function is created at the handler's address
f = idaapi.get_func(handler)
if not f:
# create function
idc.MakeFunction(handler, idaapi.BADADDR)
# Node label is function name or address
s = GetFunctionName(handler)
if not s:
s = "%x" % handler
# cache name
self.names[handler] = s
# Get the node id given the handler address
# We use an addr -> id dictionary so that similar addresses get similar node id
if not addr_id.has_key(handler):
id = self.AddNode( (False, handler, s) )
addr_id[handler] = id # add this ID
else:
id = addr_id[handler]
# Link handlers to each other
self.AddEdge(id_parent, id)
id_parent = id
return True
def OnGetText(self, node_id):
is_thread, value, label = self[node_id]
if is_thread:
return (label, 0xff00f0)
return label
def OnDblClick(self, node_id):
is_thread, value, label = self[node_id]
if is_thread:
idc.SelectThread(value)
self.Show()
s = "SEH chain for " + hex(value)
t = "-" * len(s)
print t
print s
print t
for handler in self.result[value]:
print "%x: %s" % (handler, self.names[handler])
print t
else:
idc.Jump(value)
return True
# -----------------------------------------------------------------------
def main():
if not idaapi.dbg_can_query():
print "The debugger must be active and suspended before using this script!"
return
# Save current thread id
tid = GetCurrentThreadId()
# Iterate through all function instructions and take only call instructions
result = {}
for tid in idautils.Threads():
result[tid] = GetExceptionChain(tid)
# Restore previously selected thread
idc.SelectThread(tid)
# Build the graph
g = SEHGraph("SEH graph", result)
g.Show()
main()

70
Scripts/VaDump.py Normal file
View File

@ -0,0 +1,70 @@
"""
This script shows how to send debugger commands and use the result in IDA
Copyright (c) 1990-2009 Hex-Rays
ALL RIGHTS RESERVED.
"""
import idc
from idaapi import Choose
import re
# class to store parsed results
class memva:
def __init__(self, m):
self.base = int(m.group(1), 16)
self.regionsize = int(m.group(2), 16)
self.state = int(m.group(3), 16)
self.statestr = m.group(4).strip()
self.protect = int(m.group(5), 16)
self.protectstr = m.group(6).strip()
if m.group(7):
self.type = int(m.group(8), 16)
self.typestr = m.group(9).strip()
else:
self.type = 0
self.typestr = ""
def __str__(self):
return "(Base %08X; RegionSize: %08X; State: %08X/%10s; protect: %08X/%10s; type: %08X/%10s)" % (
self.base, self.regionsize, self.state,
self.statestr, self.protect,
self.protectstr, self.type, self.typestr)
# Chooser class
class MemChoose(Choose):
def __init__(self, list, title):
Choose.__init__(self, list, title)
self.width = 250
def enter(self, n):
o = self.list[n-1]
idc.Jump(o.base)
# main
def main():
s = idc.Eval('SendDbgCommand("!vadump")')
if "IDC_FAILURE" in s:
return (False, "Cannot execute the command")
matches = re.finditer(r'BaseAddress:\s*?(\w+?)\n' \
+'RegionSize:\s*?(\w*?)\n' \
+'State:\s*?(\w*?)\s*?(\w*?)\n' \
+'Protect:\s*?(\w*?)\s*?(\w*?)\n' \
+'(Type:\s*?(\w*?)\s*?(\w*?)\n)*', s)
L = []
for x in matches:
L.append(memva(x))
if not L:
return (False, "Nothing to display: Could not parse the result!")
# Get a Choose instance
chooser = MemChoose(L, "Memory choose")
# Run the chooser
chooser.choose()
return (True, "Success!")
r = main()
if not r[0]:
print r[1]

367
Scripts/VirusTotal.py Normal file
View File

@ -0,0 +1,367 @@
# -----------------------------------------------------------------------
# VirusTotal IDA Plugin
# By Elias Bachaalany <elias at hex-rays.com>
# (c) Hex-Rays 2011
#
# Special thanks:
# - VirusTotal team
# - Bryce Boe for his VirusTotal Python code
#
import idaapi
import idc
from idaapi import Choose2, plugin_t
import BboeVt as vt
import webbrowser
import urllib
import os
PLUGIN_TEST = 0
# -----------------------------------------------------------------------
# Configuration file
VT_CFGFILE = os.path.join(idaapi.get_user_idadir(), "virustotal.cfg")
# -----------------------------------------------------------------------
# VirusTotal Icon in PNG format
VT_ICON = (
"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52"
"\x00\x00\x00\x10\x00\x00\x00\x10\x04\x03\x00\x00\x00\xED\xDD\xE2"
"\x52\x00\x00\x00\x30\x50\x4C\x54\x45\x03\x8B\xD3\x5C\xB4\xE3\x9C"
"\xD1\xED\xF7\xFB\xFD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD3\xF2\x42\x61\x00\x00\x00"
"\x4B\x49\x44\x41\x54\x78\x9C\x2D\xCA\xC1\x0D\x80\x30\x0C\x43\x51"
"\x27\x2C\x50\x89\x05\x40\x2C\x40\xEB\xFD\x77\xC3\x76\xC9\xE9\xEB"
"\xC5\x20\x5F\xE8\x1A\x0F\x97\xA3\xD0\xE4\x1D\xF9\x49\xD1\x59\x29"
"\x4C\x43\x9B\xD0\x15\x01\xB5\x4A\x9C\xE4\x70\x14\x39\xB3\x31\xF8"
"\x15\x70\x04\xF4\xDA\x20\x39\x02\x8A\x0D\xA8\x0F\x94\xA7\x09\x0E"
"\xC5\x16\x2D\x54\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82")
# -----------------------------------------------------------------------
class VirusTotalConfig(object):
def __init__(self):
self.Default()
def Default(self):
self.md5sum = GetInputMD5()
self.infile = idaapi.dbg_get_input_path()
if not self.infile:
self.infile = ""
# Persistent options
self.apikey = ""
self.options = 1 | 2
def Read(self):
"""
Read configuration from file
"""
if not os.path.exists(VT_CFGFILE):
return
f = open(VT_CFGFILE, 'r')
lines = f.readlines()
for i, line in enumerate(lines):
line = line.strip()
if i == 0:
self.apikey = line
elif i == 1:
self.options = int(line)
else:
break
def Write(self):
"""
Write configuration to file
"""
lines = (self.apikey.strip(), str(self.options))
try:
f = open(VT_CFGFILE, 'w')
f.write("\n".join(lines))
f.close()
except:
pass
# -----------------------------------------------------------------------
def VtReport(apikey, filename=None, md5sum=None):
if filename is None and md5sum is None:
return (False, "No parameters passed!")
# Check filename existance
if filename is not None and not os.path.exists(filename):
return (False, "Input file '%s' does not exist!" % filename)
#print("fn=%s md5=%s" % (filename, md5sum))
# Get file report from VirusTotal
try:
vt.set_apikey(apikey)
result = vt.get_file_report(filename=filename, md5sum=md5sum)
except Exception as e:
return (False, "Exception:\n%s" % str(e))
# Already analyzed?
if result is not None:
# Transform the results
items = []
for av, mwname in result.items():
mwname = str(mwname) if mwname else "n/a"
av = str(av)
items.append([av, mwname])
result = items
return (True, result)
# -----------------------------------------------------------------------
class VirusTotalChooser(Choose2):
"""
Chooser class to display results from VT
"""
def __init__(self, title, items, icon, embedded=False):
Choose2.__init__(self,
title,
[ ["Antivirus", 20], ["Result", 40] ],
embedded=embedded)
self.items = items
self.icon = icon
def GetItems(self):
return self.items
def SetItems(self, items):
self.items = [] if items is None else items
def OnClose(self):
pass
def OnGetLine(self, n):
return self.items[n]
def OnGetSize(self):
return len(self.items)
def OnSelectLine(self, n):
# Google search for the malware name and the antivirus name
s = urllib.urlencode({"q" : " ".join(self.items[n])})
webbrowser.open_new_tab("http://www.google.com/search?%s" % s)
# --------------------------------------------------------------------------
class VirusTotalForm(Form):
def __init__(self, icon):
self.EChooser = VirusTotalChooser("E1", [], icon, embedded=True)
Form.__init__(self, r"""STARTITEM {id:txtInput}
VirusTotal - IDAPython plugin v1.0 (c) Hex-Rays
{FormChangeCb}
<#API key#~A~pi key:{txtApiKey}>
Options:
<#Open results in a chooser when form closes#~P~opout results on close:{rOptRemember}>
<#Use MD5 checksum#~M~D5Sum:{rOptMD5}>
<#Use file on disk#~F~ile:{rOptFile}>{grpOptions}>
<#Type input (file or MD5 string)#~I~nput:{txtInput}>
<Results:{cEChooser}>
<#Get reports from VT#~R~eport:{btnReport}>
""", {
'FormChangeCb': Form.FormChangeCb(self.OnFormChange),
'txtApiKey' : Form.StringInput(swidth=80),
'grpOptions' : Form.ChkGroupControl(("rOptRemember", "rOptMD5", "rOptFile")),
'txtInput' : Form.FileInput(open=True),
'btnReport' : Form.ButtonInput(self.OnReportClick),
'cEChooser' : Form.EmbeddedChooserControl(self.EChooser)
})
def OnReportClick(self, code=0):
pass
def OnFormChange(self, fid):
if fid == self.rOptMD5.id or fid == self.rOptFile.id:
input = (self.cfg.md5sum, self.cfg.infile)
if fid == self.rOptMD5.id:
c1 = self.rOptMD5
c2 = self.rOptFile
idx = 0
else:
c1 = self.rOptFile
c2 = self.rOptMD5
idx = 1
v = not self.GetControlValue(c1)
if v: idx = not idx
# Uncheck the opposite input type
self.SetControlValue(c2, v)
# Set input field depending on input type
self.SetControlValue(self.txtInput, input[idx])
#
# Report button
#
elif fid == self.btnReport.id:
input = self.GetControlValue(self.txtInput)
as_file = self.GetControlValue(self.rOptFile)
apikey = self.GetControlValue(self.txtApiKey)
ok, r = VtReport(self.cfg.apikey,
filename=input if as_file else None,
md5sum=None if as_file else input)
# Error?
if not ok:
idc.Warning(r)
return 1
# Pass the result
self.EChooser.SetItems(r)
# We have results and it was a file? Print its MD5
if r and as_file:
print("%s: %s" % (vt.LAST_FILE_HASH, input))
# Refresh the embedded chooser control
# (Could also clear previous results if not were retrieved during this run)
self.RefreshField(self.cEChooser)
# Store the input for the caller
self.cfg.input = input
# No results and file as input was supplied?
if r is None:
if as_file:
# Propose to upload
if idc.AskYN(0, "HIDECANCEL\nNo previous results. Do you want to submit the file:\n\n'%s'\n\nto VirusTotal?" % input) == 0:
return 1
try:
r = vt.scan_file(input)
except Exception as e:
idc.Warning("Exceptio during upload: %s" % str(e))
else:
if r is None:
idc.Warning("Failed to upload the file!")
else:
idc.Warning("File uploaded. Check again later to get the analysis report. Scan id: %s" % r)
else:
idc.Warning("No results found for hash: %s" % input)
return 1
def Show(self, cfg):
# Compile the form once
if not self.Compiled():
_, args = self.Compile()
#print args[0]
# Populate the form
self.txtApiKey.value = cfg.apikey
self.grpOptions.value = cfg.options
self.txtInput.value = cfg.infile if self.rOptFile.checked else cfg.md5sum
# Remember the config
self.cfg = cfg
# Execute the form
ok = self.Execute()
# Forget the cfg
del self.cfg
# Success?
if ok != 0:
# Update config
cfg.options = self.grpOptions.value
cfg.apikey = self.txtApiKey.value
# Popup results?
if self.rOptRemember.checked:
ok = 2
return ok
# -----------------------------------------------------------------------
class VirusTotalPlugin_t(plugin_t):
flags = idaapi.PLUGIN_UNL
comment = "VirusTotal plugin for IDA"
help = ""
wanted_name = "VirusTotal report"
wanted_hotkey = "Alt-F8"
def init(self):
# Some initialization
self.icon_id = 0
return idaapi.PLUGIN_OK
def run(self, arg=0):
# Load icon from the memory and save its id
self.icon_id = idaapi.load_custom_icon(data=VT_ICON, format="png")
if self.icon_id == 0:
raise RuntimeError("Failed to load icon data!")
# Create config object
cfg = VirusTotalConfig()
# Read previous config
cfg.Read()
# Create form
f = VirusTotalForm(self.icon_id)
# Show the form
ok = f.Show(cfg)
if ok == 0:
f.Free()
return
# Save configuration
cfg.Write()
# Spawn a non-modal chooser w/ the results if any
if ok == 2 and f.EChooser.GetItems():
VirusTotalChooser(
"VirusTotal results [%s]" % cfg.input,
f.EChooser.GetItems(),
self.icon_id).Show()
f.Free()
return
def term(self):
# Free the custom icon
if self.icon_id != 0:
idaapi.free_custom_icon(self.icon_id)
# -----------------------------------------------------------------------
def PLUGIN_ENTRY():
return VirusTotalPlugin_t()
# --------------------------------------------------------------------------
if PLUGIN_TEST:
# Create form
f = PLUGIN_ENTRY()
f.init()
f.run()
f.term()

91
Scripts/callstack_test.py Normal file
View File

@ -0,0 +1,91 @@
import sys
import os
def __sys(cmd, fmt=None, echo=True):
"""Executes a string of OS commands and returns the a list of tuples (return code,command executed)"""
if not fmt:
fmt = {}
r = []
for cmd in [x for x in (cmd % fmt).split("\n") if len(x)]:
if echo:
print ">>>", cmd
r.append((os.system(cmd), cmd))
return r
body = r"""/// Autogenerated file
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <windows.h>
void want_break(int n)
{
printf("do you want to DebugBreak in func%d()?", n);
char ch = _toupper(_getch());
printf("\n");
if (ch == 'Y')
DebugBreak();
else if (ch == 'X')
ExitProcess(n);
}
%FUNCS%
int main(int /*argc*/, char * /*argv[]*/)
{
func1();
return 0;
}
"""
funcs_body = []
func_body = r"""
void func%(n)d()
{
printf("%(ident)senter %(n)d\n");%(pause)s
func%(n1)d();
printf("%(ident)sleave %(n)d\n");
}
"""
if len(sys.argv) < 2:
print "usage: gen nb_calls pause_frequency"
sys.exit(0)
n = int(sys.argv[1])
if n < 1:
print "at least one call should be passed!"
sys.exit(1)
m = int(sys.argv[2])
func_params = {'n': 0, 'n1': 0, 'ident': '', 'pause' : ''}
for i in xrange(1, n + 1):
func_params['n'] = i
func_params['n1'] = i+1
func_params['ident'] = " " * i
func_params['pause'] = ("\n want_break(%d);" % i) if (i % m) == 0 else ''
funcs_body.append(func_body % func_params)
funcs_body.append(r"""
void func%(n)d()
{
printf("that's it #%(n)d!\n");
}
""" % {'n':i+1})
funcs_body.reverse()
# write the file
body = body.replace('%FUNCS%', ''.join(funcs_body))
f = file('src.cpp', 'w')
f.write(body)
f.close()
__sys("""
if exist src.exe del src.exe
bcc32 src
if exist src.exe move src.exe src_bcc.exe
if exist src.obj del src.obj
cl32 src.cpp /Zi /Od
""")

68
Scripts/msdnapihelp.py Normal file
View File

@ -0,0 +1,68 @@
"""
User contributed script: MSDN API HELP plugin
This script fetches the API reference (from MSDN) of a given highlighted identifier
and returns the results in a new web browser page.
This script depends on the feedparser package: http://code.google.com/p/feedparser/
10/05/2010
- initial version
"""
import idaapi
# -----------------------------------------------------------------------
class msdnapihelp_plugin_t(idaapi.plugin_t):
flags = idaapi.PLUGIN_UNL
comment = "Online MSDN API Help"
help = "Help me"
wanted_name = "MSDN API Help"
wanted_hotkey = "F3"
def init(self):
return idaapi.PLUGIN_OK
@staticmethod
def sanitize_name(name):
t = idaapi.FUNC_IMPORT_PREFIX
if name.startswith(t):
return name[len(t):]
return name
def run(self, arg):
# Get the highlighted identifier
id = idaapi.get_highlighted_identifier()
if not id:
print "No identifier was highlighted"
return
import webbrowser
try:
import feedparser
except:
idaapi.warning('Feedparser package not installed')
return
id = self.sanitize_name(id)
print "Looking up '%s' in MSDN online" % id
d = feedparser.parse("http://social.msdn.microsoft.com/Search/Feed.aspx?locale=en-us&format=RSS&Query=%s" % id)
if len(d['entries']) > 0:
url = d['entries'][0].link
webbrowser.open_new_tab(url)
else:
print "API documentation not found for: %s" % id
def term(self):
pass
# -----------------------------------------------------------------------
def PLUGIN_ENTRY():
return msdnapihelp_plugin_t()

View File

@ -1,4 +1,4 @@
#ifndef _BASETSD_H
#define _BASETSD_H
/* Microsoft free compilers seem to lack this file and Python needs it */
#endif
#ifndef _BASETSD_H
#define _BASETSD_H
/* Microsoft free compilers seem to lack this file and Python needs it */
#endif

475
build.py
View File

@ -1,30 +1,46 @@
#!/usr/bin/env python
#------------------------------------------------------------
# IDAPython - Python plugin for Interactive Disassembler Pro
#---------------------------------------------------------------------
# IDAPython - Python plugin for Interactive Disassembler
#
# Copyright (c) 2004-2007 Gergely Erdelyi <dyce@d-dome.net>
# (c) The IDAPython Team <idapython@googlegroups.com>
#
# All rights reserved.
#
# For detailed copyright information see the file COPYING in
# the root of the distribution archive.
#------------------------------------------------------------
#---------------------------------------------------------------------
# build.py - Custom build script
#------------------------------------------------------------
import os, sys, platform, types, shutil
#---------------------------------------------------------------------
import os
import platform
import shutil
import sys
import types
import zipfile
import glob
from distutils import sysconfig
# Start of user configurable options
VERBOSE = True
IDA_MAJOR_VERSION = 5
IDA_MINOR_VERSION = 1
IDA_SDK = ".." + os.sep + "swigsdk-versions" + os.sep + "%d.%d" % (IDA_MAJOR_VERSION, IDA_MINOR_VERSION)
IDA_MAJOR_VERSION = 6
IDA_MINOR_VERSION = 8
if 'IDA' in os.environ:
IDA_SDK = os.environ['IDA']
else:
IDA_SDK = os.path.join("..", "..", "include")
if not os.path.exists(IDA_SDK):
IDA_SDK = os.path.join("..", "swigsdk-versions", ("%d.%d" % (IDA_MAJOR_VERSION, IDA_MINOR_VERSION)))
assert os.path.exists(IDA_SDK), "Could not find IDA SDK include path"
# End of user configurable options
# IDAPython version
VERSION_MAJOR = 0
VERSION_MINOR = 9
VERSION_PATCH = 55
VERSION_MAJOR = 1
VERSION_MINOR = 7
VERSION_PATCH = 0
# Determine Python version
PYTHON_MAJOR_VERSION = int(platform.python_version()[0])
@ -33,8 +49,13 @@ PYTHON_MINOR_VERSION = int(platform.python_version()[2])
# Find Python headers
PYTHON_INCLUDE_DIRECTORY = sysconfig.get_config_var('INCLUDEPY')
S_EA64 = 'ea64'
S_WITH_HEXRAYS = 'with-hexrays'
S_NO_OPT = 'no-opt'
S_DEBUG = 'debug'
# Swig command-line parameters
SWIG_OPTIONS = '-modern -python -c++ -w451 -shadow -D__GNUC__'
SWIG_OPTIONS = '-modern -python -threads -c++ -w451 -shadow -D__GNUC__'
# Common macros for all compilations
COMMON_MACROS = [
@ -49,28 +70,60 @@ COMMON_MACROS = [
# Common includes for all compilations
COMMON_INCLUDES = [ ".", "swig" ]
# -----------------------------------------------------------------------
# List files for the binary distribution
BINDIST_MANIFEST = [
"README.txt",
"COPYING.txt",
"CHANGES.txt",
"AUTHORS.txt",
"STATUS.txt",
"python/init.py",
"python/idc.py",
"python/idautils.py",
("idaapi.py", "python"),
"python.cfg",
"docs/notes.txt",
"examples/chooser.py",
"examples/colours.py",
"examples/ex_idphook_asm.py",
"examples/ex_uirequests.py",
"examples/debughook.py",
"examples/ex_cli.py",
"examples/ex1.idc",
"examples/ex_custdata.py",
"examples/ex1_idaapi.py",
"examples/ex1_idautils.py" ]
"examples/ex1_idautils.py",
"examples/hotkey.py",
"examples/structure.py",
"examples/ex_gdl_qflow_chart.py",
"examples/ex_strings.py",
"examples/ex_actions.py",
"examples/ex_func_chooser.py",
"examples/ex_choose2.py",
"examples/ex_debug_names.py",
"examples/ex_graph.py",
"examples/ex_hotkey.py",
"examples/ex_patch.py",
"examples/ex_expr.py",
"examples/ex_timer.py",
"examples/ex_dbg.py",
"examples/ex_custview.py",
"examples/ex_prefix_plugin.py",
"examples/ex_pyside.py",
"examples/ex_pyqt.py",
"examples/ex_askusingform.py",
"examples/ex_uihook.py",
"examples/ex_idphook_asm.py",
"examples/ex_imports.py"
]
# -----------------------------------------------------------------------
# List files for the source distribution (appended to binary list)
SRCDIST_MANIFEST = [
"BUILDING.txt",
"python.cpp",
"basetsd.h",
"build.py",
"python.cfg",
"swig/allins.i",
"swig/area.i",
"swig/auto.i",
"swig/bytes.i",
"swig/dbg.i",
@ -81,8 +134,10 @@ SRCDIST_MANIFEST = [
"swig/fixup.i",
"swig/frame.i",
"swig/funcs.i",
"swig/gdl.i",
"swig/ida.i",
"swig/idaapi.i",
"swig/idd.i",
"swig/idp.i",
"swig/ints.i",
"swig/kernwin.i",
@ -91,6 +146,7 @@ SRCDIST_MANIFEST = [
"swig/moves.i",
"swig/nalt.i",
"swig/name.i",
"swig/netnode.i",
"swig/offset.i",
"swig/pro.i",
"swig/queue.i",
@ -103,27 +159,34 @@ SRCDIST_MANIFEST = [
"swig/typeinf.i",
"swig/ua.i",
"swig/xref.i",
"patches/ida51.patch"
"swig/graph.i",
"swig/fpro.i",
"swig/hexrays.i",
]
# Temporaty build files to remove
BUILD_TEMPFILES = [
"idaapi.cpp",
"idaapi.obj",
"idaapi.o",
"idaapi.py",
"idapython.sln",
"idapython.ncb",
"python.exp",
"python.lib",
"python.obj"
]
# -----------------------------------------------------------------------
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
debug = '--' + S_DEBUG in sys.argv
return {
S_EA64: ea64,
S_WITH_HEXRAYS: with_hexrays,
S_NO_OPT: no_opt,
S_DEBUG: debug
}
# -----------------------------------------------------------------------
class BuilderBase:
""" Base class for builders """
def __init__(self):
pass
def compile(self, source, objectname=None, includes=[], macros=[]):
"""
Compile the source file
@ -149,7 +212,8 @@ class BuilderBase:
includestring,
macrostring)
if VERBOSE: print cmdstring
if VERBOSE:
print cmdstring
return os.system(cmdstring)
@ -160,21 +224,17 @@ class BuilderBase:
self.linker_out_string(outfile))
for objectfile in objects:
cmdstring = "%s %s" % (cmdstring, objectfile + self.object_extension)
cmdstring = "%s %s" % (cmdstring, objectfile + self.object_extension)
for libpath in libpaths:
cmdstring = "%s %s%s" % (cmdstring, self.libpath_delimiter, libpath)
for library in libraries:
cmdstring = "%s %s" % (cmdstring, library)
if extra_parameters:
cmdstring = "%s %s" % (cmdstring, extra_parameters)
if VERBOSE: print cmdstring
return os.system(cmdstring)
def _build_command_string(self, macros, argument_delimiter):
macrostring = ""
@ -185,19 +245,20 @@ class BuilderBase:
macrostring += '%s%s ' % (argument_delimiter, item)
return macrostring
# -----------------------------------------------------------------------
class GCCBuilder(BuilderBase):
""" Generic GCC compiler class """
def __init__(self):
self.include_delimiter = "-I"
self.macro_delimiter = "-D"
self.libpath_delimiter = "-L"
self.compiler_parameters = "-fpermissive"
self.compiler_parameters = "-fpermissive -Wno-write-strings"
self.linker_parameters = "-shared"
self.basemacros = [ ]
self.compiler = "g++"
self.linker = "g++"
self.compiler = "g++ -m32"
self.linker = "g++ -m32"
self.source_extension = ".cpp"
self.object_extension = ".o"
@ -211,8 +272,9 @@ class GCCBuilder(BuilderBase):
return "-o %s" % filename
# -----------------------------------------------------------------------
class MSVCBuilder(BuilderBase):
""" Generic GCC compiler class """
""" Generic Visual C compiler class """
def __init__(self):
self.include_delimiter = "/I"
self.macro_delimiter = "/D"
@ -226,113 +288,156 @@ class MSVCBuilder(BuilderBase):
self.linker = "link"
self.source_extension = ".cpp"
self.object_extension = ".obj"
def compiler_in_string(self, filename):
return "/c %s" % filename
def compiler_out_string(self, filename):
return "/Fo%s" % filename
def linker_out_string(self, filename):
return "/out:%s" % filename
def build_distribution(manifest, distrootdir):
""" Create dist tree and copy files to it """
# Remove the previous distibution if exits
# -----------------------------------------------------------------------
def build_distribution(manifest, distrootdir, ea64, nukeold):
""" Create a distibution to a directory and a ZIP file """
# (Re)create the output directory
if os.path.exists(distrootdir):
shutil.rmtree(distrootdir)
# Create output directory
os.makedirs(distrootdir)
if nukeold:
shutil.rmtree(distrootdir)
os.makedirs(distrootdir)
else:
os.makedirs(distrootdir)
# Also make a ZIP archive of the build
zippath = distrootdir + ".zip"
zip = zipfile.ZipFile(zippath, nukeold and "w" or "a", zipfile.ZIP_DEFLATED)
# Copy files, one by one
for f in manifest:
if type(f) == types.TupleType:
srcfilepath = f[0]
srcfilename = os.path.basename(srcfilepath)
dstdir = distrootdir + os.sep + f[1]
dstfilepath = dstdir + os.sep + srcfilename
dstdir = os.path.join(distrootdir, f[1])
dstfilepath = os.path.join(dstdir, srcfilename)
else:
srcfilepath = f
srcfilename = os.path.basename(f)
srcdir = os.path.dirname(f)
if srcdir == "":
dstdir = distrootdir
else:
dstdir = distrootdir + os.sep + srcdir
dstdir = os.path.join(distrootdir, srcdir)
if not os.path.exists(dstdir):
os.makedirs(dstdir)
dstfilepath = dstdir + os.sep + srcfilename
dstfilepath = os.path.join(dstdir, srcfilename)
shutil.copyfile(srcfilepath, dstfilepath)
zip.write(dstfilepath)
zip.close()
def build_plugin(system, idasdkdir):
# -----------------------------------------------------------------------
def build_plugin(
platform,
idasdkdir,
plugin_name,
options):
""" Build the plugin from the SWIG wrapper and plugin main source """
# Find IDA SDK headers
ida_include_directory = idasdkdir + os.sep + "include"
global SWIG_OPTIONS
# Get the arguments
ea64 = options[S_EA64]
with_hexrays = options[S_WITH_HEXRAYS]
# Path to the IDA SDK headers
ida_include_directory = os.path.join(idasdkdir, "include")
builder = None
# Platform-specific settings for the Linux build
if system == "Linux":
if platform == "linux":
builder = GCCBuilder()
plugin_name = "python.plx"
platform_macros = [ "__LINUX__" ]
python_libpath = sysconfig.EXEC_PREFIX + os.sep + "lib"
python_library = "-lpython%d.%d" % (PYTHON_MAJOR_VERSION, PYTHON_MINOR_VERSION)
ida_libpath = idasdkdir + os.sep + "libgcc32.lnx"
python_libpath = os.path.join(sysconfig.EXEC_PREFIX, "lib")
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 = "/usr/lib/python%s.%s/lib-dynload/*.so" % (PYTHON_MAJOR_VERSION, PYTHON_MINOR_VERSION)
extra_link_parameters = " -s"
builder.compiler_parameters += " -O2"
# Platform-specific settings for the Windows build
if system == "Windows":
elif platform == "win32":
builder = MSVCBuilder()
plugin_name = "python.plw"
platform_macros = [ "__NT__" ]
python_libpath = sysconfig.EXEC_PREFIX + os.sep + "libs"
python_libpath = os.path.join(sysconfig.EXEC_PREFIX, "libs")
python_library = "python%d%d.lib" % (PYTHON_MAJOR_VERSION, PYTHON_MINOR_VERSION)
ida_libpath = idasdkdir + os.sep + "libvc.w32"
ida_libpath = os.path.join(idasdkdir, "lib", ea64 and "x86_win_vc_64" or "x86_win_vc_32")
ida_lib = "ida.lib"
extra_link_parameters = None
# Platform-specific settings for the Linux build
if system == "Darwin":
SWIG_OPTIONS += " -D__NT__ "
extra_link_parameters = ""
if options[S_DEBUG]:
builder.compiler_parameters += " /Zi"
builder.linker_parameters += " /DEBUG"
if not options[S_NO_OPT] and not options[S_DEBUG]:
builder.compiler_parameters += " -Ox"
# Platform-specific settings for the Mac OS X build
elif platform == "macosx":
builder = GCCBuilder()
builder.linker_parameters = "-dynamiclib"
plugin_name = "python.pmc"
platform_macros = [ "__MAC__" ]
python_libpath = "."
python_library = "-framework Python"
ida_libpath = idasdkdir + os.sep + "libgcc32.mac"
ida_lib = "-lida"
extra_link_parameters = ""
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 = " -s"
builder.compiler_parameters += " -O3"
assert builder, "Unknown platform! No idea how to build here..."
# Enable EA64 for the compiler if necessary
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:
platform_macros.append("PLUGINFIX")
# Turn off obsolete functions
#platform_macros.append("NO_OBSOLETE_FUNCS")
# Build the wrapper from the interface files
swigcmd = "swig %s -Iswig -o idaapi.cpp -I%s idaapi.i" % (SWIG_OPTIONS, ida_include_directory)
ea64flag = ea64 and "-D__EA64__" or ""
swigcmd = "swig %s -Iswig -o idaapi.cpp %s -I%s idaapi.i" % (SWIG_OPTIONS, ea64flag, ida_include_directory)
if VERBOSE: print swigcmd
res = os.system(swigcmd)
assert res == 0, "Failed to build the wrapper with SWIG"
if res != 0: return False
# If we are running on windows, we have to patch some directors'
# virtual methods, so they have the right calling convention.
# Without that, compilation just won't succeed.
if platform == "win32":
res = os.system("python patch_directors_cc.py -f idaapi.h")
assert res == 0, "Failed to patch directors' calling conventions"
# Compile the wrapper
res = builder.compile("idaapi",
includes=[ PYTHON_INCLUDE_DIRECTORY, ida_include_directory ],
macros=platform_macros)
if res != 0: return False
assert res == 0, "Failed to build the wrapper module"
# Compile the main plugin source
res = builder.compile("python",
includes=[ PYTHON_INCLUDE_DIRECTORY, ida_include_directory ],
macros=platform_macros)
if res != 0: return False
assert res == 0, "Failed to build the main plugin object"
# Link the final binary
res = builder.link( ["idaapi", "python"],
@ -340,69 +445,163 @@ def build_plugin(system, idasdkdir):
[ python_libpath, ida_libpath ],
[ python_library, ida_lib ],
extra_link_parameters)
assert res == 0, "Failed to link the plugin binary"
if res != 0: return False
return True
def clean(manifest):
""" Clean the temporary files """
for i in manifest:
try:
os.unlink(i)
except:
pass
if __name__ == "__main__":
# -----------------------------------------------------------------------
def detect_platform(ea64):
# Detect the platform
system = platform.system()
if system == "Windows" or system == "Microsoft":
system = "Windows"
platform_string = "win32"
plugin_name = "python.plw"
if system == "Linux":
platform_string = "linux"
plugin_name = "python.plx"
plugin_name = ea64 and "python.p64" or "python.plw"
if system == "Darwin":
elif system == "Linux":
platform_string = "linux"
plugin_name = ea64 and "python.plx64" or "python.plx"
elif system == "Darwin":
platform_string = "macosx"
plugin_name = "python.pmc"
BINDISTDIR = "idapython-%d.%d.%d_ida%d.%d_py%d.%d_%s" % ( VERSION_MAJOR,
VERSION_MINOR,
VERSION_PATCH,
IDA_MAJOR_VERSION,
IDA_MINOR_VERSION,
PYTHON_MAJOR_VERSION,
PYTHON_MINOR_VERSION,
platform_string)
SRCDISTDIR = "idapython-%d.%d.%d" % ( VERSION_MAJOR,
VERSION_MINOR,
VERSION_PATCH )
plugin_name = ea64 and "python.pmc64" or "python.pmc"
else:
print "Unknown platform!"
sys.exit(-1)
return (system, platform_string, plugin_name)
# -----------------------------------------------------------------------
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,
VERSION_PATCH,
IDA_MAJOR_VERSION,
IDA_MINOR_VERSION,
PYTHON_MAJOR_VERSION,
PYTHON_MINOR_VERSION,
platform_string)
# Build the plugin
res = build_plugin(system, IDA_SDK)
if not res: sys.exit(1)
build_plugin(platform_string, IDA_SDK, plugin_name, options)
# Build the binary distribution
binmanifest = []
binmanifest.extend(BINDIST_MANIFEST)
binmanifest.append((plugin_name, "plugins"))
build_distribution(binmanifest, BINDISTDIR)
if nukeold:
binmanifest.extend(BINDIST_MANIFEST)
# Build the binary distribution
if not ea64 or nukeold:
binmanifest.extend([(x, "python") for x in "python/init.py", "python/idc.py", "python/idautils.py", "idaapi.py"])
binmanifest.append((plugin_name, "plugins"))
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,
VERSION_MINOR,
VERSION_PATCH)
# Build the source distribution
srcmanifest = []
srcmanifest.extend(BINDIST_MANIFEST)
srcmanifest.extend(SRCDIST_MANIFEST)
build_distribution(srcmanifest, SRCDISTDIR)
srcmanifest.extend([(x, "python") for x in "python/init.py", "python/idc.py", "python/idautils.py"])
build_distribution(srcmanifest, SRCDISTDIR, ea64=False, nukeold=True)
# Clean the temp files
cleanlist = []
cleanlist.extend(BUILD_TEMPFILES)
cleanlist.append(plugin_name)
# clean(cleanlist)
# -----------------------------------------------------------------------
def gen_docs(z = False):
print "Generating documentation....."
old_dir = os.getcwd()
try:
curdir = os.getcwd() + os.sep
docdir = 'idapython-reference-%d.%d.%d' % (VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH)
sys.path.append(curdir + 'python')
sys.path.append(curdir + 'tools')
sys.path.append(curdir + 'docs')
import epydoc.cli
import swigdocs
os.chdir('docs')
PYWRAPS_FN = 'pywraps'
swigdocs.gen_docs(outfn = PYWRAPS_FN + '.py')
epydoc.cli.optparse.sys.argv = [ 'epydoc',
'--no-sourcecode',
'-u', 'http://code.google.com/p/idapython/',
'--navlink', '<a href="http://www.hex-rays.com/idapro/idapython_docs/">IDAPython Reference</a>',
'--no-private',
'--simple-term',
'-o', docdir,
'--html',
'idc', 'idautils', PYWRAPS_FN, 'idaapi']
# Generate the documentation
epydoc.cli.cli()
print "Documentation generated!"
# Clean temp files
for f in [PYWRAPS_FN + '.py', PYWRAPS_FN + '.pyc']:
if os.path.exists(f):
os.unlink(f)
if z:
z = docdir + '-doc.zip'
zip = zipfile.ZipFile(z, "w", zipfile.ZIP_DEFLATED)
for fn in glob.glob(docdir + os.sep + '*'):
zip.write(fn)
zip.close()
print "Documentation compressed to", z
except Exception, e:
print 'Failed to generate documentation:', e
finally:
os.chdir(old_dir)
return
# -----------------------------------------------------------------------
def usage():
print """IDAPython build script.
Available switches:
--doc:
Generate documentation into the 'docs' directory
--zip:
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)
if '--debug' in sys.argv:
debug = 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:
options[S_EA64] = True
build_binary_package(options, nukeold=False)
# Always build the source package
build_source_package()
# -----------------------------------------------------------------------
if __name__ == "__main__":
main()

View File

@ -1,53 +1,53 @@
Assorted notes
--------------
Wrapped functions and constants:
All the symbols from the idaapi module are listed in symbollist.txt.
Documentation for the plugin API functions functions is in the IDA
SDK header files. All function and symbol names directly translate
to the C++ counterparts. If you try to use a function that is not
wrapped yet you will get an exception like this:
Traceback (most recent call last):
File "<string>", line 1, in ?
NameError: name 'foobar' is not defined
If this happens you can check the function in symbollist.txt. If it
is not included and it should be please report it to the author.
Data types:
All the C++ data types are mapped to corresponding Python data types.
For example ea_t maps to a Python integer. Complex data types (like
structures and classes) are mapped to Python classes that have the
same attributes as the original type.
Arguments and return values:
Generally all function arguments should be the same type as specified
by the original headers. Pointers to complex types (structures, classes)
are checked and must match the original declarations.
For example comment = get_func_comment("aa", 0) will raise an exception:
Traceback (most recent call last):
File "<string>", line 1, in ?
TypeError: Type error. Got aa, expected _p_func_t
When calling functions that return a string in a buffer (usually with
maximum size) the buffer and size parameter is omitted. These functions
return either the result in a string or None if the call fails and returns
NULL. The output buffers are maximized at MAXSTR.
Example:
C++: get_func_name(0x1234, buf, sizeof(buf));
Python: name = get_func_name(0x1234)
Any function that should return a char * is going to return either a
Python string (up to MAXSTR) or None.
Assorted notes
--------------
Wrapped functions and constants:
All the symbols from the idaapi module are listed in symbollist.txt.
Documentation for the plugin API functions functions is in the IDA
SDK header files. All function and symbol names directly translate
to the C++ counterparts. If you try to use a function that is not
wrapped yet you will get an exception like this:
Traceback (most recent call last):
File "<string>", line 1, in ?
NameError: name 'foobar' is not defined
If this happens you can check the function in symbollist.txt. If it
is not included and it should be please report it to the author.
Data types:
All the C++ data types are mapped to corresponding Python data types.
For example ea_t maps to a Python integer. Complex data types (like
structures and classes) are mapped to Python classes that have the
same attributes as the original type.
Arguments and return values:
Generally all function arguments should be the same type as specified
by the original headers. Pointers to complex types (structures, classes)
are checked and must match the original declarations.
For example comment = get_func_comment("aa", 0) will raise an exception:
Traceback (most recent call last):
File "<string>", line 1, in ?
TypeError: Type error. Got aa, expected _p_func_t
When calling functions that return a string in a buffer (usually with
maximum size) the buffer and size parameter is omitted. These functions
return either the result in a string or None if the call fails and returns
NULL. The output buffers are maximized at MAXSTR.
Example:
C++: get_func_name(0x1234, buf, sizeof(buf));
Python: name = get_func_name(0x1234)
Any function that should return a char * is going to return either a
Python string (up to MAXSTR) or None.

View File

@ -1,46 +1,50 @@
#
# Demonstration of the new chooser usage
#
#
# Modal chooser
#
# Get a modal Choose instance
chooser = Choose([], "MyChooser", 1)
# List to choose from
chooser.list = [ "First", "Second", "Third" ]
# Set the width
chooser.width = 50
# Run the chooser
ch = chooser.choose()
# Print the results
if ch > 0:
print "You chose %d which is %s" % (ch, chooser.list[ch-1])
else:
print "Escape from chooser"
#
# Normal chooser
#
class MyChoose(Choose):
"""
You have to subclass Chooser to override the enter() method
"""
def __init__(self, list=[], name="Choose"):
Choose.__init__(self, list, name)
# Set the width
self.width = 50
def enter(self, n):
print "Enter called. Do some stuff here."
print "The chosen item is %d = %s" % (n, self.list[n-1])
print "Now press ESC to leave."
# Get a Choose instance
chooser = MyChoose([ "First", "Second", "Third" ], "MyChoose")
# Run the chooser
ch = chooser.choose()
#---------------------------------------------------------------------
# Chooser test
#
# This script demonstrates the usage of the class-based chooser.
#
# Author: Gergely Erdelyi <gergely.erdelyi@d-dome.net>
#---------------------------------------------------------------------
from idaapi import Choose
#
# Modal chooser
#
# Get a modal Choose instance
chooser = Choose([], "MyChooser", 1)
# List to choose from
chooser.list = [ "First", "Second", "Third" ]
# Set the width
chooser.width = 50
# Run the chooser
ch = chooser.choose()
# Print the results
if ch > 0:
print "You chose %d which is %s" % (ch, chooser.list[ch-1])
else:
print "Escape from chooser"
#
# Normal chooser
#
class MyChoose(Choose):
"""
You have to subclass Chooser to override the enter() method
"""
def __init__(self, list=[], name="Choose"):
Choose.__init__(self, list, name)
# Set the width
self.width = 50
self.deflt = 1
def enter(self, n):
print "Enter called. Do some stuff here."
print "The chosen item is %d = %s" % (n, self.list[n-1])
print "Now press ESC to leave."
# Get a Choose instance
chooser = MyChoose([ "First", "Second", "Third" ], "MyChoose")
# Run the chooser
ch = chooser.choose()

19
examples/colours.py Normal file
View File

@ -0,0 +1,19 @@
#---------------------------------------------------------------------
# Colour test
#
# This script demonstrates the usage of background colours.
#
# Author: Gergely Erdelyi <gergely.erdelyi@d-dome.net>
#---------------------------------------------------------------------
# Set the colour of the current segment to BLUE
SetColor(here(), CIC_SEGM, 0xc02020)
# Set the colour of the current function to GREEN
SetColor(here(), CIC_FUNC, 0x208020)
# Set the colour of the current item to RED
SetColor(here(), CIC_ITEM, 0x2020c0)
# Print the colours just set
print "%x" % GetColor(here(), CIC_SEGM)
print "%x" % GetColor(here(), CIC_FUNC)
print "%x" % GetColor(here(), CIC_ITEM)

107
examples/debughook.py Normal file
View File

@ -0,0 +1,107 @@
#---------------------------------------------------------------------
# Debug notification hook test
#
# This script start the executable and steps through the first five
# instructions. Each instruction is disassembled after execution.
#
# Original Author: Gergely Erdelyi <gergely.erdelyi@d-dome.net>
#
# Maintained By: IDAPython Team
#
#---------------------------------------------------------------------
from idaapi import *
class MyDbgHook(DBG_Hooks):
""" Own debug hook class that implementd the callback functions """
def dbg_process_start(self, pid, tid, ea, name, base, size):
print("Process started, pid=%d tid=%d name=%s" % (pid, tid, name))
def dbg_process_exit(self, pid, tid, ea, code):
print("Process exited pid=%d tid=%d ea=0x%x code=%d" % (pid, tid, ea, code))
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_process_attach(self, pid, tid, ea, name, base, size):
print("Process attach pid=%d tid=%d ea=0x%x name=%s base=%x size=%x" % (pid, tid, ea, name, base, size))
def dbg_process_detach(self, pid, tid, ea):
print("Process detached, pid=%d tid=%d ea=0x%x" % (pid, tid, ea))
return 0
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)
def dbg_bpt(self, tid, ea):
print "Break point at 0x%x pid=%d" % (ea, tid)
# return values:
# -1 - to display a breakpoint warning dialog
# if the process is suspended.
# 0 - to never display a breakpoint warning dialog.
# 1 - to always display a breakpoint warning dialog.
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):
print("Trace tid=%d ea=0x%x" % (tid, ea))
# return values:
# 1 - do not log this trace event;
# 0 - log it
return 0
def dbg_step_into(self):
print("Step into")
self.dbg_step_over()
def dbg_run_to(self, pid, tid=0, ea=0):
print "Runto: tid=%d" % tid
idaapi.continue_process()
def dbg_step_over(self):
eip = GetRegValue("EIP")
print("0x%x %s" % (eip, GetDisasm(eip)))
self.steps += 1
if self.steps >= 5:
request_exit_process()
else:
request_step_over()
# Remove an existing debug hook
try:
if debughook:
print("Removing previous hook ...")
debughook.unhook()
except:
pass
# Install the debug hook
debughook = MyDbgHook()
debughook.hook()
debughook.steps = 0
# Stop at the entry point
ep = GetLongPrm(INF_START_IP)
request_run_to(ep)
# Step one instruction
request_step_over()
# Start debugging
run_requests()

View File

@ -1,35 +1,35 @@
//
// Reference Lister
//
// List all functions and all references to them in the current section.
//
// Implemented in IDC
//
#include <idc.idc>
static main()
{
auto ea, func, ref;
// Get current ea
ea = ScreenEA();
// Loop from start to end in the current segment
for (func=SegStart(ea);
func != BADADDR && func < SegEnd(ea);
func=NextFunction(func))
{
// If the current address is function process it
if (GetFunctionFlags(func) != -1)
{
Message("Function %s at 0x%x\n", GetFunctionName(func), func);
// Find all code references to func
for (ref=RfirstB(func); ref != BADADDR; ref=RnextB(func, ref))
{
Message(" called from %s(0x%x)\n", GetFunctionName(ref), ref);
}
}
}
}
//
// Reference Lister
//
// List all functions and all references to them in the current section.
//
// Implemented in IDC
//
#include <idc.idc>
static main()
{
auto ea, func, ref;
// Get current ea
ea = ScreenEA();
// Loop from start to end in the current segment
for (func=SegStart(ea);
func != BADADDR && func < SegEnd(ea);
func=NextFunction(func))
{
// If the current address is function process it
if (GetFunctionFlags(func) != -1)
{
Message("Function %s at 0x%x\n", GetFunctionName(func), func);
// Find all code references to func
for (ref=RfirstB(func); ref != BADADDR; ref=RnextB(func, ref))
{
Message(" called from %s(0x%x)\n", GetFunctionName(ref), ref);
}
}
}
}

View File

@ -7,23 +7,27 @@
#
from idaapi import *
# Get current ea
ea = get_screen_ea()
def main():
# Get current ea
ea = get_screen_ea()
# Get segment class
seg = getseg(ea)
# Get segment class
seg = getseg(ea)
# Loop from segment start to end
func = get_func(seg.startEA)
# Loop from segment start to end
func = get_next_func(seg.startEA)
seg_end = seg.endEA
while func is not None and func.startEA < seg_end:
funcea = func.startEA
print "Function %s at 0x%x" % (GetFunctionName(funcea), funcea)
while func != None and func.startEA < seg.endEA:
funcea = func.startEA
print "Function %s at 0x%x" % (GetFunctionName(funcea), funcea)
ref = get_first_cref_to(funcea)
ref = get_first_cref_to(funcea)
while ref != BADADDR:
print " called from %s(0x%x)" % (get_func_name(ref), ref)
ref = get_next_cref_to(funcea, ref)
while ref != BADADDR:
print " called from %s(0x%x)" % (get_func_name(ref), ref)
ref = get_next_cref_to(funcea, ref)
func = get_next_func(funcea)
func = get_next_func(funcea)
main()

View File

@ -7,14 +7,21 @@
#
from idautils import *
# Get current ea
ea = ScreenEA()
def main():
# Get current ea
ea = ScreenEA()
if ea == idaapi.BADADDR:
print("Could not get get_screen_ea()")
return
# Loop from start to end in the current segment
for funcea in Functions(SegStart(ea), SegEnd(ea)):
print "Function %s at 0x%x" % (GetFunctionName(funcea), funcea)
# Loop from start to end in the current segment
for funcea in Functions(SegStart(ea), SegEnd(ea)):
print("Function %s at 0x%x" % (GetFunctionName(funcea), funcea))
# Find all code references to funcea
for ref in CodeRefsTo(funcea, 1):
print " called from %s(0x%x)" % (GetFunctionName(ref), ref)
# Find all code references to funcea
for ref in CodeRefsTo(funcea, 1):
print(" called from %s(0x%x)" % (GetFunctionName(ref), ref))
if __name__=='__main__':
main()

119
examples/ex_actions.py Normal file
View File

@ -0,0 +1,119 @@
import idaapi
class SayHi(idaapi.action_handler_t):
def __init__(self, message):
idaapi.action_handler_t.__init__(self)
self.message = message
def activate(self, ctx):
print "Hi, %s" % (self.message)
return 1
# You can implement update(), to inform IDA when:
# * your action is enabled
# * update() should queried again
# E.g., returning 'idaapi.AST_ENABLE_FOR_FORM' will
# tell IDA that this action is available while the
# user is in the current widget, and that update()
# must be queried again once the user gives focus
# to another widget.
#
# For example, the following update() implementation
# will let IDA know that the action is available in
# "IDA View-*" views, and that it's not even worth
# querying update() anymore until the user has moved
# to another view..
def update(self, ctx):
return idaapi.AST_ENABLE_FOR_FORM if ctx.form_type == idaapi.BWN_DISASM else idaapi.AST_DISABLE_FOR_FORM
print "Creating a custom icon from raw data!"
# Stunned panda face icon data.
icon_data = "".join([
"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x02\xCA\x49\x44\x41\x54\x78\x5E\x65",
"\x53\x6D\x48\x53\x6F\x14\x3F\xBA\xB5\xB7\xA0\x8D\x20\x41\xF2\xBA\x5D\xB6\x0F\x56\xF4\x41\xA2\xC0\x9C\xE9\xB4\x29\x4A\x7D\xB0\x22\x7A\x11\x02\x23\x48\x2A\xD4\x74\x53\x33\x3F\xD4",
"\x3E\x4A\x50\x19\xE4\xB0\xD0\x22\xCD\x44\x45\x4A\x31\x8C\x92\xA2\x3E\x65\x0A\x4D\xCB\x96\x7E\xE8\xD5\x97\xCC\xFE\xFE\x37\xA7\x77\xDB\xBD\xA7\xE7\x3C\xBE\x05\x9E\xED\xB7\xB3\xF3",
"\x7B\x39\xF7\xEE\x19\x17\xA8\xAC\x56\xDB\x54\x82\x60\x41\xB3\x59\xBC\xFF\xAC\xF9\xCA\xB5\xAE\x86\xCA\xF9\x4E\xAF\x1B\x3B\xEA\x5D\x48\x9D\x66\xE2\x49\x27\x9F\xD5\x66\x9B\xA2\x1C",
"\x22\x02\xD0\x40\xE4\x81\x6C\x3B\x76\x37\x56\xE3\x37\x5F\x2F\x62\xE8\x0B\xD3\x66\x19\x7E\x53\xA7\x99\x78\xAE\x1F\x64\x3E\x21\x71\x69\x09\x5F\x20\x98\x2D\x58\x70\x24\x07\x07\x7B",
"\x6F\xB0\x79\x82\x61\x81\x21\xCC\xDE\x21\x54\x16\x02\xD4\x69\x26\x9E\x74\xEE\xCB\xCF\x4D\xC7\x44\xB3\x88\x7C\x81\xC5\x22\xFE\x6C\xB9\xE9\x46\x67\x46\x1A\x8A\x16\x2B\x0A\x5B\x05",
"\x74\x66\x65\xE1\x98\x6F\x00\x31\x32\x87\x9F\x59\x77\x66\x66\x61\x42\xBC\xC0\xF5\x6C\x47\x1A\x36\xD7\xB9\x51\x14\xC5\x1E\xBE\xA0\xC3\x5B\xD9\x98\x99\xE1\xC0\xCE\xBE\x57\x48\xD7",
"\x9A\x63\x68\xEA\x7C\x8A\xF6\x14\x3B\x9F\xF6\xA6\xA4\x60\xEB\xE3\x3E\x9C\x5F\xD6\x5A\x7A\xFA\x71\xBF\xC3\x81\x3D\x4D\x35\x0D\x7C\xC1\xF3\x87\x57\x43\xF9\x87\x8F\x21\x95\x5E\xAB",
"\x41\x83\x4E\x83\x54\xDB\x92\x76\x20\xCA\xBF\xD0\x99\x9D\xBB\x4E\xDB\xBD\xC7\x8E\x2F\x5A\x3D\x74\x3D\x50\x03\x80\x7E\x7A\x7A\x06\x46\x47\xFD\xA0\x33\x6C\x84\x18\x46\x0C\xBD\x1F",
"\x86\x2D\x71\x71\x00\x52\x10\x16\x17\xE6\xC1\xE7\x1B\x61\x9A\x81\x69\x31\x30\xFC\x61\x14\xB4\x3A\x3D\x20\x82\x1E\x58\xA9\x15\x05\x41\x14\x05\xB8\x58\xEE\x82\x7D\xE9\x99\x20\xCB",
"\x32\x94\x95\x95\xC3\xA5\xD2\x53\x00\x51\x09\xAA\x4B\x0B\xA1\xB8\xA4\x0C\x52\x53\x33\x40\xA5\x52\x81\xDB\x5D\x01\xA2\x45\x00\x45\x51\x80\x2A\x36\x12\x8D\x42\x49\x51\x01\x44\xE5",
"\x18\x90\x22\x0A\x98\x8C\x46\xF0\x54\x14\x42\x6D\x7D\x3B\xE4\x1C\x75\x41\xAD\xB7\x1D\x3C\x55\x85\x60\x32\x19\x41\x8A\x2A\xDC\x57\x5C\x74\x12\x28\x47\xA5\x8E\x44\xE4\xF0\x76\x5B",
"\x82\xA6\xCD\x5B\x0D\xB2\x12\xE6\xE4\x06\xB5\x1A\x66\xA7\x26\x41\x92\xC2\xA0\xD5\x6A\x60\x67\x92\x19\xAE\x7B\xCE\x70\x4D\x15\xAB\x01\xAD\xC1\x08\x3F\x46\x64\x6E\x8E\x9D\xF9\x13",
"\xE8\x1A\xFF\xE4\x63\x8A\x0E\xE6\x02\x41\xF8\x3F\x18\x82\x40\x28\x04\xFD\xDD\x75\xF0\xB6\xFF\x2E\x75\x9A\x89\x27\x9D\xFB\xC8\x4F\x39\xBE\xE0\xB4\xAB\xCE\x35\xFE\x71\x00\x16\x17",
"\x25\x76\x50\x26\x76\x6B\x61\x86\x08\xE4\x1D\xAF\x81\xBC\x13\x97\xA9\xD3\x4C\x3C\xE9\xDC\x47\x7E\xCA\xF1\x05\x0C\x5F\x7D\xFE\xEF\x35\x03\xAF\x9F\x00\xB0\x73\x30\x9A\xE2\x81\x0E",
"\xF6\xC1\xED\x52\xB8\x77\xAB\x98\x3A\xCD\xC4\x73\x9D\x7C\x6F\xDE\xF9\xCF\x53\x0E\xFE\xA9\xCD\xAE\xB3\x87\xCE\x75\x35\x54\xE1\xD0\xCB\x47\x38\x39\x36\x88\xFF\x4D\xF8\x57\x41\x33",
"\xF1\xA4\x93\x0F\x00\x36\xAD\x3E\x4C\x6B\xC5\xC9\x5D\x77\x6A\x2F\xB4\x31\xA3\xC4\x40\x4F\x21\x0F\xD1\x4C\x3C\xE9\x2B\xE1\xF5\x0B\xD6\x90\xC8\x90\x4C\xE6\x35\xD0\xCC\x79\x5E\xFF",
"\x2E\xF8\x0B\x2F\x3D\xE5\xC3\x97\x06\xCF\xCF\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82"])
act_icon = idaapi.load_custom_icon(data=icon_data, format="png")
hooks = None
act_name = "example:add_action"
if idaapi.register_action(idaapi.action_desc_t(
act_name, # Name. Acts as an ID. Must be unique.
"Say hi!", # Label. That's what users see.
SayHi("developer"), # Handler. Called when activated, and for updating
"Ctrl+F12", # Shortcut (optional)
"Greets the user", # Tooltip (optional)
act_icon)): # Icon ID (optional)
print "Action registered. Attaching to menu."
# Insert the action in the menu
if idaapi.attach_action_to_menu("Edit/Export data", act_name, idaapi.SETMENU_APP):
print "Attached to menu."
else:
print "Failed attaching to menu."
# Insert the action in a toolbar
if idaapi.attach_action_to_toolbar("AnalysisToolBar", act_name):
print "Attached to toolbar."
else:
print "Failed attaching to toolbar."
# We will also want our action to be available in the context menu
# for the "IDA View-A" widget.
#
# To do that, we could in theory retrieve a reference to "IDA View-A", and
# then request to "permanently" attach the action to it, using something
# like this:
# idaapi.attach_action_to_popup(ida_view_a, None, act_name, None)
#
# but alas, that won't do: widgets in IDA are very "volatile", and
# can be deleted & re-created on some occasions (e.g., starting a
# debugging session), and our efforts to permanently register our
# action on "IDA View-A" would be annihilated as soon as "IDA View-A"
# is deleted.
#
# Instead, we can opt for a different method: attach our action on-the-fly,
# when the popup for "IDA View-A" is being populated, right before
# it is displayed.
class Hooks(idaapi.UI_Hooks):
def finish_populating_tform_popup(self, form, popup):
# We'll add our action to all "IDA View-*"s.
# If we wanted to add it only to "IDA View-A", we could
# also discriminate on the widget's title:
#
# if idaapi.get_tform_title(form) == "IDA View-A":
# ...
#
if idaapi.get_tform_type(form) == idaapi.BWN_DISASM:
idaapi.attach_action_to_popup(form, popup, act_name, None)
hooks = Hooks()
hooks.hook()
else:
print "Action found; unregistering."
# No need to call detach_action_from_menu(); it'll be
# done automatically on destruction of the action.
if idaapi.unregister_action(act_name):
print "Unregistered."
else:
print "Failed to unregister action."
if hooks is not None:
hooks.unhook()
hooks = None

View File

@ -0,0 +1,18 @@
import idaapi
def cb(*args):
print("Callback called!")
return 1
try:
ex_addmenu_item_ctx
idaapi.del_menu_item(ex_addmenu_item_ctx)
print("Menu removed")
del ex_addmenu_item_ctx
except:
ex_addmenu_item_ctx = idaapi.add_menu_item("Search/", "X", "", 0, cb, tuple("hello world"))
if ex_addmenu_item_ctx is None:
print("Failed to add menu!")
del ex_addmenu_item_ctx
else:
print("Menu added successfully. Run the script again to delete the menu")

379
examples/ex_askusingform.py Normal file
View File

@ -0,0 +1,379 @@
# -----------------------------------------------------------------------
# This is an example illustrating how to use the Form class
# (c) Hex-Rays
#
from idaapi import Form
#<pycode(ex_askusingform)>
# --------------------------------------------------------------------------
class TestEmbeddedChooserClass(Choose2):
"""
A simple chooser to be used as an embedded chooser
"""
def __init__(self, title, nb = 5, flags=0):
Choose2.__init__(self,
title,
[ ["Address", 10], ["Name", 30] ],
embedded=True, width=30, height=20, flags=flags)
self.n = 0
self.items = [ self.make_item() for x in xrange(0, nb+1) ]
self.icon = 5
self.selcount = 0
def make_item(self):
r = [str(self.n), "func_%04d" % self.n]
self.n += 1
return r
def OnClose(self):
pass
def OnGetLine(self, n):
print("getline %d" % n)
return self.items[n]
def OnGetSize(self):
n = len(self.items)
print("getsize -> %d" % n)
return n
# --------------------------------------------------------------------------
class MyForm(Form):
def __init__(self):
self.invert = False
self.EChooser = TestEmbeddedChooserClass("E1", flags=Choose2.CH_MULTI)
Form.__init__(self, r"""STARTITEM {id:rNormal}
BUTTON YES* Yeah
BUTTON NO Nope
BUTTON CANCEL Nevermind
Form Test
{FormChangeCb}
This is a string: +{cStr1}+
This is an address: +{cAddr1}+
Escape\{control}
This is a string: '{cStr2}'
This is a number: {cVal1}
<#Hint1#Enter name:{iStr1}>
<#Hint2#Select color:{iColor1}>
Browse test
<#Select a file to open#Browse to open:{iFileOpen}>
<#Select a file to save#Browse to save:{iFileSave}>
<#Select dir#Browse for dir:{iDir}>
Type
<#Select type#Write a type:{iType}>
Numbers
<##Enter a selector value:{iSegment}>
<##Enter a raw hex:{iRawHex}>
<##Enter a character:{iChar}>
<##Enter an address:{iAddr}>
Button test
<##Button1:{iButton1}> <##Button2:{iButton2}>
Check boxes:
<Error output:{rError}>
<Normal output:{rNormal}>
<Warnings:{rWarnings}>{cGroup1}>
Radio boxes:
<Green:{rGreen}>
<Red:{rRed}>
<Blue:{rBlue}>{cGroup2}>
<Embedded chooser:{cEChooser}>
The end!
""", {
'cStr1': Form.StringLabel("Hello"),
'cStr2': Form.StringLabel("StringTest"),
'cAddr1': Form.NumericLabel(0x401000, Form.FT_ADDR),
'cVal1' : Form.NumericLabel(99, Form.FT_HEX),
'iStr1': Form.StringInput(),
'iColor1': Form.ColorInput(),
'iFileOpen': Form.FileInput(open=True),
'iFileSave': Form.FileInput(save=True),
'iDir': Form.DirInput(),
'iType': Form.StringInput(tp=Form.FT_TYPE),
'iSegment': Form.NumericInput(tp=Form.FT_SEG),
'iRawHex': Form.NumericInput(tp=Form.FT_RAWHEX),
'iAddr': Form.NumericInput(tp=Form.FT_ADDR),
'iChar': Form.NumericInput(tp=Form.FT_CHAR),
'iButton1': Form.ButtonInput(self.OnButton1),
'iButton2': Form.ButtonInput(self.OnButton2),
'cGroup1': Form.ChkGroupControl(("rNormal", "rError", "rWarnings")),
'cGroup2': Form.RadGroupControl(("rRed", "rGreen", "rBlue")),
'FormChangeCb': Form.FormChangeCb(self.OnFormChange),
'cEChooser' : Form.EmbeddedChooserControl(self.EChooser)
})
def OnButton1(self, code=0):
print("Button1 pressed")
def OnButton2(self, code=0):
print("Button2 pressed")
def OnFormChange(self, fid):
if fid == self.iButton1.id:
print("Button1 fchg;inv=%s" % self.invert)
self.SetFocusedField(self.rNormal)
self.EnableField(self.rError, self.invert)
self.invert = not self.invert
elif fid == self.iButton2.id:
g1 = self.GetControlValue(self.cGroup1)
g2 = self.GetControlValue(self.cGroup2)
d = self.GetControlValue(self.iDir)
f = self.GetControlValue(self.iFileOpen)
print("cGroup2:%x;Dir=%s;fopen=%s;cGroup1:%x" % (g1, d, f, g2))
elif fid == self.cEChooser.id:
l = self.GetControlValue(self.cEChooser)
print("Chooser: %s" % l)
else:
print(">>fid:%d" % fid)
return 1
# --------------------------------------------------------------------------
def stdalone_main():
f = MyForm()
f, args = f.Compile()
print args[0]
print args[1:]
f.rNormal.checked = True
f.rWarnings.checked = True
print hex(f.cGroup1.value)
f.rGreen.selected = True
print f.cGroup2.value
print "Title: '%s'" % f.title
f.Free()
# --------------------------------------------------------------------------
def ida_main():
# Create form
global f
f = MyForm()
# Compile (in order to populate the controls)
f.Compile()
f.iColor1.value = 0x5bffff
f.iDir.value = os.getcwd()
f.rNormal.checked = True
f.rWarnings.checked = True
f.rGreen.selected = True
f.iStr1.value = "Hello"
f.iFileSave.value = "*.*"
f.iFileOpen.value = "*.*"
# Execute the form
ok = f.Execute()
print("r=%d" % ok)
if ok == 1:
print("f.str1=%s" % f.iStr1.value)
print("f.color1=%x" % f.iColor1.value)
print("f.openfile=%s" % f.iFileOpen.value)
print("f.savefile=%s" % f.iFileSave.value)
print("f.dir=%s" % f.iDir.value)
print("f.type=%s" % f.iType.value)
print("f.seg=%s" % f.iSegment.value)
print("f.rawhex=%x" % f.iRawHex.value)
print("f.char=%x" % f.iChar.value)
print("f.addr=%x" % f.iAddr.value)
print("f.cGroup1=%x" % f.cGroup1.value)
print("f.cGroup2=%x" % f.cGroup2.value)
sel = f.EChooser.GetEmbSelection()
if sel is None:
print("No selection")
else:
print("Selection: %s" % sel)
# Dispose the form
f.Free()
# --------------------------------------------------------------------------
def ida_main_legacy():
# Here we simply show how to use the old style form format using Python
# Sample form from kernwin.hpp
s = """Sample dialog box
This is sample dialog box for %A
using address %$
<~E~nter value:N:32:16::>
"""
# Use either StringArgument or NumericArgument to pass values to the function
num = Form.NumericArgument('N', value=123)
ok = idaapi.AskUsingForm(s,
Form.StringArgument("PyAskUsingForm").arg,
Form.NumericArgument('$', 0x401000).arg,
num.arg)
if ok == 1:
print("You entered: %x" % num.value)
# --------------------------------------------------------------------------
def test_multilinetext_legacy():
# Here we text the multi line text control in legacy mode
# Sample form from kernwin.hpp
s = """Sample dialog box
This is sample dialog box
<Enter multi line text:t40:80:50::>
"""
# Use either StringArgument or NumericArgument to pass values to the function
ti = textctrl_info_t("Some initial value")
ok = idaapi.AskUsingForm(s, pointer(c_void_p.from_address(ti.clink_ptr)))
if ok == 1:
print("You entered: %s" % ti.text)
del ti
# --------------------------------------------------------------------------
class MyForm2(Form):
"""Simple Form to test multilinetext and combo box controls"""
def __init__(self):
Form.__init__(self, r"""STARTITEM 0
BUTTON YES* Yeah
BUTTON NO Nope
BUTTON CANCEL NONE
Form Test
{FormChangeCb}
<Multilinetext:{txtMultiLineText}>
""", {
'txtMultiLineText': Form.MultiLineTextControl(text="Hello"),
'FormChangeCb': Form.FormChangeCb(self.OnFormChange),
})
def OnFormChange(self, fid):
if fid == self.txtMultiLineText.id:
pass
elif fid == -2:
ti = self.GetControlValue(self.txtMultiLineText)
print "ti.text = %s" % ti.text
else:
print(">>fid:%d" % fid)
return 1
# --------------------------------------------------------------------------
def test_multilinetext(execute=True):
"""Test the multilinetext and combobox controls"""
f = MyForm2()
f, args = f.Compile()
if execute:
ok = f.Execute()
else:
print args[0]
print args[1:]
ok = 0
if ok == 1:
assert f.txtMultiLineText.text == f.txtMultiLineText.value
print f.txtMultiLineText.text
f.Free()
# --------------------------------------------------------------------------
class MyForm3(Form):
"""Simple Form to test multilinetext and combo box controls"""
def __init__(self):
self.__n = 0
Form.__init__(self,
r"""BUTTON YES* Yeah
BUTTON NO Nope
BUTTON CANCEL NONE
Dropdown list test
{FormChangeCb}
<Dropdown list (readonly):{cbReadonly}> <Add element:{iButtonAddelement}> <Set index:{iButtonSetIndex}>
<Dropdown list (editable):{cbEditable}> <Set string:{iButtonSetString}>
""", {
'FormChangeCb': Form.FormChangeCb(self.OnFormChange),
'cbReadonly': Form.DropdownListControl(
items=["red", "green", "blue"],
readonly=True,
selval=1),
'cbEditable': Form.DropdownListControl(
items=["1MB", "2MB", "3MB", "4MB"],
readonly=False,
selval="4MB"),
'iButtonAddelement': Form.ButtonInput(self.OnButtonNop),
'iButtonSetIndex': Form.ButtonInput(self.OnButtonNop),
'iButtonSetString': Form.ButtonInput(self.OnButtonNop),
})
def OnButtonNop(self, code=0):
"""Do nothing, we will handle events in the form callback"""
pass
def OnFormChange(self, fid):
if fid == self.iButtonSetString.id:
s = idc.AskStr("none", "Enter value")
if s:
self.SetControlValue(self.cbEditable, s)
elif fid == self.iButtonSetIndex.id:
s = idc.AskStr("1", "Enter index value:")
if s:
try:
i = int(s)
except:
i = 0
self.SetControlValue(self.cbReadonly, i)
elif fid == self.iButtonAddelement.id:
# add a value to the string list
self.__n += 1
self.cbReadonly.add("some text #%d" % self.__n)
# Refresh the control
self.RefreshField(self.cbReadonly)
elif fid == -2:
s = self.GetControlValue(self.cbEditable)
print "user entered: %s" % s
sel_idx = self.GetControlValue(self.cbReadonly)
return 1
# --------------------------------------------------------------------------
def test_dropdown(execute=True):
"""Test the combobox controls, in a modal dialog"""
f = MyForm3()
f, args = f.Compile()
if execute:
ok = f.Execute()
else:
print args[0]
print args[1:]
ok = 0
if ok == 1:
print "Editable: %s" % f.cbEditable.value
print "Readonly: %s" % f.cbReadonly.value
f.Free()
# --------------------------------------------------------------------------
tdn_form = None
def test_dropdown_nomodal():
"""Test the combobox controls, in a non-modal form"""
global tdn_form
if tdn_form is None:
tdn_form = MyForm3()
tdn_form.modal = False
tdn_form.openform_flags = idaapi.PluginForm.FORM_TAB
tdn_form, _ = tdn_form.Compile()
tdn_form.Open()
#</pycode(ex_askusingform)>
# --------------------------------------------------------------------------
ida_main()

133
examples/ex_choose2.py Normal file
View File

@ -0,0 +1,133 @@
import idaapi
from idaapi import Choose2
#<pycode(py_choose2ex1)>
class chooser_handler_t(idaapi.action_handler_t):
def __init__(self, thing):
idaapi.action_handler_t.__init__(self)
self.thing = thing
def activate(self, ctx):
sel = []
for i in xrange(len(ctx.chooser_selection)):
sel.append(str(ctx.chooser_selection.at(i)))
print "command %s selected @ %s" % (self.thing, ", ".join(sel))
def update(self, ctx):
return idaapi.AST_ENABLE_FOR_FORM if idaapi.is_chooser_tform(ctx.form_type) else idaapi.AST_DISABLE_FOR_FORM
class MyChoose2(Choose2):
def __init__(self, title, nb = 5, flags=0, width=None, height=None, embedded=False, modal=False):
Choose2.__init__(
self,
title,
[ ["Address", 10], ["Name", 30] ],
flags = flags,
width = width,
height = height,
embedded = embedded)
self.n = 0
self.items = [ self.make_item() for x in xrange(0, nb+1) ]
self.icon = 5
self.selcount = 0
self.modal = modal
self.popup_names = ["Inzert", "Del leet", "Ehdeet", "Ree frech"]
print("created %s" % str(self))
def OnClose(self):
print "closed", str(self)
def OnEditLine(self, n):
self.items[n][1] = self.items[n][1] + "*"
print("editing %d" % n)
def OnInsertLine(self):
self.items.append(self.make_item())
print("insert line")
def OnSelectLine(self, n):
self.selcount += 1
Warning("[%02d] selectline '%s'" % (self.selcount, n))
def OnGetLine(self, n):
print("getline %d" % n)
return self.items[n]
def OnGetSize(self):
n = len(self.items)
print("getsize -> %d" % n)
return n
def OnDeleteLine(self, n):
print("del %d " % n)
del self.items[n]
return n
def OnRefresh(self, n):
print("refresh %d" % n)
return n
def OnGetIcon(self, n):
r = self.items[n]
t = self.icon + r[1].count("*")
print "geticon", n, t
return t
def show(self):
return self.Show(self.modal) >= 0
def make_item(self):
r = [str(self.n), "func_%04d" % self.n]
self.n += 1
return r
def OnGetLineAttr(self, n):
print("getlineattr %d" % n)
if n == 1:
return [0xFF0000, 0]
# -----------------------------------------------------------------------
def test_choose2(modal=False):
global c
c = MyChoose2("Choose2 - sample 1", nb=10, modal=modal)
r = c.show()
form = idaapi.get_current_tform()
for thing in ["A", "B"]:
idaapi.attach_action_to_popup(form, None, "choose2:act%s" % thing)
# -----------------------------------------------------------------------
def test_choose2_embedded():
global c
c = MyChoose2("Choose2 - embedded", nb=12, embedded = True, width=123, height=222)
r = c.Embedded()
if r == 1:
try:
if test_embedded:
o, sel = _idaapi.choose2_get_embedded(c)
print("o=%s, type(o)=%s" % (str(o), type(o)))
test_embedded(o)
finally:
c.Close()
# -----------------------------------------------------------------------
if __name__ == '__main__':
# Register actions
for thing in ["A", "B"]:
actname = "choose2:act%s" % thing
idaapi.register_action(
idaapi.action_desc_t(
actname,
"command %s" % thing,
chooser_handler_t(thing)))
#test_choose2_embedded()
test_choose2(False)
#</pycode(py_choose2ex1)>

100
examples/ex_cli.py Normal file
View File

@ -0,0 +1,100 @@
# -----------------------------------------------------------------------
# This is an example illustrating how to implement a CLI
# (c) Hex-Rays
#
from idaapi import NW_OPENIDB, NW_CLOSEIDB, NW_TERMIDA, NW_REMOVE, COLSTR, cli_t
#<pycode(ex_cli_ex1)>
class mycli_t(cli_t):
flags = 0
sname = "pycli"
lname = "Python CLI"
hint = "pycli hint"
def OnExecuteLine(self, line):
"""
The user pressed Enter. The CLI is free to execute the line immediately or ask for more lines.
This callback is mandatory.
@param line: typed line(s)
@return Boolean: True-executed line, False-ask for more lines
"""
print "OnExecute:", line
return True
def OnKeydown(self, line, x, sellen, vkey, shift):
"""
A keyboard key has been pressed
This is a generic callback and the CLI is free to do whatever it wants.
This callback is optional.
@param line: current input line
@param x: current x coordinate of the cursor
@param sellen: current selection length (usually 0)
@param vkey: virtual key code. if the key has been handled, it should be returned as zero
@param shift: shift state
@return:
None - Nothing was changed
tuple(line, x, sellen, vkey): if either of the input line or the x coordinate or the selection length has been modified.
It is possible to return a tuple with None elements to preserve old values. Example: tuple(new_line, None, None, None) or tuple(new_line)
"""
print "Onkeydown: line=%s x=%d sellen=%d vkey=%d shift=%d" % (line, x, sellen, vkey, shift)
return None
def OnCompleteLine(self, prefix, n, line, prefix_start):
"""
The user pressed Tab. Find a completion number N for prefix PREFIX
This callback is optional.
@param prefix: Line prefix at prefix_start (string)
@param n: completion number (int)
@param line: the current line (string)
@param prefix_start: the index where PREFIX starts in LINE (int)
@return: None if no completion could be generated otherwise a String with the completion suggestion
"""
print "OnCompleteLine: prefix=%s n=%d line=%s prefix_start=%d" % (prefix, n, line, prefix_start)
return None
#</pycode(ex_cli_ex1)>
# -----------------------------------------------------------------------
def nw_handler(code, old=0):
if code == NW_OPENIDB:
print "nw_handler(): installing CLI"
mycli.register()
elif code == NW_CLOSEIDB:
print "nw_handler(): removing CLI"
mycli.unregister()
elif code == NW_TERMIDA:
print "nw_handler(): uninstalled nw handler"
idaapi.notify_when(NW_TERMIDA | NW_OPENIDB | NW_CLOSEIDB | NW_REMOVE, nw_handler)
# -----------------------------------------------------------------------
# Already installed?
try:
mycli
# remove previous CLI
mycli.unregister()
del mycli
# remove previous handler
nw_handler(NW_TERMIDA)
except:
pass
finally:
mycli = mycli_t()
# register CLI
if mycli.register():
print "CLI installed"
# install new handler
idaapi.notify_when(NW_TERMIDA | NW_OPENIDB | NW_CLOSEIDB, nw_handler)
else:
del mycli
print "Failed to install CLI"

216
examples/ex_custdata.py Normal file
View File

@ -0,0 +1,216 @@
# -----------------------------------------------------------------------
# This is an example illustrating how to use custom data types in Python
# (c) Hex-Rays
#
from idaapi import data_type_t, data_format_t, NW_OPENIDB, NW_CLOSEIDB, NW_TERMIDA, NW_REMOVE, COLSTR
import struct
import ctypes
import platform
#<pycode(ex_custdata)>
# -----------------------------------------------------------------------
class pascal_data_type(data_type_t):
def __init__(self):
data_type_t.__init__(self, name="py_pascal_string",
value_size = 2, menu_name = "Pascal string",
asm_keyword = "pstr")
def calc_item_size(self, ea, maxsize):
# Custom data types may be used in structure definitions. If this case
# ea is a member id. Check for this situation and return 1
if _idaapi.is_member_id(ea):
return 1
# get the length byte
n = _idaapi.get_byte(ea)
# string too big?
if n > maxsize:
return 0
# ok, accept the string
return n + 1
class pascal_data_format(data_format_t):
FORMAT_NAME = "py_pascal_string_pstr"
def __init__(self):
data_format_t.__init__(self, name=pascal_data_format.FORMAT_NAME)
def printf(self, value, current_ea, operand_num, dtid):
# Take the length byte
n = ord(value[0])
o = ['"']
for ch in value[1:]:
b = ord(ch)
if b < 0x20 or b > 128:
o.append(r'\x%02x' % ord(ch))
else:
o.append(ch)
o.append('"')
return "".join(o)
# -----------------------------------------------------------------------
class simplevm_data_type(data_type_t):
ASM_KEYWORD = "svm_emit"
def __init__(self):
data_type_t.__init__(self,
name="py_simple_vm",
value_size = 1,
menu_name = "SimpleVM",
asm_keyword = simplevm_data_type.ASM_KEYWORD)
def calc_item_size(self, ea, maxsize):
if _idaapi.is_member_id(ea):
return 1
# get the opcode and see if it has an imm
n = 5 if (_idaapi.get_byte(ea) & 3) == 0 else 1
# string too big?
if n > maxsize:
return 0
# ok, accept
return n
class simplevm_data_format(data_format_t):
def __init__(self):
data_format_t.__init__(self,
name="py_simple_vm_format",
menu_name = "SimpleVM")
# Some tables for the disassembler
INST = {1: 'add', 2: 'mul', 3: 'sub', 4: 'xor', 5: 'mov'}
REGS = {1: 'r1', 2: 'r2', 3: 'r3'}
def disasm(self, inst):
"""A simple local disassembler. In reality one can use a full-blown disassembler to render the text"""
opbyte = ord(inst[0])
op = opbyte >> 4
if not (1<=op<=5):
return None
r1 = (opbyte & 0xf) >> 2
r2 = opbyte & 3
sz = 0
if r2 == 0:
if len(inst) != 5:
return None
imm = struct.unpack_from('L', inst, 1)[0]
sz = 5
else:
imm = None
sz = 1
text = "%s %s, %s" % (
COLSTR(simplevm_data_format.INST[op], idaapi.SCOLOR_INSN),
COLSTR(simplevm_data_format.REGS[r1], idaapi.SCOLOR_REG),
COLSTR("0x%08X" % imm, idaapi.SCOLOR_NUMBER) if imm is not None else COLSTR(simplevm_data_format.REGS[r2], idaapi.SCOLOR_REG))
return (sz, text)
def printf(self, value, current_ea, operand_num, dtid):
r = self.disasm(value)
if not r:
return None
if dtid == 0:
return "%s(%s)" % (simplevm_data_type.ASM_KEYWORD, r[1])
return r[1]
# -----------------------------------------------------------------------
# This format will display DWORD values as MAKE_DWORD(0xHI, 0xLO)
class makedword_data_format(data_format_t):
def __init__(self):
data_format_t.__init__(self,
name="py_makedword",
value_size = 4,
menu_name = "Make DWORD")
def printf(self, value, current_ea, operand_num, dtid):
if len(value) != 4: return None
w1 = struct.unpack_from("H", value, 0)[0]
w2 = struct.unpack_from("H", value, 2)[0]
return "MAKE_DWORD(0x%04X, 0x%04X)" % (w2, w1)
# -----------------------------------------------------------------------
# This format will try to load a resource string given a number
# So instead of displaying:
# push 66h
# call message_box_from_rsrc_string
# It can be rendered as;
# push RSRC("The message")
# call message_box_from_rsrc_string
#
# The get_rsrc_string() is not optimal since it loads/unloads the
# DLL each time for a new string. It can be improved in many ways.
class rsrc_string_format(data_format_t):
def __init__(self):
data_format_t.__init__(self,
name="py_w32rsrcstring",
value_size = 1,
menu_name = "Resource string")
self.cache_node = idaapi.netnode("$ py_w32rsrcstring", 0, 1)
def get_rsrc_string(self, fn, id):
"""
Simple method that loads the input file as a DLL with LOAD_LIBRARY_AS_DATAFILE flag.
It then tries to LoadString()
"""
k32 = ctypes.windll.kernel32
u32 = ctypes.windll.user32
hinst = k32.LoadLibraryExA(fn, 0, 0x2)
if hinst == 0:
return ""
buf = ctypes.create_string_buffer(1024)
r = u32.LoadStringA(hinst, id, buf, 1024-1)
k32.FreeLibrary(hinst)
return buf.value if r else ""
def printf(self, value, current_ea, operand_num, dtid):
# Is it already cached?
val = self.cache_node.supval(current_ea)
# Not cached?
if val == None:
# Retrieve it
num = idaapi.struct_unpack(value)
val = self.get_rsrc_string(idaapi.get_input_file_path(), num)
# Cache it
self.cache_node.supset(current_ea, val)
# Failed to retrieve?
if val == "" or val == "\x00":
return None
# Return the format
return "RSRC_STR(\"%s\")" % COLSTR(val, idaapi.SCOLOR_IMPNAME)
# -----------------------------------------------------------------------
# Table of formats and types to be registered/unregistered
# If a tuple has one element then it is the format to be registered with dtid=0
# If the tuple has more than one element, the tuple[0] is the data type and tuple[1:] are the data formats
new_formats = [
(pascal_data_type(), pascal_data_format()),
(simplevm_data_type(), simplevm_data_format()),
(makedword_data_format(),),
(simplevm_data_format(),)
]
if platform.system() == 'Windows':
new_formats.append((rsrc_string_format(),))
#</pycode(ex_custdata)>
# -----------------------------------------------------------------------
def nw_handler(code, old=0):
# delete notifications
if code == NW_OPENIDB:
idaapi.register_data_types_and_formats(new_formats)
elif code == NW_CLOSEIDB:
idaapi.unregister_data_types_and_formats(new_formats)
elif code == NW_TERMIDA:
idaapi.notify_when(NW_TERMIDA | NW_OPENIDB | NW_CLOSEIDB | NW_REMOVE, nw_handler)
# -----------------------------------------------------------------------
# Check if already installed
if idaapi.find_custom_data_type(pascal_data_format.FORMAT_NAME) == -1:
if not idaapi.register_data_types_and_formats(new_formats):
print "Failed to register types!"
else:
idaapi.notify_when(NW_TERMIDA | NW_OPENIDB | NW_CLOSEIDB, nw_handler)
print "Formats installed!"
else:
print "Formats already installed!"

183
examples/ex_custview.py Normal file
View File

@ -0,0 +1,183 @@
# -----------------------------------------------------------------------
# This is an example illustrating how to use customview in Python
# (c) Hex-Rays
#
import idaapi
import idc
from idaapi import simplecustviewer_t
#<pycode(py_custviewerex1)>
class say_something_handler_t(idaapi.action_handler_t):
def __init__(self, thing):
idaapi.action_handler_t.__init__(self)
self.thing = thing
def activate(self, ctx):
print self.thing
def update(self, ctx):
return idaapi.AST_ENABLE_ALWAYS
# -----------------------------------------------------------------------
class mycv_t(simplecustviewer_t):
def Create(self, sn=None):
# Form the title
title = "Simple custom view test"
if sn:
title += " %d" % sn
# Create the customviewer
if not simplecustviewer_t.Create(self, title):
return False
for i in xrange(0, 100):
self.AddLine("Line %d" % i)
# self.Jump(0)
return True
def OnClick(self, shift):
"""
User clicked in the view
@param shift: Shift flag
@return: Boolean. True if you handled the event
"""
print "OnClick, shift=%d" % shift
return True
def OnDblClick(self, shift):
"""
User dbl-clicked in the view
@param shift: Shift flag
@return: Boolean. True if you handled the event
"""
word = self.GetCurrentWord()
if not word: word = "<None>"
print "OnDblClick, shift=%d, current word=%s" % (shift, word)
return True
def OnCursorPosChanged(self):
"""
Cursor position changed.
@return: Nothing
"""
print "OnCurposChanged"
def OnClose(self):
"""
The view is closing. Use this event to cleanup.
@return: Nothing
"""
print "OnClose " + self.title
def OnKeydown(self, vkey, shift):
"""
User pressed a key
@param vkey: Virtual key code
@param shift: Shift flag
@return: Boolean. True if you handled the event
"""
print "OnKeydown, vk=%d shift=%d" % (vkey, shift)
# ESCAPE?
if vkey == 27:
self.Close()
# VK_DELETE
elif vkey == 46:
n = self.GetLineNo()
if n is not None:
self.DelLine(n)
self.Refresh()
print "Deleted line %d" % n
# Goto?
elif vkey == ord('G'):
n = self.GetLineNo()
if n is not None:
v = idc.AskLong(self.GetLineNo(), "Where to go?")
if v:
self.Jump(v, 0, 5)
elif vkey == ord('R'):
print "refreshing...."
self.Refresh()
elif vkey == ord('C'):
print "refreshing current line..."
self.RefreshCurrent()
elif vkey == ord('A'):
s = idc.AskStr("NewLine%d" % self.Count(), "Append new line")
self.AddLine(s)
self.Refresh()
elif vkey == ord('X'):
print "Clearing all lines"
self.ClearLines()
self.Refresh()
elif vkey == ord('I'):
n = self.GetLineNo()
s = idc.AskStr("InsertedLine%d" % n, "Insert new line")
self.InsertLine(n, s)
self.Refresh()
elif vkey == ord('E'):
l = self.GetCurrentLine(notags=1)
if not l:
return False
n = self.GetLineNo()
print "curline=<%s>" % l
l = l + idaapi.COLSTR("*", idaapi.SCOLOR_VOIDOP)
self.EditLine(n, l)
self.RefreshCurrent()
print "Edited line %d" % n
else:
return False
return True
def OnHint(self, lineno):
"""
Hint requested for the given line number.
@param lineno: The line number (zero based)
@return:
- tuple(number of important lines, hint string)
- None: if no hint available
"""
return (1, "OnHint, line=%d" % lineno)
# -----------------------------------------------------------------------
try:
# created already?
mycv
print "Already created, will close it..."
mycv.Close()
del mycv
except:
pass
def show_win():
x = mycv_t()
if not x.Create():
print "Failed to create!"
return None
x.Show()
tcc = x.GetTCustomControl()
# Register actions
for thing in ["Hello", "World"]:
actname = "custview:say_%s" % thing
idaapi.register_action(
idaapi.action_desc_t(actname, "Say %s" % thing, say_something_handler_t(thing)))
idaapi.attach_action_to_popup(tcc, None, actname)
return x
mycv = show_win()
if not mycv:
del mycv
def make_many(n):
L = []
for i in xrange(1, n+1):
v = mycv_t()
if not v.Create(i):
break
v.Show()
L.append(v)
return L
#</pycode(py_custviewerex1)>

34
examples/ex_dbg.py Normal file
View File

@ -0,0 +1,34 @@
from tempo import *;
def test_getmeminfo():
L = tempo.getmeminfo()
out = []
# startEA endEA name sclass sbase bitness perm
for (startEA, endEA, name, sclass, sbase, bitness, perm) in L:
out.append("%x: %x name=<%s> sclass=<%s> sbase=%x bitness=%2x perm=%2x" % (startEA, endEA, name, sclass, sbase, bitness, perm))
f = file(r"d:\temp\out.log", "w")
f.write("\n".join(out))
f.close()
print "dumped meminfo!"
def test_getregs():
# name flags class dtyp bit_strings bit_strings_default_mask
L = tempo.getregs()
out = []
for (name, flags, cls, dtype, bit_strings, bit_strings_default_mask) in L:
out.append("name=<%s> flags=%x class=%x dtype=%x bit_strings_mask=%x" % (name, flags, cls, dtype, bit_strings_default_mask))
if bit_strings:
for s in bit_strings:
out.append(" %s" % s)
f = file(r"d:\temp\out.log", "w")
f.write("\n".join(out))
f.close()
print "dumped regs!"

Some files were not shown because too many files have changed in this diff Show More