Skip to content

Commit

Permalink
Python3 first version
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrea Marcelli committed Feb 10, 2020
1 parent 97eef30 commit ffa6023
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 68 deletions.
17 changes: 9 additions & 8 deletions ghida.py
Original file line number Diff line number Diff line change
Expand Up @@ -623,14 +623,14 @@ def update(self, ctx):

class DisasmsHooks(idaapi.UI_Hooks):

def finish_populating_tform_popup(self, form, popup):
def finish_populating_widget_popup(self, form, popup):
# TODO - Attach to the functions view.
# if idaapi.get_tform_type(form) == idaapi.BWN_FUNCS:
# if idaapi.get_widget_type(form) == idaapi.BWN_FUNCS:
# idaapi.attach_action_to_popup(
# form, popup, "my:disasmsaction", None)

# Attach to the disassembler view only
if idaapi.get_tform_type(form) == idaapi.BWN_DISASMS:
if idaapi.get_widget_type(form) == idaapi.BWN_DISASMS:
idaapi.attach_action_to_popup(
form, popup, "my:disasmsaction", None)
idaapi.attach_action_to_popup(
Expand All @@ -647,7 +647,7 @@ def register_handlers():

# Load a custom icon
icon_path = gl.plugin_resource("ghida.png")
icon_data = str(open(icon_path, "rb").read())
icon_data = open(icon_path, "rb").read()
icon_ghida = idaapi.load_custom_icon(data=icon_data)

idaapi.register_action(idaapi.action_desc_t(
Expand Down Expand Up @@ -728,7 +728,7 @@ def load_configuration():
print("GHIDA_CONF.load_save_cached_comments",
GHIDA_CONF.load_save_cached_comments)

md5 = idautils.GetInputFileMD5()
md5 = idautils.GetInputFileMD5().hex()

# Initalize the cache (and load cached objects)
DECOMPILED_CACHE = gl.DecompiledCache(
Expand All @@ -752,7 +752,7 @@ def register_actions_and_handlers_decompile_view():
"""
# Load a custom icon
icon_path = gl.plugin_resource("ghida.png")
icon_data = str(open(icon_path, "rb").read())
icon_data = open(icon_path, "rb").read()
icon_ghida = idaapi.load_custom_icon(data=icon_data)

decompiler_widget = idaapi.find_widget('Decompiled Function')
Expand Down Expand Up @@ -893,7 +893,8 @@ def decompile_function_wrapper(cache_only=False, do_show=True):
# Check if the program has been rebased
if GHIDA_CONF.image_base != image_base:
print(
"GhIDA:: [DEBUG] program has been rebased. Invalidating caches.")
"GhIDA:: [DEBUG] program has been rebased. "
"Invalidating caches.")
DECOMPILED_CACHE.invalidate_cache()
COMMENTS_CACHE.invalidate_cache()
gl.force_export_XML_file()
Expand Down Expand Up @@ -976,11 +977,11 @@ def decompile_function_wrapper(cache_only=False, do_show=True):
print("GhIDA:: [!] Decompilation wrapper error")
idaapi.warning("GhIDA decompilation wrapper error")


# ------------------------------------------------------------
# GHIDRA DECOMPILER PLUGIN
# ------------------------------------------------------------


class GhIDADecompiler_t(idaapi.plugin_t):
comment = "GhIDA Decompiler for IDA Pro"
help = "GhIDA Decompiler shortcut key is Ctrl-Alt-D"
Expand Down
16 changes: 8 additions & 8 deletions ghida_plugin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@

ghida_vv = "0.1"

from comments_cache import *
from config import *
from constants import *
from decompiled_cache import *
from idaxml import SYMBLE_TABLE_DICT
from lib import *
from ui import *
from utility import *
from .comments_cache import *
from .config import *
from .constants import *
from .decompiled_cache import *
from .idaxml import SYMBLE_TABLE_DICT
from .lib import *
from .ui import *
from .utility import *

SYMBLE_TABLE_DICT = dict()
70 changes: 40 additions & 30 deletions ghida_plugin/idaxml.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@
import idc
import datetime
import os
import sys
import time

from xml.etree import cElementTree


Expand Down Expand Up @@ -242,7 +244,7 @@ def __init__(self, arg):
self.inf = ida_idaapi.get_inf_structure()
self.min_ea = self.inf.min_ea
self.max_ea = self.inf.max_ea
self.cbsize = (ida_idp.ph_get_cnbits() + 7) / 8
self.cbsize = int((ida_idp.ph_get_cnbits() + 7) / 8)
self.processor = str.upper(ida_idp.get_idp_name())
self.batch = ida_kernwin.cvar.batch

Expand All @@ -266,7 +268,7 @@ def export_xml(self, filename):
idc.msg("\n------------------------------------------------" +
"-----------")
idc.msg("\nExporting XML <PROGRAM> document ....")
begin = time.clock()
begin = time.time()

self.write_xml_declaration()
ret_val = self.export_program()
Expand Down Expand Up @@ -462,7 +464,7 @@ def display_cpu_time(self, start):
Args:
start: Floating-point value representing start time in seconds.
"""
idc.msg('CPU time: %6.4f' % (time.clock() - start))
idc.msg('CPU time: %6.4f' % (time.time() - start))

def end_element(self, tag, newline=True):
"""
Expand Down Expand Up @@ -510,7 +512,7 @@ def export_bookmarks(self):
Exports marked location descriptions as BOOKMARK elements.
"""
found = False
timer = time.clock()
timer = time.time()
for slot in range(0, 1025):
address = idc.get_bookmark(slot)
description = idc.get_bookmark_desc(slot)
Expand Down Expand Up @@ -571,7 +573,7 @@ def export_code(self):
if (addr == BADADDR):
return
self.update_status(CODE)
timer = time.clock()
timer = time.time()
data = ida_bytes.next_that(addr, self.max_ea, idc.is_data)
unknown = ida_bytes.next_unknown(addr, self.max_ea)
self.start_element(CODE, True)
Expand Down Expand Up @@ -641,7 +643,7 @@ def export_comments(self):
if (addr == BADADDR):
return
self.update_status(COMMENTS)
timer = time.clock()
timer = time.time()
self.start_element(COMMENTS, True)
while (addr != BADADDR):
cmt = idc.get_cmt(addr, False)
Expand Down Expand Up @@ -677,7 +679,7 @@ def export_data(self):
addr = ida_bytes.next_that(addr, self.max_ea, idc.is_data)
if (addr == BADADDR):
return
timer = time.clock()
timer = time.time()
self.update_status(DATA)
self.start_element(DATA, True)
while (addr != BADADDR):
Expand Down Expand Up @@ -730,7 +732,7 @@ def export_datatypes(self):
if idc.get_struc_qty() == 0:
return
self.update_status(DATATYPES)
timer = time.clock()
timer = time.time()
self.start_element(DATATYPES, True)
self.export_structures()
self.export_enums()
Expand Down Expand Up @@ -927,7 +929,7 @@ def export_functions(self):
if functions == None:
return
self.update_status(FUNCTIONS)
timer = time.clock()
timer = time.time()
self.start_element(FUNCTIONS, True)
for addr in functions:
function = ida_funcs.get_func(addr)
Expand Down Expand Up @@ -1013,7 +1015,7 @@ def export_markup(self):
and manual instructions and operands.
"""
self.update_status(MARKUP)
timer = time.clock()
timer = time.time()
self.start_element(MARKUP, True)
addr = self.min_ea
while addr != BADADDR:
Expand Down Expand Up @@ -1124,6 +1126,7 @@ def export_memory_contents(self, binfilename, binfile, start, end):
if ((has_val == False) or (next_address != addr + 1) or
(next_address == end)):
if length > 0:
length = int(length)
offset = binfile.tell()
ida_loader.base2file(binfile.get_fp(), offset, startaddr,
startaddr + length)
Expand All @@ -1147,7 +1150,7 @@ def export_memory_map(self):
if (nsegs == 0):
return
self.update_status(MEMORY_MAP)
timer = time.clock()
timer = time.time()
binfilename = ''
if (self.options.MemoryContent.checked == True):
(binfilename, ext) = os.path.splitext(self.filename)
Expand Down Expand Up @@ -1178,9 +1181,9 @@ def export_memory_reference(self, addr, op):
elif idc.is_code(f) == True:
insn = ida_ua.insn_t()
ida_ua.decode_insn(insn, addr)
target = insn.ops[op].value - ri.tdelta + ri.base
target = (insn.ops[op].value - ri.tdelta + ri.base) & ((1 << 64) - 1)
elif idc.is_data(f) == True:
target = self.get_data_value(addr) - ri.tdelta + ri.base
target = (self.get_data_value(addr) - ri.tdelta + ri.base) & ((1 << 64) - 1)
else:
return
else:
Expand Down Expand Up @@ -1221,6 +1224,8 @@ def export_memory_section(self, seg, binfilename):
self.write_attribute(NAME, segname)
self.write_address_attribute(START_ADDR, seg.start_ea)
length = (seg.end_ea - seg.start_ea) * self.cbsize

length = int(length)
self.write_numeric_attribute(LENGTH, length)
perms = ""
if (seg.perm != 0):
Expand All @@ -1247,7 +1252,7 @@ def export_program(self):
"""
# output the PROGRAM element
self.update_status(PROGRAM)
timer = time.clock()
timer = time.time()
self.start_element(PROGRAM)
self.write_attribute(NAME, idc.get_root_filename())
self.write_attribute(EXE_PATH, idc.get_input_file_path())
Expand All @@ -1257,7 +1262,7 @@ def export_program(self):
# check for presence of INPUT_MD5 netnode
md5 = ida_netnode.netnode(INPUT_MD5)
if md5 == BADNODE:
input_md5 = idc.retrieve_input_file_md5()
input_md5 = idc.retrieve_input_file_md5().hex()
else:
input_md5 = md5.supval(ida_nalt.RIDX_MD5)
if input_md5 != None:
Expand Down Expand Up @@ -1390,7 +1395,7 @@ def export_program_entry_points(self):
if (nepts == 0):
return
self.update_status(PROGRAM_ENTRY_POINTS)
timer = time.clock()
timer = time.time()
self.start_element(PROGRAM_ENTRY_POINTS, True)
for i in range(nepts):
self.start_element(PROGRAM_ENTRY_POINT)
Expand All @@ -1415,7 +1420,7 @@ def export_register_values(self):
if has_segregareas == False:
return
self.update_status(REGISTER_VALUES)
timer = time.clock()
timer = time.time()
self.start_element(REGISTER_VALUES, True)
sr = ida_segregs.sreg_range_t()
for j in range(first, last):
Expand Down Expand Up @@ -1651,7 +1656,7 @@ def export_symbol_table(self):
return
self.update_status(SYMBOL_TABLE)
self.start_element(SYMBOL_TABLE, True)
timer = time.clock()
timer = time.time()
while addr != BADADDR:
# only export meaningful names (user and auto)
f = idc.get_full_flags(addr)
Expand Down Expand Up @@ -1680,8 +1685,9 @@ def export_typeinfo_cmt(self, cmt):
cmt: String containing type info.
"""
# older versions of IDAPython returned a '\n' at end of cmt
while cmt[-1] == '\n':
cmt = cmt[:-1]
if(len(cmt) > 0):
while cmt[-1] == '\n':
cmt = cmt[:-1]
self.write_comment_element(TYPEINFO_CMT, cmt)

def export_user_memory_reference(self, addr):
Expand Down Expand Up @@ -2307,13 +2313,13 @@ def import_xml(self):
if event in self.callbacks:
if element.tag in self.callbacks[event]:
if event == 'start':
self.timers[element.tag] = time.clock()
self.timers[element.tag] = time.time()
self.callbacks[event][element.tag](element)
if event == 'end':
element.clear()
if event == 'end':
n += 1
end = time.clock()
end = time.time()
ida_kernwin.hide_wait_box()
self.display_summary('Import' if self.plugin else "Load")
idc.msg('\nXML Elements parsed: ' + str(n) + '\n\n')
Expand Down Expand Up @@ -2391,7 +2397,7 @@ def display_timer(self, element):
return
if element.tag in self.timers:
idc.msg('elapsed time: %.4f' %
(time.clock() - self.timers[element.tag]))
(time.time() - self.timers[element.tag]))

def display_total_time(self, element):
"""
Expand All @@ -2402,7 +2408,7 @@ def display_total_time(self, element):
"""
TOTAL = 'Total '
idc.msg('\n%35selapsed time: %.4f' %
(TOTAL, time.clock() - self.timers[PROGRAM]))
(TOTAL, time.time() - self.timers[PROGRAM]))

def get_address(self, element, attr):
"""
Expand Down Expand Up @@ -2473,7 +2479,7 @@ def get_cbsize(self):
Integer representing the number of 8-bit bytes in an
addressable codebyte.
"""
return (ida_idp.ph_get_cnbits() + 7) / 8
return int((ida_idp.ph_get_cnbits() + 7) / 8)

def get_datatype_flags(self, datatype, size):
"""
Expand Down Expand Up @@ -2675,7 +2681,9 @@ def import_bookmark(self, bookmark):
break
except:
msg = "** Exception occurred in import_bookmark **"
print("\n" + msg + "\n", sys.exc_type, sys.exc_value)
print(msg)
excinfo = sys.exc_info()
print(excinfo)

def import_cmts(self, element, sid, typ):
"""
Expand Down Expand Up @@ -3003,7 +3011,9 @@ def import_function(self, function):
self.import_register_var(register_var, func)
except:
msg = "** Exception occurred in import_function **"
print("\n" + msg + "\n", sys.exc_type, sys.exc_value)
print(msg)
excinfo = sys.exc_info()
print(excinfo)

def import_function_def(self, function_def):
# import_function_def: NOT IMPLEMENTED
Expand Down Expand Up @@ -3466,7 +3476,7 @@ def import_structure(self, structure):
if self.has_attribute(structure, NAMESPACE) == False:
return
namespace = self.get_attribute(structure, NAMESPACE)
name = namspace + '__' + name
name = namespace + '__' + name
name.replace('/', '_')
name.replace('.', '_')
dtyp = idc.get_struc_id(name)
Expand Down Expand Up @@ -3535,7 +3545,7 @@ def import_union(self, union):
if self.has_attribute(union, NAMESPACE) == False:
return
namespace = self.get_attribute(union, NAMESPACE)
name = namspace + '__' + name
name = namespace + '__' + name
name.replace('/', '_')
name.replace('.', '_')
dtyp = idc.get_struc_id(name)
Expand Down Expand Up @@ -3703,4 +3713,4 @@ def update_import(self, element):
USER_DEFINED = 'USER_DEFINED'
VALUE = 'VALUE'
VARIABLE_LENGTH = 'VARIABLE_LENGTH'
ZERO_PAD = 'ZERO_PAD'
ZERO_PAD = 'ZERO_PAD'
Loading

0 comments on commit ffa6023

Please sign in to comment.