### Add 64-bit Conversion Capabilities to Plugins Source: https://github.com/idapython/src/blob/master/examples/index.md This example shows how to add 64-bit (.idb->.i64) conversion capabilities to custom plugins. Refer to the SDK/plugins/cvt64_sample example for more details. ```python # This is a placeholder for the py_cvt64_sample.py script. # The actual code would involve using IDA's API for database conversion. # Example usage might involve functions from ida_idaapi and ida_kernwin. # import ida_idaapi # import ida_kernwin # def run_cvt64(): # # Placeholder for conversion logic # print("64-bit conversion logic would go here.") # if __name__ == '__main__': # run_cvt64() ``` -------------------------------- ### Configuring and Installing SWIG on Linux/OSX Source: https://github.com/idapython/src/blob/master/BUILDING.txt Configure, compile, and install a specific version of SWIG on Linux or macOS. Ensure the --prefix points to your desired installation path. ```bash sh autogen.sh ./configure --prefix=/my_path_to/swig-4.0.1-py3-install && make && make install ``` -------------------------------- ### Install Hex-Rays Decompiler Hooks Source: https://context7.com/idapython/src/llms.txt Install custom hooks to receive notifications during decompilation. This example shows how to hook into maturity level changes and cursor position changes, and how to provide custom hints. ```python import ida_hexrays class DecompilerHooks(ida_hexrays.Hexrays_Hooks): def maturity(self, cfunc, maturity): # Called when decompilation reaches a new maturity level if maturity == ida_hexrays.CMAT_FINAL: print("Decompilation complete for %s" % cfunc.entry_ea) return 0 def create_hint(self, vd): # Provide custom tooltips in the decompiler window if vd.item.is_citem(): item = vd.item.it if item.op == ida_hexrays.cot_call: return (1, "==> Function call", 1) return (0, None, 0) def curpos(self, vd): # Called when cursor position changes in decompiler if vd.item.is_citem(): print("Cursor at item type: %s" % ida_hexrays.get_ctype_name(vd.item.it.op)) return 0 # Install hooks (requires Hex-Rays decompiler) if ida_hexrays.init_hexrays_plugin(): hooks = DecompilerHooks() hooks.hook() print("Decompiler hooks installed") ``` -------------------------------- ### Add Custom Command-Line Interpreter Source: https://github.com/idapython/src/blob/master/examples/index.md Demonstrates adding a custom command-line interpreter to IDA, including basic tab completion support. This example does not execute code but serves as a starting point. ```python import ida_idaapi import ida_kernwin class MyCLI(ida_kernwin.cli_t): def __init__(self): ida_kernwin.cli_t.__init__(self) def cmd(self, cmd): print(f"You entered: {cmd}") return 0 def get_completion(self, cmd_prefix): # Example: provide completions for 'help', 'exit', 'list' completions = ['help', 'exit', 'list'] return [c for c in completions if c.startswith(cmd_prefix)] # --- Main execution --- cli = MyCLI() # Register the CLI ida_kernwin.register_cli(cli) # Notify when IDA is terminating to unregister the CLI @ida_idaapi.notify_when(ida_idaapi.NW_TERMIDA) def cleanup(): ida_kernwin.unregister_cli(cli) print("Custom CLI unregistered.") print("Custom CLI registered. Type 'help', 'exit', or 'list' in the command line.") # To manually unregister: # ida_kernwin.unregister_cli(cli) ``` -------------------------------- ### Building IDAPython Plugin Source: https://github.com/idapython/src/blob/master/BUILDING.txt Execute the build script for IDAPython, specifying the SWIG home directory, whether to include Hex-Rays decompiler support, and the IDA installation path. ```bash python build.py --swig-home /my_path_to/swig-4.0.1-py3-install --with-hexrays --ida-install /path/to/ida_install/ ``` -------------------------------- ### Auto-Instantiate Custom Widgets Across Sessions in IDAPython Source: https://github.com/idapython/src/blob/master/examples/index.md Create and manage custom widgets that are automatically re-created at IDA startup or desktop load time. This example should be placed in the 'plugins' directory. ```python import ida_idaapi import ida_kernwin class MyWidget(ida_kernwin.simplecustviewer_t): def __init__(self, title): ida_kernwin.simplecustviewer_t.__init__(self, title) def Create(self, caption): return ida_kernwin.simplecustviewer_t.Create(self, caption) class MyPlugin(ida_idaapi.plugin_t): flags = ida_idaapi.PLUGIN_PROC comment = "Auto-instantiate widget plugin" help = "Auto-instantiate widget plugin" wanted_name = "AutoWidgetPlugin" wanted_hotkey = "" def init(self): # Register action to open the widget action_name = "my_widget_toggle" desc = ida_kernwin.action_desc_t( action_name, "Open/Close My Widget", MyActionHandler(), None, None, -1) ida_kernwin.register_action(desc) ida_kernwin.attach_action_to_menu( 'view\tOpen subviews\tMy Custom Widgets\t', action_name, ida_kernwin.SETMENU_APP) return ida_idaapi.PLUGIN_OK def run(self, arg): ida_kernwin.msg("Plugin run called. Use menu to toggle widget.\n") def term(self): ida_kernwin.msg("Plugin terminated.\n") class MyActionHandler(ida_kernwin.action_handler_t): def __init__(self): ida_kernwin.action_handler_t.__init__(self) self.widget = None def activate(self, ctx): if self.widget and self.widget.visible(): self.widget.Close(0) self.widget = None else: self.widget = MyWidget("My Custom Widget") if not self.widget.Create("My Custom Widget"): ida_kernwin.msg("Failed to create widget.\n") self.widget = None else: ida_kernwin.msg("Widget created.\n") return 1 def update(self, ctx): return ida_kernwin.AST_ENABLE_ALWAYS def PLUGIN_ENTRY(): return MyPlugin() ``` -------------------------------- ### Show Tabular Data with IDA's Choose Class Source: https://github.com/idapython/src/blob/master/examples/index.md Demonstrates subclassing `ida_kernwin.Choose` to display data in a table format. This example also shows how to register actions that can interact with the chooser. The `Choose` class supports features like editing, insertion, deletion, and refreshing. ```python import ida_kernwin class MyChooser(ida_kernwin.Choose): def __init__(self, title, items): self.title = title self.items = items # Define columns: header, type, width self.cols = [ ["Name", ida_kernwin.Choose.CHCOL_PLAIN, 200], ["Value", ida_kernwin.Choose.CHCOL_HEX, 100] ] # Set chooser flags (e.g., can edit, can delete) self.popup_names = ["Edit", "Delete"] self.flags = ida_kernwin.Choose.CH_CAN_EDIT | ida_kernwin.Choose.CH_CAN_DEL | ida_kernwin.Choose.CH_CAN_INS ida_kernwin.Choose.__init__(self, self.title, self.cols, self.flags) def OnGetLine(self, n): # Return the data for the nth row if n < len(self.items): return self.items[n] return None def OnInsertLine(self): # Handle insertion of a new row new_item = ["New Item", 0] self.items.append(new_item) return len(self.items) - 1 def OnEditLine(self, n): # Handle editing of the nth row if n < len(self.items): # In a real scenario, you'd use ask_str, ask_long, etc. print(f"Editing item {n}: {self.items[n]}") # Example: Update the item self.items[n][0] = "Edited Item" self.items[n][1] = 0x1234 return ida_kernwin.Choose.ALL_CHANGED return ida_kernwin.Choose.NOTHING_CHANGED def OnDelLine(self, n): # Handle deletion of the nth row if n < len(self.items): del self.items[n] return ida_kernwin.Choose.ALL_CHANGED return ida_kernwin.Choose.NOTHING_CHANGED def Show(self): # Show the chooser return ida_kernwin.Choose.Show(self) def main(): # Sample data data = [ ["Address", 0x1000], ["Size", 0x500], ["Flags", 0xABCDEF] ] chooser = MyChooser("My Data Viewer", data) chooser.Show() if __name__ == '__main__': main() ``` -------------------------------- ### Add Custom Menus to IDA Source: https://github.com/idapython/src/blob/master/examples/index.md Create custom menus and submenus in IDA's menubar using ida_kernwin.create_menu and ida_kernwin.attach_action_to_menu. This example focuses on menu creation, not context menus. ```python import ida_kernwin # Define an action ACTION_MY_MENU = "MyPlugin:MyAction" class MyActionHandler(ida_kernwin.action_handler_t): def __init__(self): ida_kernwin.action_handler_t.__init__(self) # Maybe set self.action = ACTION_MY_MENU def activate(self, ctx): print("My custom action activated!") return 0 def update(self, ctx): return ida_kernwin.AST_ENABLE_ALWAYS # Create the action handler handler = MyActionHandler() # Register the action accel = ida_kernwin.action_desc_t( ACTION_MY_MENU, "My Custom Action", # Action label handler, None, # Optional owner "Description of my action", # Tooltip None, # Optional icon None) # Optional hotkey ida_kernwin.register_action(accel) # Create a menu item and attach the action # This will create a top-level menu 'MyMenu' with a submenu 'SubMenu' # and add 'My Custom Action' to it. ida_kernwin.create_menu("MyMenu", "My Menu") ida_kernwin.create_menu("MyMenu.SubMenu", "&SubMenu", "MyMenu") ida_kernwin.attach_action_to_menu("MyMenu.SubMenu", ACTION_MY_MENU, ida_kernwin.SETMENU_INS) print("Custom menu added.") # To remove the menu and action: # ida_kernwin.delete_menu("MyMenu.SubMenu") # ida_kernwin.delete_menu("MyMenu") # ida_kernwin.unregister_action(ACTION_MY_MENU) ``` -------------------------------- ### Create Custom Actions with Icons and Tooltips in IDAPython Source: https://github.com/idapython/src/blob/master/examples/index.md Example of creating custom user actions that can be added to menus, toolbars, or context menus. Actions can have icons, tooltips, and dynamic availability controlled by an `update` callback. Requires registering and unregistering the action. ```python import ida_kernwin class MyActionHandler(ida_kernwin.action_handler_t): def __init__(self): ida_kernwin.action_handler_t.__init__(self) # TODO: Initialize your action here def activate(self, ctx): # TODO: Implement action activation logic print("My custom action activated!") return 0 def update(self, ctx): # TODO: Implement action update logic (e.g., enable/disable) return ida_kernwin.AST_ENABLE_ALWAYS # Action description MyActionDesc = ida_kernwin.action_desc_t( "my_custom_action.ida", # Action identifier "My Custom Action", # Action label MyActionHandler(), # Action handler object None, # Shortcut "This is a tooltip for my custom action", # Tooltip # Optional: Load custom icon # ida_kernwin.load_custom_icon("path/to/icon.png") ) def main(): # Register the action if ida_kernwin.register_action(MyActionDesc): print("Action registered successfully.") # Attach the action to a menu (e.g., Edit ->) ida_kernwin.attach_action_to_menu("edit_popup", "my_custom_action.ida NOTEXT") else: print("Failed to register action.") # To unregister later: # ida_kernwin.unregister_action("my_custom_action.ida") if __name__ == '__main__': main() ``` -------------------------------- ### Programmatically Drive Debugging Session Source: https://github.com/idapython/src/blob/master/examples/index.md Automates a debugging session by stepping through the first five instructions and disassembling each one after execution. This example utilizes DBG_Hooks for managing the debugging process. ```python import ida_dbg import ida_idaapi import ida_lines # TODO: Add example code here ``` -------------------------------- ### Add Custom Microcode Optimization Rule Source: https://github.com/idapython/src/blob/master/examples/index.md Installs a custom microcode optimization rule to transform 'x | ~x' into '-1'. Requires the 'be_ornot_be.idb' database to test. ```python import ida_hexrays import ida_idaapi class vds19_optinsn_t(ida_hexrays.optinsn_t): def __init__(self): super(vds19_optinsn_t, self).__init__() def is_applicable(self, mba): return mba.is_expr(ida_hexrays.m_or, ida_hexrays.m_bnot) def apply(self, mba): mba.op = ida_hexrays.m_mov mba.operands[0] = ida_hexrays.mop_prt(mba.operands[0]) mba.operands[1] = ida_hexrays.mop_prt(ida_hexrays.mop_num(0xFFFFFFFF, 8)) return True class vds19_plugin_t(ida_idaapi.plugin_t): flags = ida_idaapi.PLUGIN_KEEP comment = "Adds a custom microcode instruction optimization rule" help = "Transforms x | ~x into -1" wanted_name = "vds19" wanted_hotkey = "" def init(self): ida_hexrays.init_hexrays_plugin() ida_hexrays.register_optimizer(vds19_optinsn_t()) return ida_idaapi.PLUGIN_KEEP def run(self, arg): ida_idaapi.msg("This is a plugin, not an action. Please see help.\n") def term(self): pass def PLUGIN_ENTRY(): return vds19_plugin_t() ``` -------------------------------- ### Create Custom Viewer Listings in IDAPython Source: https://github.com/idapython/src/blob/master/examples/index.md Provides a foundation for creating custom listing widgets within IDA, sharing features with built-in widgets like highlighting and copy-paste. This example also demonstrates attaching actions to the custom viewer's context menu. ```python import ida_kernwin import ida_lines class MyCustomViewer(ida_kernwin.simplecustviewer_t): def __init__(self, title): ida_kernwin.simplecustviewer_t.__init__(self) self.title = title self.lines = [] def Create(self, title): return ida_kernwin.simplecustviewer_t.Create(self, title) def Show(self): return ida_kernwin.simplecustviewer_t.Show(self) def AddLine(self, line): self.lines.append(line) self.RefreshLines(len(self.lines) - 1, len(self.lines) - 1) def GetLineCount(self): return len(self.lines) def GetLine(self, n): if n < len(self.lines): return self.lines[n] return None def OnRefresh(self): # Called when the viewer needs to be refreshed pass def OnClose(self): # Called when the viewer is closed print("Custom viewer closed.") return 0 def OnDblClick(self, shift): # Handle double-click events print("Double clicked!") return 0 def OnKey(self, v): # Handle key press events if v == ida_kernwin.IK_DELETE: print("Delete key pressed.") return 1 # Indicate key was handled return 0 # Indicate key was not handled # Action handler for the custom viewer class MyViewerActionHandler(ida_kernwin.action_handler_t): def __init__(self, viewer): ida_kernwin.action_handler_t.__init__(self) self.viewer = viewer def activate(self, ctx): print("Action activated in custom viewer!") # Example: Add a new line self.viewer.AddLine("New line added by action") return 0 def update(self, ctx): return ida_kernwin.AST_ENABLE_ALWAYS def main(): viewer = MyCustomViewer("My Custom Listing") viewer.Create(viewer.title) # Add some initial lines with colors viewer.AddLine(ida_lines.COLSTR("Line 1: Default color", ida_lines.COLOR_DEFAULT)) viewer.AddLine(ida_lines.COLSTR("Line 2: Name color", ida_lines.COLOR_DNAME)) viewer.AddLine(ida_lines.COLSTR("Line 3: Custom color", ida_lines.SCOLOR_PREFIX | ida_lines.SCOLOR_VOIDOP)) # Register and attach an action action_handler = MyViewerActionHandler(viewer) action_desc = ida_kernwin.action_desc_t( "my_viewer.add_line", "Add Line", action_handler ) if ida_kernwin.register_action(action_desc): ida_kernwin.attach_action_to_popup(viewer.GetTWidget(), None, "my_viewer.add_line") print("Action attached to custom viewer popup.") viewer.Show() if __name__ == '__main__': main() ``` -------------------------------- ### Test cexpr_t refwidth property Source: https://github.com/idapython/src/blob/master/CONTRIBUTING.md This example demonstrates how to test the `refwidth` property of a `cexpr_t` instance, including setting and retrieving its value, and handling type errors. It simulates user interaction with IDAPython. ```python Python>x = cexpr_t() Python>x.refwidth 0 Python>x.refwidth = 18 Python>x.refwidth 18 Python>x.refwidth = var_ref_t() Traceback ( , , in , , in refwidth = property( lambda self: self._get_refwidth() if True else 0, lambda self, v: True and self._ensure_no_obj(self._get_refwidth(),"refwidth", False) and self._acquire_ownership(v, False) and self._set_refwidth(v)) , , in _set_refwidth return _ida_hexrays.cexpr_t__set_refwidth(self, *args) TypeError: in method 'cexpr_t__set_refwidth', argument 2 of type 'int' ``` -------------------------------- ### Save and Restore Listing Position Source: https://github.com/idapython/src/blob/master/examples/index.md Re-implements IDA's bookmark functionality by saving and restoring the current cursor position in a listing. This example remembers only one position and does not persist it across IDA sessions. ```Python save_and_restore_listing_pos.py ``` -------------------------------- ### Execute Code into Application (Linux) Source: https://github.com/idapython/src/blob/master/examples/index.md Shows how to use the ida_idd.Appcall utility to execute code within the process being debugged on Linux. This example involves running a test program and performing appcalls to specific functions. ```python import ida_dbg import ida_idaapi import ida_idd import ida_kernwin import ida_name import ida_typeinf # TODO: Add example code here ``` -------------------------------- ### Retrieve and Dump Current Selection Source: https://github.com/idapython/src/blob/master/examples/index.md Demonstrates how to get the current selection from IDA listing widgets (like Disassembly, Hex View, Pseudocode) and retrieve the corresponding text. Requires user interaction (selecting text and pressing a hotkey). ```python import ida_kernwin import ida_lines class DumpSelectionActionHandler(ida_kernwin.action_handler_t): def __init__(self): ida_kernwin.action_handler_t.__init__(self) def activate(self, ctx): widget = ida_kernwin.get_last_widget() if not widget: print("No active widget found.") return 0 # Check if the widget supports selection if not ida_kernwin.has_custom_viewer_data(widget, ida_kernwin.ACF_HAS_SELECTION): print("The current widget does not support selection.") return 0 # Get the selection start_line, end_line = ida_kernwin.read_selection(widget) if start_line is None or end_line is None: print("No text selected.") return 0 print(f"Selection range: Lines {start_line} to {end_line}") # Retrieve and print the text for each selected line # Note: This is a simplified example; actual text retrieval might be more complex # depending on the viewer type and content. for line_num in range(start_line, end_line + 1): line_info = ida_kernwin.line_info_t() if ida_kernwin.get_line_info(widget, line_num, line_info): print(f"Line {line_num}: {line_info.text}") else: print(f"Could not retrieve info for line {line_num}.") # Example of getting viewer user data (e.g., for Hex View) user_data = ida_kernwin.get_viewer_user_data(widget) if user_data: print(f"Viewer user data type: {type(user_data)}") return 1 def update(self, ctx): # Enable the action only if there's a widget with selection capability widget = ida_kernwin.get_last_widget() if widget and ida_kernwin.has_custom_viewer_data(widget, ida_kernwin.ACF_HAS_SELECTION): return ida_kernwin.AST_ENABLE_FOR_WIDGET return ida_kernwin.AST_DISABLE_FOR_WIDGET # --- Main execution --- action_name = "dump_selection:DumpSelectionAction" action_desc = ida_kernwin.action_desc_t( action_name, "Dump Selection", DumpSelectionActionHandler(), "Ctrl-Shift-S", # hotkey None, # icon ida_kernwin.AST_DISABLE_FOR_WIDGET # Initially disabled ) ida_kernwin.register_action(action_desc) print("Dump Selection action registered. Select text in a listing widget and press Ctrl+Shift+S.") # To unregister the action: # ida_kernwin.unregister_action(action_name) # print("Dump Selection action unregistered.") ``` -------------------------------- ### Load Type Library and Import Type Source: https://github.com/idapython/src/blob/master/examples/index.md Loads a specified type library file and then imports a type by name from it. Requires user input for the TIL file and type name. ```python import ida_kernwin import ida_typeinf def main(): til_path = ida_kernwin.ask_str("", 0, "Enter path to TIL file:") if not til_path: return if not ida_typeinf.load_til(til_path, ida_typeinf.NT_TYPE): ida_kernwin.msg("Failed to load TIL file: %s\n" % til_path) return type_name = ida_kernwin.ask_str("", 0, "Enter type name to import:") if not type_name: return tinfo = ida_typeinf.tinfo_t() if ida_typeinf.get_tinfo(tinfo, ida_typeinf.idc.get_name_ea(ida_typeinf.BADADDR), type_name): ida_typeinf.add_type(type_name, tinfo) ida_kernwin.msg("Successfully imported type: %s\n" % type_name) else: ida_kernwin.msg("Failed to import type: %s\n" % type_name) if __name__ == "__main__": main() ``` -------------------------------- ### List instruction registers Source: https://github.com/idapython/src/blob/master/examples/index.md Shows a list of direct references to a register from the current instruction. This example uses `ida_hexrays.gen_microcode` to obtain microcode information. ```python import ida_hexrays import ida_kernwin import ida_lines import ida_bytes import ida_funcs def get_register_references(): ea = ida_kernwin.get_screen_ea() func = ida_funcs.get_func(ea) if not func: ida_kernwin.warning("No function at current address") return if not ida_bytes.is_code(ida_bytes.get_flags(ea)): ida_kernwin.warning("Not a code address") return m = ida_hexrays.decompile(ea) if not m: ida_kernwin.warning("Failed to decompile function") return insn = m.get_insn(ea) if not insn: ida_kernwin.warning("Failed to get instruction at address") return gco = ida_hexrays.gco_info_t() gco.init(m, insn) gco.gtype = ida_hexrays.GC_REGS_AND_STKVARS if ida_hexrays.gen_microcode(gco) != ida_hexrays.MERR_OK: ida_kernwin.warning("Failed to generate microcode info") return for i in range(gco.regs_count()): reg_info = gco.regs(i) ida_kernwin.msg("Register: %s\n" % reg_info.name) for j in range(reg_info.refs_count()): ref = reg_info.refs(j) ida_lines.generate_disasm_line(ref.ea) # To run this, place the cursor on an instruction in the disassembly view # and execute this script. It will list registers used by that instruction. # You can also bind this function to a hotkey. ``` -------------------------------- ### Draw Custom Graphs with Actions Source: https://github.com/idapython/src/blob/master/examples/index.md Illustrates creating custom graphs using `ida_graph.GraphViewer` and implementing actions that can be performed on these graphs. ```python import ida_funcs import ida_graph import ida_idp import ida_kernwin import ida_ua import ida_xref class MyGraphViewer(ida_graph.GraphViewer): def __init__(self, title, graph_id): ida_graph.GraphViewer.__init__(self, title, graph_id) def OnRefresh(self): # Clear existing nodes and edges self.Clear() # Add nodes and edges based on some logic # For this example, let's just add a few dummy nodes node_id_1 = self.AddNode(0, "Node 1") node_id_2 = self.AddNode(1, "Node 2") node_id_3 = self.AddNode(2, "Node 3") self.AddEdge(node_id_1, node_id_2) self.AddEdge(node_id_2, node_id_3) return True def OnNodeClicked(self, node_id): print(f"Node clicked: {node_id}") # You can retrieve node data here if needed return True class MyGraphActionHandler(ida_kernwin.action_handler_t): def __init__(self, viewer_id): ida_kernwin.action_handler_t.__init__(self) self.viewer_id = viewer_id def activate(self, ctx): viewer = ida_graph.get_graph_viewer(self.viewer_id) if viewer: print(f"Action activated on viewer: {viewer.title()}") # Example: Refresh the graph viewer.Refresh() return 1 def update(self, ctx): return ida_kernwin.AST_ENABLE_ALWAYS # --- Main execution --- viewer_id = 1 # Unique ID for the graph viewer # Create and show the graph viewer viewer = MyGraphViewer("My Custom Graph", viewer_id) viewer.Show() # Register an action for the graph viewer action_name = "my_custom_graph:RefreshAction" action_desc = ida_kernwin.action_desc_t( action_name, "Refresh Custom Graph", MyGraphActionHandler(viewer_id), "Ctrl+Alt+R", # hotkey None, # icon 0 # flags ) ida_kernwin.register_action(action_desc) # Attach the action to the graph viewer's popup menu # Note: get_custom_viewer_location might need adjustment based on context # For simplicity, we'll assume it's a top-level viewer ida_kernwin.attach_dynamic_action_to_popup(viewer.viewer_id, "", action_name) print(f"Custom graph viewer '{viewer.title()}' created with ID {viewer_id}.") print(f"Action '{action_name}' registered and attached to popup.") # To unregister the action: # ida_kernwin.unregister_action(action_name) ``` -------------------------------- ### Get Numbered Type by Ordinal Source: https://github.com/idapython/src/blob/master/til_api_improvements.md Fetch a `tinfo_t` object for a numbered type using its ordinal with `til_t.get_numbered_type`. Returns `None` if the ordinal is invalid. ```python til_t.get_numbered_type(ordinal: int): tinfo_t | None ``` -------------------------------- ### Hook Operand Changes in IDA Source: https://github.com/idapython/src/blob/master/examples/index.md Notifies the user when an instruction's operand or a data item is modified. This example utilizes IDB_Hooks to intercept changes. ```python import ida_bytes import ida_idp import ida_nalt import ida_typeinf # Example of hooking operand changes # See examples/disassembler/operand_changed.py ``` -------------------------------- ### Produce C Listing for Entire File using IDAPython Source: https://github.com/idapython/src/blob/master/examples/index.md Automates IDA to perform auto-analysis and produce a .c file with decompilation of all functions. Run with `ida -A "-S...path/to/produce_c_file.py" `. ```python import ida_auto import ida_hexrays import ida_loader import ida_pro # This script produces a C listing for the entire file. # It automates IDA to perform auto-analysis on a file and, once that is done, # produce a .c file containing the decompilation of all the functions in that file. # Run like so: # ida -A "-S...path/to/produce_c_file.py" # where: # -A instructs IDA to run in non-interactive mode # -S holds a path to the script to run (note this is a single token; there is no space between '-S' and its path.) def main(): # Wait for IDA to finish the auto-analysis ida_auto.auto_wait() # Decompile all functions in the file ida_hexrays.decompile_many(0, ida_hexrays.VDRUN_MAYSTOP | ida_hexrays.VDRUN_NEWFILE | ida_hexrays.VDRUN_SILENT) # Get the path to the IDB file idb_path = ida_loader.get_path(ida_loader.PATH_TYPE_IDB) # Construct the output file path c_file_path = idb_path.replace(".idb", ".c") # Write the decompiled code to the output file with open(c_file_path, "w") as f: for func_ea in Functions(): cfunc = ida_hexrays.decompile(func_ea) if cfunc: f.write(str(cfunc.text)) f.write("\n") # Exit IDA ida_pro.qexit(0) if __name__ == "__main__": main() ``` -------------------------------- ### Get Named Type by Name Source: https://github.com/idapython/src/blob/master/til_api_improvements.md Retrieve a `tinfo_t` object for a specific named type from the type library using `til_t.get_named_type`. Returns `None` if the type is not found. ```python til_t.get_named_type(name: str) : tinfo_t | None ``` -------------------------------- ### Get Named Types from Type Library Source: https://github.com/idapython/src/blob/master/til_api_improvements.md Retrieve a generator for all named types in a type library using `til_t.named_types()`. Each iteration provides a new `tinfo_t` object. ```python til_t.named_types() : generator of tinfo_t ``` -------------------------------- ### Create a Type Library File with IDAPython Source: https://github.com/idapython/src/blob/master/examples/index.md Illustrates creating a new type library file (e.g., libssh2-64.til) containing specific structures. The created file can be placed in IDA's til directory. Requires the ida_typeinf module. ```python import ida_typeinf def create_libssh2_til_example(): # Example of creating a type library file # This is a placeholder and would contain actual IDA Python code pass create_libssh2_til_example() ``` -------------------------------- ### Print All Debugger Registers Source: https://context7.com/idapython/src/llms.txt Access and display register values for all threads in a debugged process using ida_idd.get_dbg() and ida_dbg.get_reg_vals(). This example registers an action to trigger the printing of registers. ```python import ida_idd import ida_dbg import ida_kernwin def print_all_registers(): print("=== Registers ===") dbg = ida_idd.get_dbg() # Iterate over all threads for tidx in range(ida_dbg.get_thread_qty()): tid = ida_dbg.getn_thread(tidx) print(" Thread #%d" % tid) # Get all register values for this thread regvals = ida_dbg.get_reg_vals(tid) for ridx, rv in enumerate(regvals): rinfo = dbg.regs(ridx) rval = rv.pyval(rinfo.dtype) if isinstance(rval, int): rval = "0x%x" % rval print(" %s: %s" % (rinfo.name, rval)) print("=== End of Registers ===") # Register as an action ACTION_NAME = "example:print_registers" class PrintRegistersHandler(ida_kernwin.action_handler_t): def activate(self, ctx): print_all_registers() return 1 def update(self, ctx): return ida_kernwin.AST_ENABLE_ALWAYS ida_kernwin.register_action(ida_kernwin.action_desc_t( ACTION_NAME, "Print Registers", PrintRegistersHandler(), "Alt+Shift+C")) ``` -------------------------------- ### Create Dockable Container with PyQt Widgets Source: https://github.com/idapython/src/blob/master/examples/index.md Convert IDA's dockable widget into a PyQt5-compatible widget using ida_kernwin.PluginForm.FormToPyQtWidget. This allows populating the container with standard Qt widgets. ```python import ida_kernwin from PyQt5 import QtWidgets class MyPluginForm(ida_kernwin.PluginForm): def OnCreate(self, form): self.parent = self.FormToPyQtWidget(form) self.populate_widgets() def populate_widgets(self): layout = QtWidgets.QVBoxLayout() label = QtWidgets.QLabel("Hello from PyQt!") button = QtWidgets.QPushButton("Click Me") layout.addWidget(label) layout.addWidget(button) self.parent.setLayout(layout) def OnClose(self, form): pass # To show the form: # MyPluginForm().Show("My PyQt Plugin") ``` -------------------------------- ### Get Numbered Types from Type Library Source: https://github.com/idapython/src/blob/master/til_api_improvements.md Obtain a generator for all numbered types within a type library using `til_t.numbered_types()`. Each iteration yields a fresh `tinfo_t` object. ```python til_t.numbered_types() : generator of tinfo_t ``` -------------------------------- ### Retrieve Selection from Strings Window Source: https://github.com/idapython/src/blob/master/examples/index.md Shows how to create actions that can retrieve string literal data from the 'Strings' window, either directly from the chooser or by querying the IDB. Useful for context-aware actions. ```Python show_selected_strings.py ``` -------------------------------- ### Get Innermost Structure Member - Python Source: https://github.com/idapython/src/blob/master/examples/index.md Demonstrates how to retrieve the 'innermost' member of a structure at a given offset, allowing you to 'drill down' into nested types. Useful for precise member identification. ```python import ida_typeinf def get_innermost_member(struct_name, offset): """ Retrieves the innermost member of a structure at a given offset. Args: struct_name (str): The name of the structure. offset (int): The byte offset within the structure. Returns: tuple: (member_name, member_offset, member_type_str) or None if not found. """ # First, parse the type declarations if they are not already known # This is a placeholder; in a real scenario, you'd ensure types 'a' and 'b' are defined. # ida_typeinf.parse_decls('struct b { int low; int high; }; struct a { int foo; b b_instance; int bar; };', True) tinfo = ida_typeinf.tinfo_t() if not ida_typeinf.get_tinfo(tinfo, struct_name): print(f"Structure '{struct_name}' not found. Ensure it is defined.") return None if not tinfo.is_struct() and not tinfo.is_union(): print(f"'{struct_name}' is not a structure or union.") return None # Get the innermost member information member_id = tinfo.get_innermost_member(offset) if member_id == ida_typeinf.BADADDR: print(f"No innermost member found at offset {offset} in '{struct_name}'.") return None # Retrieve member details member_info = ida_typeinf.member_info_t() if tinfo.get_member_by_id(member_info, member_id): member_name = member_info.name member_offset = member_info.soff member_type_str = member_info.type.dstr() return member_name, member_offset, member_type_str else: print(f"Failed to retrieve details for innermost member ID {member_id} in '{struct_name}'.") return None # Example usage: # Assuming 'a' and 'b' structs are defined as in the description: # result = get_innermost_member('a', 5) # if result: # name, off, type_str = result # print(f"Innermost member at offset 5 in 'a': {name} (Offset: {off}, Type: {type_str})") ``` -------------------------------- ### Add Custom Microcode Instruction Optimization Rule Source: https://github.com/idapython/src/blob/master/examples/index.md Installs a custom microcode instruction optimization rule to transform specific call patterns. Requires the 'arm64_brk.i64' file to observe the effect. ```python import ida_bytes import ida_hexrays import ida_idaapi import ida_typeinf class CustomMopOptimizer(ida_hexrays.optinsn_t): def __init__(self): ida_hexrays.optinsn_t.__init__(self) def is_applicable(self, mba): # Check if the instruction is a call to !DbgRaiseAssertionFailure if mba.op.get(0).type == ida_hexrays.mop_f仯: func_name = ida_hexrays.mop_str(mba.op.get(0)) if func_name == "!DbgRaiseAssertionFailure": return True return False def optimize(self, mba): # Transform the call to include a string argument # This is a simplified example; a real implementation would parse arguments # and potentially use ida_typeinf to construct the correct type. # Create a new mop for the string literal # In a real scenario, you'd likely want to add a string to the IDB # and reference it here. new_mop = ida_hexrays.mop_t(mba.mba.pool) new_mop.set_string("\"assertion text\"") # Replace the original operand with the new string operand mba.op.set(0, new_mop) # Mark the instruction as modified mba.mba.is_dirty = True return True class CustomOptimizerPlugin(ida_idaapi.plugin_t): flags = ida_idaapi.PLUGIN_HIDE | ida_idaapi.PLUGIN_KEEP comment = "Custom microcode instruction optimization rule" help = "Applies a custom optimization rule to !DbgRaiseAssertionFailure calls." wanted_name = "CustomOptimizer" wanted_hotkey = "" def init(self): ida_hexrays.init_hexrays_plugin() self.optimizer = CustomMopOptimizer() ida_hexrays.register_optimizer(self.optimizer) ida_kernwin.msg("Custom microcode optimizer installed.\n") return ida_idaapi.PLUGIN_KEEP def run(self, arg): ida_kernwin.msg("Custom microcode optimizer is already installed.\n") def term(self): if hasattr(self, 'optimizer'): ida_hexrays.unregister_optimizer(self.optimizer) ida_kernwin.msg("Custom microcode optimizer uninstalled.\n") def PLUGIN_ENTRY(): return CustomOptimizerPlugin() ``` -------------------------------- ### Implement Assembly for Pseudo Instructions Source: https://github.com/idapython/src/blob/master/examples/index.md Adds support for assembling pseudo instructions like 'zero eax' (xor eax, eax) and 'nothing' (nop) using IDP_Hooks. ```python import ida_idp import idautils class MyAssembler(ida_idp.IDP_Hooks): def __init__(self): ida_idp.IDP_Hooks.__init__(self) def assemble_custom_insn(self, opstr): # Check for pseudo instructions if opstr == "zero eax": # Assemble to 'xor eax, eax' return "xor eax, eax" elif opstr == "nothing": # Assemble to 'nop' return "nop" return None # Not a custom instruction # Install the hook hook = MyAssembler() hook.hook() # Example usage (in IDA's Python console): # print(ida_idp.assemble_custom_insn("zero eax")) # print(ida_idp.assemble_custom_insn("nothing")) # To uninstall: # hook.unhook() ``` -------------------------------- ### Create and Register Custom Action with Icon and Menu Source: https://context7.com/idapython/src/llms.txt Defines a custom action 'SayHi' that prints a message and context information. It registers the action, attaches it to a menu and toolbar, and hooks into context menus for broader usability. Ensure the action ID is unique. ```python import ida_kernwin class SayHi(ida_kernwin.action_handler_t): def __init__(self, message): ida_kernwin.action_handler_t.__init__(self) self.message = message def activate(self, ctx): # ctx provides context about where the action was triggered print("Hi, %s" % self.message) print(" cur_ea %08X" % ctx.cur_ea) print(" cur_value: %08X" % ctx.cur_value) print(" cur_extracted_ea %08X" % ctx.cur_extracted_ea) return 1 def update(self, ctx): # Only enable in disassembly views if ctx.widget_type == ida_kernwin.BWN_DISASM: return ida_kernwin.AST_ENABLE_FOR_WIDGET return ida_kernwin.AST_DISABLE_FOR_WIDGET act_name = "example:say_hi" # Register the action if ida_kernwin.register_action(ida_kernwin.action_desc_t( act_name, # Unique action ID "Say ~h~i!", # Label (~ marks accelerator key) SayHi("developer"), # Handler instance "Ctrl+F12", # Shortcut "Greets the user")): print("Action registered.") # Attach to menu ida_kernwin.attach_action_to_menu("Edit/Export data", act_name, ida_kernwin.SETMENU_APP) # Attach to toolbar ida_kernwin.attach_action_to_toolbar("AnalysisToolBar", act_name) # Hook to add action to context menus class Hooks(ida_kernwin.UI_Hooks): def finish_populating_widget_popup(self, widget, popup): if ida_kernwin.get_widget_type(widget) == ida_kernwin.BWN_DISASM: ida_kernwin.attach_action_to_popup(widget, popup, act_name, None) hooks = Hooks() hooks.hook() ``` -------------------------------- ### Override Function Chooser Colors Source: https://github.com/idapython/src/blob/master/examples/index.md Customize the coloring of functions in the IDA Functions window by overriding ida_kernwin.UI_Hooks.get_chooser_item_attrs. This example colors functions based on their size, with larger functions appearing darker. ```python import ida_funcs import ida_kernwin class MyChooserHook(ida_kernwin.UI_Hooks): def get_chooser_item_attrs(self, chooser_id, item_idx, attrs): if chooser_id == ida_kernwin.Chooser_funcs: # Get the function's start address func_ea = ida_funcs.get_func(ida_kernwin.get_screen_ea()) if func_ea: # Get function size fsize = ida_funcs.get_func(func_ea).size() # Calculate color based on size (e.g., scale from 0 to 255) # This is a simplified example; actual color mapping might need adjustment color_val = min(255, fsize // 100) # Example scaling color = (color_val << 16) | (color_val << 8) | color_val # Grayscale attrs.bgcolor = color return 0 # Return 0 to indicate success hook = MyChooserHook() # Enable the hook for the function chooser if hook.hook(): ida_kernwin.enable_chooser_item_attrs(ida_kernwin.Chooser_funcs, True) print("Function chooser coloring hook enabled.") else: print("Failed to enable function chooser coloring hook.") # To disable the hook: # ida_kernwin.enable_chooser_item_attrs(ida_kernwin.Chooser_funcs, False) # hook.unhook() ```