Skip to content

Commit

Permalink
Small fixes, updates plugin to v1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
gaasedelen committed Apr 24, 2020
1 parent d6cb766 commit 8ad9dc6
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 142 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2017 Andrew Marumoto, Markus Gaasedelen
Copyright (c) 2020 Andrew Marumoto, Markus Gaasedelen

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,21 @@ Prefix is a small function prefixing plugin for [IDA Pro](https://www.hex-rays.c

## Releases

* v1.2 -- Supoort IDA 7.0 -> 7.4, Python 2/3, deprecates IDA 6.x.
* v1.1 -- Added IDA 7 support.
* v1.0 -- Initial release

## Installation

Install Prefix into the IDA plugins folder.
Prefix is a cross-platform (Windows, macOS, Linux) Python 2/3 plugin. It takes zero third party dependencies, making the code both portable and easy to install.

- Copy the contents of the `plugin` folder to the IDA plugins folder
- On Windows, the folder is at `C:\Program Files (x86)\IDA 6.8\plugins`
- On MacOS, the folder is at `/Applications/IDA\ Pro\ 6.8/idaq.app/Contents/MacOS/plugins`
- On Linux, the folder may be at `/opt/IDA/plugins/`
1. From your disassembler's python console, run the following command to find its plugin directory:
- **IDA Pro**: `os.path.join(idaapi.get_user_idadir(), "plugins")`

The plugin is platform agnostic, but has only been tested on Windows for IDA 6.8 --> 7.0
2. Copy the contents of this repository's `/plugin/` folder to the listed directory.
3. Restart your disassembler.

This plugin is only supported for IDA 7.0 and newer.

## Usage

Expand Down
120 changes: 35 additions & 85 deletions plugin/ida_prefix.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
import idaapi
import idautils

from prefix.shims import *
from PyQt5 import QtGui, QtCore, QtWidgets

#------------------------------------------------------------------------------
# IDA Plugin
#------------------------------------------------------------------------------

VERSION = "v1.1.2"
VERSION = "v1.2"
AUTHORS = ['Andrew Marumoto', 'Markus Gaasedelen']

def PLUGIN_ENTRY():
Expand Down Expand Up @@ -195,18 +195,20 @@ def _del_action_recursive(self):

class Hooks(idaapi.UI_Hooks):

def finish_populating_widget_popup(self, widget, popup):
def ready_to_run(self):
"""
A right click menu is about to be shown. (IDA 7)
UI ready to run -- an IDA event fired when everything is spunup.
NOTE: this is a placeholder func, it gets replaced on a live instance
but we need it defined here for IDA 7.2+ to properly hook it.
"""
inject_prefix_actions(widget, popup, idaapi.get_widget_type(widget))
return 0
pass

def finish_populating_tform_popup(self, form, popup):
def finish_populating_widget_popup(self, widget, popup):
"""
A right click menu is about to be shown. (IDA 6.x)
A right click menu is about to be shown. (IDA 7)
"""
inject_prefix_actions(form, popup, idaapi.get_tform_type(form))
inject_prefix_actions(widget, popup, idaapi.get_widget_type(widget))
return 0

def hxe_callback(self, event, *args):
Expand Down Expand Up @@ -350,12 +352,8 @@ def recursive_prefix(addr):
idaapi.msg("Prefix: 0x%08X does not belong to a defined function\n" % addr)
return

# NOTE / COMPAT:
# prompt the user for a prefix to apply to the selected functions
if using_ida7api:
tag = idaapi.ask_str(PREFIX_DEFAULT, 0, "Function Tag")
else:
tag = idaapi.askstr(0, PREFIX_DEFAULT, "Function Tag")
tag = idaapi.ask_str(PREFIX_DEFAULT, 0, "Function Tag")

# the user closed the window... ignore
if tag == None:
Expand Down Expand Up @@ -392,12 +390,8 @@ def bulk_prefix():
Prefix the Functions window selection with a user defined string.
"""

# NOTE / COMPAT:
# prompt the user for a prefix to apply to the selected functions
if using_ida7api:
tag = idaapi.ask_str(PREFIX_DEFAULT, 0, "Function Tag")
else:
tag = idaapi.askstr(0, PREFIX_DEFAULT, "Function Tag")
tag = idaapi.ask_str(PREFIX_DEFAULT, 0, "Function Tag")

# the user closed the window... ignore
if tag == None:
Expand Down Expand Up @@ -470,14 +464,9 @@ def refresh_views():
# refresh IDA views
idaapi.refresh_idaview_anyway()

# NOTE/COMPAT: refresh hexrays view, if active
if using_ida7api:
current_widget = idaapi.get_current_widget()
vu = idaapi.get_widget_vdui(current_widget)
else:
current_tform = idaapi.get_current_tform()
vu = idaapi.get_tform_vdui(current_tform)

# refresh hexrays
current_widget = idaapi.get_current_widget()
vu = idaapi.get_widget_vdui(current_widget)
if vu:
vu.refresh_ctext()

Expand All @@ -493,16 +482,9 @@ def get_cursor_func_ref():
Returns BADADDR or a valid function address.
"""

# NOTE / COMPAT:
if using_ida7api:
current_widget = idaapi.get_current_widget()
form_type = idaapi.get_widget_type(current_widget)
vu = idaapi.get_widget_vdui(current_widget)
else:
current_tform = idaapi.get_current_tform()
form_type = idaapi.get_tform_type(current_tform)
vu = idaapi.get_tform_vdui(current_tform)
current_widget = idaapi.get_current_widget()
form_type = idaapi.get_widget_type(current_widget)
vu = idaapi.get_widget_vdui(current_widget)

#
# hexrays view is active
Expand All @@ -526,21 +508,11 @@ def get_cursor_func_ref():
# use that as a valid rename target
#

# NOTE/COMPAT:
if using_ida7api:
op_addr = idc.get_operand_value(cursor_addr, opnum)
else:
op_addr = idc.GetOperandValue(cursor_addr, opnum)

op_addr = idc.get_operand_value(cursor_addr, opnum)
op_func = idaapi.get_func(op_addr)

# NOTE/COMPAT:
if using_ida7api:
if op_func and op_func.start_ea == op_addr:
return op_addr
else:
if op_func and op_func.startEA == op_addr:
return op_addr
if op_func and op_func.start_ea == op_addr:
return op_addr

# unsupported/unknown view is active
else:
Expand All @@ -552,14 +524,8 @@ def get_cursor_func_ref():
#

cursor_func = idaapi.get_func(cursor_addr)

# NOTE/COMPAT:
if using_ida7api:
if cursor_func and cursor_func.start_ea == cursor_addr:
return cursor_addr
else:
if cursor_func and cursor_func.startEA == cursor_addr:
return cursor_addr
if cursor_func and cursor_func.start_ea == cursor_addr:
return cursor_addr

# fail
return idaapi.BADADDR
Expand All @@ -568,18 +534,9 @@ def get_selected_funcs():
"""
Return the list of function names selected in the Functions window.
"""

# NOTE / COMPAT:
if using_ida7api:
import sip
twidget = idaapi.find_widget("Functions window")
widget = sip.wrapinstance(long(twidget), QtWidgets.QWidget) # NOTE: LOL
else:
tform = idaapi.find_tform("Functions window")
if using_pyqt5:
widget = idaapi.PluginForm.FormToPyQtWidget(tform)
else:
widget = idaapi.PluginForm.FormToPySideWidget(tform)
import sip
twidget = idaapi.find_widget("Functions window")
widget = sip.wrapinstance(int(twidget), QtWidgets.QWidget)

# TODO: test this
if not widget:
Expand Down Expand Up @@ -663,20 +620,13 @@ def graph_down(ea, path=set()):
instruction_info = idaapi.insn_t()
for address in idautils.FuncItems(ea):

# NOTE / COMPAT:
if using_ida7api:

# decode the instruction
if not idaapi.decode_insn(instruction_info, address):
continue

# check if this instruction is a call
if not idaapi.is_call_insn(instruction_info):
continue
# decode the instruction
if not idaapi.decode_insn(instruction_info, address):
continue

else:
if not idaapi.is_call_insn(address):
continue
# check if this instruction is a call
if not idaapi.is_call_insn(instruction_info):
continue

# save this address as a call instruction
call_instructions.append(address)
Expand All @@ -690,9 +640,9 @@ def graph_down(ea, path=set()):

# TODO
for r in idautils.XrefsFrom(x, idaapi.XREF_FAR):
#print "0x%08X" % h, "--calls-->", "0x%08X" % r.to
#print(0x%08X" % h, "--calls-->", "0x%08X" % r.to)
if not r.iscode:
continue
continue

# get the function pointed at by this call
func = idaapi.get_func(r.to)
Expand Down
50 changes: 0 additions & 50 deletions plugin/prefix/shims.py

This file was deleted.

0 comments on commit 8ad9dc6

Please sign in to comment.