├── __init__.py ├── ui ├── __init__.py ├── mk.py ├── warning.ui ├── elf.ui ├── selectName.ui ├── CMD.ui ├── emulate.ui ├── trace.ui ├── traceDump.ui ├── offset.ui ├── ea_view.ui ├── heap.ui └── restyle.ui ├── .gitignore ├── arrow.png ├── screens ├── cmd.png ├── cmd2.png ├── emu.png ├── heap.png ├── trace.png ├── view.png ├── view2.png ├── screen.png ├── screen3.png ├── trace10.png ├── trace2.png ├── trace4.png ├── trace5.png ├── trace6.png ├── trace7.png ├── trace8.png └── trace9.png ├── ea_main.py ├── chunk_template.html ├── ea_read_t.py ├── get_offsets.py ├── README.md ├── api_funcs.py ├── style_template.css ├── ea_trace.py ├── ea_cmd.py ├── ea_skin.py ├── ea_emu_client.py ├── ea_view.py ├── ea_emu_server.py ├── ea_utils.py ├── ea_heap.py └── ea_UI.py /__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.pyc 3 | *.ui_out 4 | config.json 5 | .idea -------------------------------------------------------------------------------- /arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/arrow.png -------------------------------------------------------------------------------- /screens/cmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/screens/cmd.png -------------------------------------------------------------------------------- /screens/cmd2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/screens/cmd2.png -------------------------------------------------------------------------------- /screens/emu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/screens/emu.png -------------------------------------------------------------------------------- /screens/heap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/screens/heap.png -------------------------------------------------------------------------------- /screens/trace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/screens/trace.png -------------------------------------------------------------------------------- /screens/view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/screens/view.png -------------------------------------------------------------------------------- /screens/view2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/screens/view2.png -------------------------------------------------------------------------------- /screens/screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/screens/screen.png -------------------------------------------------------------------------------- /screens/screen3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/screens/screen3.png -------------------------------------------------------------------------------- /screens/trace10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/screens/trace10.png -------------------------------------------------------------------------------- /screens/trace2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/screens/trace2.png -------------------------------------------------------------------------------- /screens/trace4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/screens/trace4.png -------------------------------------------------------------------------------- /screens/trace5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/screens/trace5.png -------------------------------------------------------------------------------- /screens/trace6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/screens/trace6.png -------------------------------------------------------------------------------- /screens/trace7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/screens/trace7.png -------------------------------------------------------------------------------- /screens/trace8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/screens/trace8.png -------------------------------------------------------------------------------- /screens/trace9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1111joe1111/ida_ea/HEAD/screens/trace9.png -------------------------------------------------------------------------------- /ui/mk.py: -------------------------------------------------------------------------------- 1 | from pysideuic import compileUi 2 | 3 | 4 | with open(r"./warning.ui", "r") as r: 5 | with open("out.ui_out", "w") as w: 6 | compileUi(r, w) 7 | 8 | quit() -------------------------------------------------------------------------------- /ea_main.py: -------------------------------------------------------------------------------- 1 | from ea_cmd import ea_cmd 2 | from ea_emu_client import ea_emulate 3 | from ea_heap import ea_heap 4 | from ea_skin import apply_skin, ea_reskin 5 | from ea_trace import ea_trace 6 | from ea_utils import QtWidgets, config 7 | from ea_view import ea_view 8 | 9 | if config["apply_skin_on_startup"]: 10 | apply_skin(init=True) 11 | # apply_initial_skin() 12 | 13 | menu_bar = next(i for i in QtWidgets.qApp.allWidgets() if isinstance(i, QtWidgets.QMenuBar)) 14 | menu = menu_bar.addMenu("IDA EA") 15 | menu.addAction("Viewer").triggered.connect(ea_view) 16 | menu.addAction("Heap").triggered.connect(ea_heap) 17 | menu.addAction("Emulate").triggered.connect(ea_emulate) 18 | menu.addAction("Trace Dump").triggered.connect(ea_trace) 19 | menu.addAction("CMD").triggered.connect(ea_cmd) 20 | menu.addAction("Reskin").triggered.connect(ea_reskin) 21 | -------------------------------------------------------------------------------- /ui/warning.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 328 10 | 47 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /ui/elf.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 328 10 | 60 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 | Executable must be ELF fomat (glibc) 21 | 22 | 23 | 24 | 25 | 26 | 27 | OK 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /chunk_template.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
address%s
prev_size%s
size%s
fd%s
bk%s
fd_nextsize%s
bk_nextsize%s
prev_inuse%s
ismmapped%s
-------------------------------------------------------------------------------- /ui/selectName.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Form 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 69 11 | 12 | 13 | 14 | Set Name 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Name: 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | Save 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /ui/CMD.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Form 4 | 5 | 6 | 7 | 0 8 | 0 9 | 677 10 | 378 11 | 12 | 13 | 14 | EA CMD 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | CMD: 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | Go! 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ea_read_t.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import pandas.io.formats.format as pf 3 | 4 | from cPickle import load 5 | from code import interact 6 | from sys import argv 7 | 8 | class IntArrayFormatter(pf.GenericArrayFormatter): 9 | def _format_strings(self): 10 | fmt_values = [ 11 | '0x{:016x}'.format(x) for x in self.values 12 | ] 13 | 14 | return fmt_values 15 | 16 | 17 | def read(file): 18 | with open(file, "r") as r: 19 | return r.read() 20 | 21 | 22 | def filter_df(conditions): 23 | return pd.concat(conditions, axis=1).all(axis=1) 24 | 25 | 26 | 27 | def load_df(path): 28 | 29 | with open(path,"rb") as r: 30 | df = load(r) 31 | df = df.set_index(pd.DatetimeIndex(df["time"] * 1000000000).time) 32 | del df["time"] 33 | return df 34 | 35 | pd.options.display.max_rows = 200 36 | pd.options.display.width = 10000 37 | pd.options.display.max_colwidth = 20 38 | pd.options.display.max_columns = 7 39 | pf.IntArrayFormatter = IntArrayFormatter 40 | 41 | 42 | if __name__ == "__main__": 43 | 44 | df = load_df(argv[1]) 45 | print 46 | print df 47 | print 48 | print "dataframe name: df" 49 | print "dataframe columns: %s" % list(df.columns) 50 | print 51 | print "current settings:" 52 | print "pd.options.display.max_rows".ljust(50) + str(pd.options.display.max_rows) 53 | print "pd.options.display.width".ljust(50) + str(pd.options.display.width) 54 | print "pd.options.display.max_colwidth".ljust(50) + str(pd.options.display.max_colwidth) 55 | print "pd.options.display.max_columns".ljust(50) + str(pd.options.display.max_columns) 56 | print "" 57 | interact(local=globals()) 58 | -------------------------------------------------------------------------------- /get_offsets.py: -------------------------------------------------------------------------------- 1 | from re import search 2 | from subprocess import PIPE, Popen, call, check_output 3 | from sys import maxsize 4 | from time import sleep 5 | 6 | # make temp c programme to find c library offsets 7 | with open("/tmp/tmp_offsets.c", "w") as w: 8 | w.write("void main(){}") 9 | 10 | if not maxsize > 2**32: 11 | print "Warning: Running 32bit Python. May not be able to calculate required offsets for 64bit programmes" 12 | 13 | 14 | def get_offsets(bits): 15 | 16 | try: 17 | call("gcc /tmp/tmp_offsets.c -m%s -o /tmp/tmp_offsets" % bits, shell=True, stderr=PIPE) 18 | 19 | except: 20 | if bits == 32: 21 | print ("Warning: Couldn't compile temp C program for x86 architecture.\n" 22 | "If you are on x64 try installing mulitlib (sudo apt-get install libc6:i386 && libc6-dbg:i386 on Debian)\n" 23 | "to resolve this.\n" 24 | "If you are only debugging 64bit programs, ignore this warning and use only 64bit offsets.") 25 | else: 26 | print ("Warning: Could not compile temp C program for x64 architecture.\n" 27 | "If on 32bit system ignore this warning and use only 32bit offsets") 28 | return 29 | 30 | 31 | p = Popen("gdb -q /tmp/tmp_offsets", shell=True,stdin=PIPE, stdout=PIPE) 32 | 33 | sleep(0.5) 34 | p.stdin.write("b main\nr\n") 35 | sleep(0.5) 36 | 37 | p.stdin.write( 38 | "info proc mappings\n" 39 | "q\n" 40 | "y\n" 41 | ) 42 | 43 | main_arena, malloc = [int(i, 16) for i in check_output("nm " + "/usr/lib/debug" + search("(/.*libc-.*\.so)", p.stdout.read()).group(1) + 44 | " | grep 'main_arena\| __libc_malloc$' | awk '{print $1}'", shell=True).split("\n") if i] 45 | 46 | print "%s-bit offsets" % bits 47 | print "main_arena: " + hex(main_arena) 48 | print "malloc: " + hex(malloc) 49 | print 50 | 51 | 52 | print "Calculating Required Offsets\n" 53 | get_offsets(32) 54 | get_offsets(64) 55 | -------------------------------------------------------------------------------- /ui/emulate.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Form 4 | 5 | 6 | 7 | 0 8 | 0 9 | 376 10 | 87 11 | 12 | 13 | 14 | EA Trace 15 | 16 | 17 | 18 | 19 | 20 | Options: 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | Annotate In IDA 30 | 31 | 32 | true 33 | 34 | 35 | 36 | 37 | 38 | 39 | Print In Server Window 40 | 41 | 42 | true 43 | 44 | 45 | 46 | 47 | 48 | 49 | Emulate On Break 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | Done 61 | 62 | 63 | 64 | 65 | 66 | 67 | Emulate! 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IDA EA # 2 | 3 | * **A set of exploitation/reversing aids for IDA** 4 | 5 | ## Features ## 6 | 7 | ### Context Viewer ### 8 | 9 | New context viewer for IDA, Features include: 10 | 11 | * Recursive pointer derfereneces 12 | 13 | * History browser 14 | 15 | * Color coded memory 16 | 17 | * Instruction rewind feature 18 | 19 | * A similar interface to that of popular `GDB` plugings (eg. `PEDA/GEF`) 20 | 21 | 22 | ![screen 1](./screens/view2.png) 23 | 24 | _______________ 25 | 26 | 27 | ### Instuction Emulator ### 28 | 29 | * Live annotate the results if furture instructions in IDA using the `Unicorn` CPU emulator 30 | 31 | 32 | * Can be hooked to breakpoints 33 | 34 | * Visualise instructions before execution 35 | 36 | 37 | ![screen 3](./screens/emu.png) 38 | 39 | _______________ 40 | 41 | ### Heap Explorer ### 42 | 43 | Explore current heap state of glibc binaries 44 | 45 | * Trace allocations 46 | 47 | * Enumerate bins 48 | 49 | * View all free and allocated chunks headers 50 | 51 | * Useful for heap exploitation / debugging. 52 | 53 | ![screen 1](./screens/heap.png) 54 | 55 | _______________ 56 | 57 | ### Trace Dumper ### 58 | 59 | * Dump the results of an IDA trace into a Pandas Dataframe 60 | 61 | * Analyze traces in Python using Pandas 62 | 63 | ![screen 2](./screens/trace.png) 64 | 65 | ![screen](./screens/trace10.png) 66 | 67 | _______________ 68 | ### CMD ### 69 | 70 | * GDB bindings for IDA 71 | 72 | * GDB style mem queries + searches 73 | 74 | ![screen 2](./screens/cmd2.png) 75 | 76 | _______________ 77 | ### Restyle ### 78 | 79 | * Restyle IDA using GUI. 80 | 81 | ![screen 3](./screens/screen3.png) 82 | 83 | 84 | 85 | ___ 86 | 87 | # Install # 88 | 89 | ### Dependencies ### 90 | 91 | No core dependencies for the plugin. Nevertheless certain fetures will be disabled without these python libraries installed: 92 | 93 | 94 | ##### Trace Dumper ##### 95 | 96 | * `Pandas` 97 | 98 | ##### Instruction Emulator ##### 99 | 100 | * `Unicorn CPU emulator` 101 | * `Capstone Dissasembler` 102 | 103 | 104 | ### Install ### 105 | 106 | * Place `ida_ea` folder in `IDA Pro` directory (`C:\Users\{name}\AppData\Roaming\Hex-Rays\IDA Pro` on Windows) 107 | 108 | * Add line `from ida_ea import ea_main` to your `idapythonrc` file. 109 | 110 | * Plugin is accessed via `IDA EA` tab added to the menu bar 111 | 112 | ## Warning ## 113 | 114 | * Only tested on Windows with `IDA 6.8` 115 | 116 | * Only supports `x86/x86-64` binaries 117 | 118 | * Alpha release so expect many bugs! 119 | 120 | 121 | # Enjoy! # 122 | -------------------------------------------------------------------------------- /ui/trace.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Form 4 | 5 | 6 | 7 | 0 8 | 0 9 | 864 10 | 505 11 | 12 | 13 | 14 | 15 | 16777215 16 | 16777215 17 | 18 | 19 | 20 | Form 21 | 22 | 23 | 24 | 25 | 26 | Qt::Horizontal 27 | 28 | 29 | 30 | 31 | 32 | 33 | QLayout::SetDefaultConstraint 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 0 47 | 0 48 | 49 | 50 | 51 | Command 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 0 60 | 0 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | label 75 | label_2 76 | splitter_2 77 | splitter_2 78 | line 79 | layoutWidget_5 80 | layoutWidget_5 81 | splitter 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /api_funcs.py: -------------------------------------------------------------------------------- 1 | from idaapi import * 2 | from idautils import * 3 | from idc import * 4 | 5 | 6 | def add_bp(addr, flags=9, type=4, size=0): 7 | add_bpt(addr,size,type) 8 | bp = bpt_t() 9 | get_bpt(addr, bp) 10 | bp.flags = flags 11 | bp.type = type 12 | bp.size = size 13 | update_bpt(bp) 14 | return bp 15 | 16 | 17 | def get_bp(addr, ret_flags=True): 18 | bp = bpt_t() 19 | get_bpt(addr,bp) 20 | return bp.flags if ret_flags else bp 21 | 22 | 23 | def set_trace(start, end): 24 | add_bp(start,104) 25 | add_bp(end, 72) 26 | 27 | 28 | def runDebugger(file, args=None): 29 | if not args: 30 | StartDebugger(file,file, file[:max(file.rfind("/"), file.rfind("\\"))]) 31 | else: 32 | StartDebugger(file," ".join([file] + args), file[:max(file.rfind("/"), file.rfind("\\"))]) 33 | 34 | 35 | def get_rg(reg): 36 | get_reg_val(reg, reg_mem) 37 | return reg_mem.ival 38 | 39 | 40 | def set_rg(reg, val): 41 | reg_mem.ival = val 42 | set_reg_val(reg, reg_mem) 43 | 44 | 45 | def set_grp_flags(name, flag, type=4, size=0): 46 | a = bpt_vec_t() 47 | get_grp_bpts(a, name) 48 | 49 | for bp in a: 50 | add_bp(bp.ea, flag, type, size) 51 | 52 | 53 | def add_grp(name, l, flags=9, type=4, size=0): 54 | for i in l: 55 | set_bpt_group(add_bp(i, flags, type, size), name) 56 | 57 | 58 | def disas(start,end): 59 | 60 | result = [] 61 | i = start 62 | while i < end: 63 | result.append((i,GetDisasm(i))) 64 | i += ItemSize(i) 65 | 66 | return result 67 | 68 | 69 | def find_ins(ins, addr, limit=1000): 70 | 71 | for x in range(limit): 72 | addr += ItemSize(addr) 73 | if ins in GetDisasm(addr): 74 | break 75 | else: 76 | addr = 0 77 | 78 | return addr 79 | 80 | 81 | def brk_write(start, end, name="brk_read"): 82 | 83 | for addr, i in disas(start, end): 84 | target = i.split(",")[0] 85 | 86 | if "[" in target: 87 | set_bpt_group(add_bp(addr), name) 88 | 89 | 90 | def brk_read(start, end, name="brk_read"): 91 | 92 | for addr, i in disas(start, end): 93 | target = i.split(",") 94 | 95 | if len(target) > 1: 96 | if "[" in target[1]: 97 | set_bpt_group(add_bp(addr), name) 98 | 99 | 100 | def traceFunc(filter ="", type= 10): 101 | 102 | for func in Functions(0, 0xffffffff): 103 | name = GetFunctionName(func) 104 | 105 | if filter in name.lower(): 106 | print name 107 | add_bp(func, type) 108 | 109 | 110 | def traceSeg(filter =""): 111 | 112 | global hooked 113 | 114 | if not hooked: 115 | p_hooks.hook() 116 | 117 | for addr in Segments(): 118 | name = SegName(addr) 119 | end = SegEnd(addr) 120 | 121 | if filter in name.lower(): 122 | print name 123 | add_bp(addr, 10, end - addr) 124 | 125 | 126 | def rd_int(addr=None, reg=None, size=4): 127 | addr = get_rg(reg) if reg else addr 128 | a = dbg_read_memory(addr, size) 129 | return int("".join(reversed(list(a))).encode("HEX"), 16) if a else 0 130 | 131 | 132 | def nop(ea): 133 | for x in range(ItemSize(ea)): 134 | patch_byte(ea + x, 0x90) 135 | 136 | 137 | regs = ["RIP", "RAX", "RBX", "RCX", "RDX", "RSI", "RDI", "RSP", "RBP", 138 | "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"] 139 | 140 | reg_mem = regval_t() 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /ui/traceDump.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Form 4 | 5 | 6 | 7 | 0 8 | 0 9 | 403 10 | 219 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Dump Browser: 23 | 24 | 25 | 26 | 27 | 28 | 29 | Open Dump 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Qt::Horizontal 39 | 40 | 41 | 42 | 43 | 44 | 45 | Dump Location: 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | Select Folder 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | Include Regs: 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | General 76 | 77 | 78 | 79 | 80 | 81 | 82 | Floating Point 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | Dump On: 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | Exit 101 | 102 | 103 | 104 | 105 | 106 | 107 | Breakpoint Hit 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | Go! 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /style_template.css: -------------------------------------------------------------------------------- 1 | /*IDA EA START*/ 2 | 3 | QWidget, QMenuBar, QMenuBar::item, QTabBar::tab, QTextEdit, QTableView { 4 | background-color: {0}; 5 | color: {1}; 6 | } 7 | 8 | QCheckBox { 9 | background-color: rgba(0, 0, 0, 0); 10 | } 11 | 12 | QTextEdit { 13 | border: 0px solid white; 14 | } 15 | 16 | QMenu::item:selected, QMenuBar::item:selected { 17 | background-color: {4}; 18 | color: black; 19 | } 20 | 21 | 22 | QTreeView::item:selected, QListView::item:selected, QTableView::item:selected { 23 | background-color: {4}; 24 | color: black; 25 | } 26 | 27 | QLineEdit { 28 | border: 1px solid {0}; 29 | min-height: 20px; 30 | border-radius: 2px; 31 | } 32 | 33 | 34 | QTabBar::tab:selected { 35 | border: 1px solid {8}; 36 | 37 | } 38 | 39 | QHeaderView::section { 40 | background-color: {5}; 41 | padding-top: 4px; 42 | padding-bottom: 4px; 43 | padding-left: 6px; 44 | border-style: solid; 45 | border-left-width: 1px; 46 | border-right-width: 0px; 47 | border-left-color: {5}; 48 | 49 | } 50 | 51 | QTableView { 52 | border: 0px solid {0}; 53 | } 54 | 55 | QTableCornerButton::section { 56 | background: {0}; 57 | } 58 | 59 | 60 | IDAView, hexview_t, CustomIDAMemo { 61 | border: none; 62 | } 63 | 64 | QScrollBar { 65 | background-color: {0}; 66 | width: 20px; 67 | margin: 0 0 0 0; 68 | } 69 | 70 | QScrollBar::sub-line, QScrollBar::add-line { 71 | width: 0; 72 | height: 0; 73 | } 74 | 75 | QScrollBar::add-page, QScrollBar::sub-page { 76 | background: none; 77 | } 78 | 79 | QScrollBar::handle:vertical { 80 | min-height: 20px; 81 | } 82 | 83 | QScrollBar::handle:horizontal { 84 | min-width: 20px; 85 | } 86 | 87 | QScrollBar::handle { 88 | background-color: {2}; 89 | margin: 3px; 90 | border-radius: 7px; 91 | } 92 | 93 | QToolBar { 94 | border: none; 95 | } 96 | 97 | QPushButton { 98 | border: 1px solid {3}; 99 | text-align: center; 100 | min-height: 20px; 101 | min-width: 50px; 102 | padding: 0 6px 0 6px; 103 | border-radius: 2px; 104 | } 105 | 106 | QComboBox { 107 | border: 1px solid {0}; 108 | } 109 | 110 | QComboBox > QLineEdit, QComboBox > QLineEdit:hover, QComboBox > QLineEdit:focus { 111 | border: none; 112 | min-height: default; 113 | } 114 | 115 | QLineEdit:hover, QLineEdit:focus, QComboBox:hover, QComboBox:focus, QPushButton:hover, QPushButton:default, QPushButton:pressed { 116 | border: 1px solid {7}; 117 | } 118 | 119 | QComboBox::drop-down { 120 | subcontrol-origin: padding; 121 | subcontrol-position: top right; 122 | width: 15px; 123 | border-left-width: 0px; 124 | } 125 | 126 | IDADockWidget > QWidget > QAbstractButton { 127 | background-color: {2}; 128 | border-radius: 3px; 129 | } 130 | 131 | QRadioButton, QLabel, QCheckBox { 132 | background: transparent; 133 | } 134 | 135 | TNavBand > QPushButton, RegJumpButton { 136 | min-height: 0; 137 | min-width: 0; 138 | padding: 0 0 0 0; 139 | border: none; 140 | } 141 | 142 | EditContainer, ChooserContainer, QGroupBox, QListView, QTreeView { 143 | border: 1px solid {8}; 144 | border-radius: 2px; 145 | } 146 | 147 | QGroupBox { 148 | margin-top: 5px; 149 | } 150 | 151 | QGroupBox::title { 152 | subcontrol-origin: margin; 153 | subcontrol-position: top center; 154 | } 155 | 156 | CLIWidget > QGroupBox > QPushButton 157 | { 158 | border: none; 159 | } 160 | 161 | CLIWidget > QGroupBox { 162 | margin-top: 0; 163 | } 164 | 165 | 166 | IDAView { 167 | font-family: {Disassembly Name}; 168 | font-size: {Disassembly Size}pt; 169 | } 170 | 171 | hexview_t { 172 | font-family: {Hex View Name}; 173 | font-size: {Hex View Size}pt; 174 | } 175 | 176 | CustomIDAMemo, EditContainer { 177 | font-family: {Text input Name}; 178 | font-size: {Text input Size}pt; 179 | } -------------------------------------------------------------------------------- /ea_trace.py: -------------------------------------------------------------------------------- 1 | import time 2 | from api_funcs import * 3 | from ea_UI import Trace_UI, QtWidgets 4 | from ea_utils import config, ea_warning, root_dir, save_config 5 | from os.path import isdir 6 | from idaapi import * 7 | from idc import * 8 | from subprocess import Popen 9 | 10 | try: 11 | import pandas as pd 12 | found_lib = True 13 | except: 14 | found_lib = False 15 | 16 | 17 | class Hook(DBG_Hooks): 18 | 19 | def __init__(self): 20 | DBG_Hooks.__init__(self) 21 | 22 | def dbg_process_exit(self, pid, tid, ea, exit_code): 23 | if isinstance(p_hooks, Hook) and dump_on_exit: 24 | dump() 25 | return 0 26 | 27 | def dbg_bpt(self, tid, ea): 28 | if get_bp(ea) == 9: 29 | if isinstance(p_hooks, Hook) and dump_on_break: 30 | dump() 31 | else: 32 | append(ea) 33 | return 0 34 | 35 | def dbg_trace(self, tid, ea): 36 | append(ea) 37 | return 0 38 | 39 | 40 | def dump(): 41 | global hooked 42 | global trace 43 | p_hooks.unhook() 44 | hooked = False 45 | df = pd.DataFrame(trace,columns=["time", "name"] + regs) 46 | df.set_index(pd.DatetimeIndex(df["time"])) 47 | dump_loc = config["trace_dir"] + ("/" if "/" in config["trace_dir"] else "\\") + str(int(time.time())) + ".pickle" 48 | df.to_pickle(dump_loc) 49 | ea_warning("Dumped IDA Trace to " + dump_loc, 50 | buttons=(("Open Folder", lambda: Popen("explorer " + config["trace_dir"], shell=True), False), 51 | ("Open In Console", lambda: open_in_console(dump_loc), False)), 52 | title="EA Trace") 53 | 54 | trace = [] 55 | 56 | 57 | def open_in_console(dump_loc): 58 | Popen('python "%s" "%s"' % (root_dir + "ea_read_t.py", dump_loc)) 59 | 60 | 61 | def append(ea): 62 | if ea not in names: 63 | names[ea] = GetDisasm(ea) 64 | trace.append([time.time(), names[ea]] + [get_rg(reg) for reg in regs]) 65 | 66 | 67 | def select_dir(): 68 | 69 | config["trace_dir"] = QtWidgets.QFileDialog.getExistingDirectory() 70 | save_config() 71 | form.lineEdit.clear() 72 | form.lineEdit.insert(config["trace_dir"]) 73 | 74 | 75 | def select_dump(): 76 | open_in_console( 77 | QtWidgets.QFileDialog.getOpenFileName(QtWidgets.QFileDialog(), 78 | 'Open Dump', '', 79 | 'pickle (*.pickle)')[0]) 80 | 81 | 82 | def go(): 83 | 84 | if not isdir(config["trace_dir"]): 85 | ea_warning("You must select a valid dump directory") 86 | return 87 | 88 | global p_hooks 89 | global general 90 | global floating_point 91 | global dump_on_break 92 | global dump_on_exit 93 | 94 | if isinstance(p_hooks, Hook): 95 | p_hooks.unhook() 96 | 97 | general = form.checkBox.isChecked() 98 | floating_point = form.checkBox_2.isChecked() 99 | dump_on_break = form.radioButton.isChecked() 100 | dump_on_exit = form.radioButton_2.isChecked() 101 | p_hooks = Hook() 102 | p_hooks.hook() 103 | a.close() 104 | 105 | 106 | def ea_trace(): 107 | 108 | global a 109 | global form 110 | 111 | if found_lib: 112 | a = QtWidgets.QFrame() 113 | form = Trace_UI() 114 | form.setupUi(a) 115 | form.checkBox.click() 116 | form.radioButton_2.click() 117 | form.pushButton.clicked.connect(select_dir) 118 | form.pushButton_2.clicked.connect(go) 119 | form.pushButton_4.clicked.connect(select_dump) 120 | if config["trace_dir"]: 121 | form.lineEdit.insert(config["trace_dir"]) 122 | # a.setWindowFlags(a.windowFlags() | QtCore.Qt.WindowStaysOnTopHint) 123 | a.show() 124 | else: 125 | ea_warning("Could not find Pandas in your Python distribution. Install it to use this feature") 126 | 127 | trace = [] 128 | hooked = False 129 | p_hooks = None 130 | dump_on_exit = False 131 | dump_on_break = False 132 | general = False 133 | floating_point = False 134 | a = None 135 | form = None 136 | names = {} 137 | 138 | 139 | -------------------------------------------------------------------------------- /ea_cmd.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from api_funcs import * 4 | from copy import copy 5 | from ea_UI import Cmd_UI 6 | from ea_utils import QtWidgets, ea_warning, get_bits, get_mem_recursive, parse_mem, style 7 | from idaapi import * 8 | from idautils import * 9 | from idc import * 10 | from re import match 11 | from time import sleep, time 12 | 13 | 14 | def get(addr, int_size, n=20): 15 | 16 | string = copy(style[0]) 17 | string += "

" 18 | 19 | for x in range(n): 20 | regions = [] 21 | get_mem_recursive(addr + x * 4, regions, int_size=int_size) 22 | string += parse_mem(regions) + "
" 23 | 24 | string += "

" 25 | 26 | form.textEdit.append(string) 27 | form.textEdit.verticalScrollBar().setValue(form.textEdit.verticalScrollBar().maximum()) 28 | 29 | 30 | def find(arg, int_size): 31 | 32 | matches = [] 33 | addr = 0 34 | 35 | for x in range(100): 36 | newAddr = FindText(addr, SEARCH_DOWN, 0, 0, arg) 37 | if newAddr != 0xffffffffffffffffL: 38 | if newAddr > addr: 39 | addr = newAddr 40 | matches.append(addr) 41 | else: 42 | addr += 0x4 43 | else: 44 | break 45 | 46 | string = copy(style[0]) 47 | string += "

" 48 | 49 | for addr in matches: 50 | regions = [] 51 | get_mem_recursive(addr, regions, int_size=int_size) 52 | string += parse_mem(regions) + "
" 53 | 54 | string += "

" 55 | 56 | form.textEdit.append(string) 57 | form.textEdit.verticalScrollBar().setValue(form.textEdit.verticalScrollBar().maximum()) 58 | 59 | 60 | def do_cmd(): 61 | 62 | int_size = 4 if get_bits() else 8 63 | cmd = form.lineEdit.text() 64 | form.textEdit.append(copy(style) + "▶ " + cmd +"
") 65 | 66 | match_read = match(r"(x\\|x)([0-9]*) *(.*)", cmd) 67 | match_search = match(r"searchmem *(.*)", cmd) 68 | match_step = match(r"step|si", cmd) 69 | match_continue = match(r"continue|c", cmd) 70 | match_run = match(r"run|r", cmd) 71 | match_finish = match(r"finish|fini", cmd) 72 | match_break = match(r"(break|b) *(.*)", cmd) 73 | match_delete = match(r"(delete|delet|del) *(.*)", cmd) 74 | 75 | 76 | if match_read: 77 | length = to_int(match_read.group(2)) 78 | addr = to_int(match_read.group(3)) 79 | 80 | get(addr, int_size, length) 81 | 82 | elif match_search: 83 | cmd = match_search.group(1) 84 | 85 | if cmd[0] == "\"" and cmd[-1] == "\"": 86 | cmd = cmd[1:-1] 87 | 88 | find(str(cmd), int_size) 89 | 90 | elif match_step: 91 | step_into() 92 | 93 | elif match_finish: 94 | step_until_ret() 95 | 96 | elif match_continue: 97 | continue_process() 98 | 99 | elif match_break: 100 | add_bp(to_int(match_break.group(2))) 101 | 102 | elif match_delete: 103 | del_bpt(to_int(match_delete.group(2))) 104 | 105 | elif match_run: 106 | if get_process_state() != 0: 107 | StopDebugger() 108 | # TODO: find way to asynchronously restart debugger without crashing IDA 109 | # a_sync(restart) 110 | else: 111 | ProcessUiAction("ProcessStart") 112 | 113 | 114 | def restart(): 115 | 116 | start = time() 117 | timeout = False 118 | 119 | while get_process_state() != 0: 120 | sleep(0.5) 121 | if start - time() > 4: 122 | timeout = True 123 | ea_warning("Restart operation timed out") 124 | break 125 | 126 | runDebugger(get_input_file_path()) 127 | 128 | 129 | def to_int(i): 130 | 131 | if "0x" in i or "0X" in i: 132 | return int(i[2:],16) 133 | else: 134 | return int(i) 135 | 136 | 137 | def ea_cmd(): 138 | 139 | global a 140 | global form 141 | 142 | a = QtWidgets.QFrame() 143 | form = Cmd_UI() 144 | form.setupUi(a) 145 | form.textEdit.setReadOnly(True) 146 | form.lineEdit.returnPressed.connect(do_cmd) 147 | form.pushButton.clicked.connect(do_cmd) 148 | a.show() 149 | 150 | 151 | addresses = 0 152 | max_iterations = 10 153 | iterations = 0 154 | a = None 155 | form = None 156 | -------------------------------------------------------------------------------- /ui/offset.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Form 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 270 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> 23 | <html><head><meta name="qrichtext" content="1" /><style type="text/css"> 24 | p, li { white-space: pre-wrap; } 25 | </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> 26 | <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Run the script &quot;get_libc_offsets.sh&quot; (located in the plugin main directory) on the linux system you are debugging and enter the offsets provided, this is only required once.</span></p></body></html> 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 32-bit Offsets: 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 100 49 | 0 50 | 51 | 52 | 53 | main_arena offset 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 100 69 | 0 70 | 71 | 72 | 73 | malloc offset 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 64-bit Offsets: 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 100 96 | 0 97 | 98 | 99 | 100 | main_arena offset 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 100 116 | 0 117 | 118 | 119 | 120 | malloc offset 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | OK 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /ea_skin.py: -------------------------------------------------------------------------------- 1 | from ea_UI import QtGui, QtWidgets, QtCore, Name_UI, Reskin_UI 2 | from ea_utils import config, root_dir, save_config, set_style 3 | from idaapi import * 4 | 5 | 6 | def color_selected(i, color): 7 | back = "{:04x}".format(color.rgb())[2:] 8 | buttons[i][0].setStyleSheet("background: " + "#" + back) 9 | buttons[i][2] = back 10 | 11 | 12 | def select_color(i): 13 | 14 | if not (i == 9 and config["match_background"]): 15 | global color 16 | color = QtWidgets.QColorDialog() 17 | # color.setCustomColor(0, 0x212121) 18 | color.setCurrentColor(QtGui.QColor.fromRgb(int(buttons[i][0].styleSheet().split("#")[1], 16))) 19 | color.colorSelected.connect(lambda color: color_selected(i, color)) 20 | color.open() 21 | 22 | 23 | def save_preset(): 24 | 25 | global name_ui 26 | name_ui = QtWidgets.QFrame() 27 | form_2 = Name_UI() 28 | form_2.setupUi(name_ui) 29 | name_ui.show() 30 | form_2.pushButton.clicked.connect(lambda: save_preset_2(form_2, name_ui)) 31 | 32 | 33 | def save_preset_2(form_2, name_ui): 34 | 35 | name = form_2.lineEdit.text() 36 | form.comboBox.addItem(name) 37 | config["skins"].append([name] + [item[2] for item in buttons]) 38 | save_config() 39 | form.comboBox.setCurrentIndex(len(config["skins"]) - 1) 40 | name_ui.close() 41 | 42 | 43 | def load_preset(i): 44 | 45 | if i == 0: 46 | colors = config["current_skin"] 47 | else: 48 | colors = config["skins"][i - 1][1:] 49 | 50 | for i, v in enumerate(colors): 51 | if i == 9 and config["match_background"]: 52 | buttons[i][0].setStyleSheet("background: " + "#" + colors[0]) 53 | else: 54 | buttons[i][0].setStyleSheet("background: " + "#" + v) 55 | buttons[i][2] = v 56 | 57 | 58 | def apply_skin(init = False): 59 | 60 | with open(root_dir + "style_template.css", "r") as r: 61 | style = r.read() 62 | 63 | skin_values = config["current_skin"][:9] if init else (item[2] for item in buttons) 64 | 65 | for i, c in enumerate(item for item in skin_values): 66 | style = style.replace("{%s}" % (i), "#" + c) 67 | 68 | for group in ("Disassembly", "Hex View", "Text input"): 69 | 70 | try: 71 | s = QtCore.QSettings() 72 | s.beginGroup("Font") 73 | s.beginGroup(group) 74 | font_name = s.value("Name") 75 | font_size = s.value("Size") 76 | style = style.replace("{%s %s}" % (group, "Name"), font_name) 77 | style = style.replace("{%s %s}" % (group, "Size"), str(font_size)) 78 | except: 79 | pass 80 | 81 | 82 | 83 | if not init: 84 | config["current_skin"] = [item[2] for item in buttons] 85 | save_config() 86 | 87 | set_style() 88 | 89 | QtWidgets.qApp.setStyleSheet(QtWidgets.qApp.styleSheet().split("/*IDA EA START*/")[0] + style) 90 | 91 | 92 | def toggle_apply_on_startup(state): 93 | config["apply_skin_on_startup"] = True if state else False 94 | 95 | 96 | def toggle_match_background(state): 97 | config["match_background"] = True if state else False 98 | save_config() 99 | 100 | if state: 101 | buttons[9][0].setStyleSheet("background: #" + buttons[0][0].styleSheet().split("#")[1]) 102 | else: 103 | buttons[9][0].setStyleSheet("background: #" + config["current_skin"][9]) 104 | 105 | 106 | def ea_reskin(): 107 | 108 | global a 109 | global form 110 | global buttons 111 | 112 | a = QtWidgets.QFrame() 113 | form = Reskin_UI() 114 | form.setupUi(a) 115 | a.show() 116 | 117 | form.comboBox.addItem("") 118 | form.comboBox.activated.connect(load_preset) 119 | 120 | buttons = [ 121 | [form.pushButton, form.pushButton_2, None], 122 | [form.pushButton_23, form.pushButton_24, None], 123 | [form.pushButton_25, form.pushButton_26, None], 124 | [form.pushButton_9, form.pushButton_10, None], 125 | [form.pushButton_13, form.pushButton_14, None], 126 | [form.pushButton_27, form.pushButton_28, None], 127 | [form.pushButton_21, form.pushButton_22, None], 128 | [form.pushButton_15, form.pushButton_16, None], 129 | [form.pushButton_11, form.pushButton_12, None], 130 | 131 | [form.pushButton_43, form.pushButton_44, None], 132 | [form.pushButton_3, form.pushButton_4, None], 133 | [form.pushButton_31, form.pushButton_32, None], 134 | [form.pushButton_29, form.pushButton_30, None], 135 | [form.pushButton_33, form.pushButton_34, None], 136 | ] 137 | 138 | for x in range(len(buttons)): 139 | buttons[x][0].clicked.connect(lambda x=x: select_color(x)) 140 | buttons[x][1].clicked.connect(lambda x=x: select_color(x)) 141 | 142 | form.pushButton_18.clicked.connect(save_preset) 143 | form.pushButton_17.clicked.connect(lambda: process_ui_action("SetColors")) 144 | form.pushButton_20.clicked.connect(apply_skin) 145 | form.checkBox.stateChanged.connect(lambda x: toggle_apply_on_startup(x)) 146 | form.checkBox_2.stateChanged.connect(lambda x: toggle_match_background(x)) 147 | load_preset(0) 148 | 149 | for i in config["skins"]: 150 | form.comboBox.addItem(i[0]) 151 | 152 | if config["apply_skin_on_startup"]: 153 | form.checkBox.setChecked(True) 154 | 155 | if config["match_background"]: 156 | form.checkBox_2.setChecked(True) 157 | buttons[9][0].setStyleSheet("background: #" + buttons[0][0].styleSheet().split("#")[1]) 158 | 159 | a = None 160 | form = None 161 | buttons = None 162 | name_ui = None 163 | color = None 164 | -------------------------------------------------------------------------------- /ui/ea_view.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Form 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1075 10 | 694 11 | 12 | 13 | 14 | 15 | 16777215 16 | 16777215 17 | 18 | 19 | 20 | EA View 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 0 30 | 0 31 | 32 | 33 | 34 | 35 | 200 36 | 16777215 37 | 38 | 39 | 40 | History 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 0 49 | 0 50 | 51 | 52 | 53 | 54 | 0 55 | 0 56 | 57 | 58 | 59 | 60 | 16777215 61 | 16777215 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | Stack Display Length 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | Rewind 86 | 87 | 88 | 89 | 90 | 91 | 92 | Clear 93 | 94 | 95 | 96 | 97 | 98 | 99 | Dump 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 0 112 | 0 113 | 114 | 115 | 116 | 117 | 10 118 | 16777215 119 | 120 | 121 | 122 | Qt::Vertical 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 1 131 | 1 132 | 133 | 134 | 135 | Qt::Vertical 136 | 137 | 138 | 139 | 140 | QLayout::SetDefaultConstraint 141 | 142 | 143 | 144 | 145 | Registers 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | Qt::Horizontal 160 | 161 | 162 | 163 | 164 | 165 | 166 | Stack 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /ea_emu_client.py: -------------------------------------------------------------------------------- 1 | import socket 2 | 3 | from api_funcs import * 4 | from cPickle import dumps, loads 5 | from ea_UI import Emulate_UI 6 | from ea_utils import QtWidgets, ea_warning, get_bits, root_dir 7 | from idaapi import * 8 | from os import name 9 | from subprocess import Popen 10 | from time import sleep 11 | 12 | # Importing Unicorn Emulator directly into the IDAPython environment causes instability in IDA (random crashes ect.) 13 | # As a result, Unicorn emulator is decoupled from IDA and runs as a seperate process communicating with IDA using a local socket (port 28745) 14 | # The following client code runs within IDAPython and ships emulation requests to ea_emu_server which is a pure Python process 15 | 16 | class Hook(DBG_Hooks): 17 | 18 | def __init__(self): 19 | DBG_Hooks.__init__(self) 20 | 21 | def dbg_bpt(self, tid, ea): 22 | send() 23 | return 0 24 | 25 | def dbg_step_into(self): 26 | send() 27 | return 0 28 | 29 | def dbg_step_until_ret(self): 30 | send() 31 | return 0 32 | 33 | def dbg_step_over(self): 34 | send() 35 | return 0 36 | 37 | 38 | def send(addr=None, code=None): 39 | 40 | if get_process_state() != -1: 41 | ea_warning("Process must be paused/suspended") 42 | 43 | else: 44 | if not addr: 45 | 46 | flags = None 47 | addr = get_rg("RIP") 48 | bp = get_bp(addr,False) 49 | 50 | if bp: 51 | flags = bp.flags 52 | bp.flags = 2 53 | update_bpt(bp) 54 | 55 | code = dbg_read_memory(addr & 0xfffffffffffff000, 0x1000) 56 | 57 | if flags: 58 | bp.flags = flags 59 | update_bpt(bp) 60 | 61 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 62 | 63 | try: 64 | s.connect((TCP_IP, TCP_PORT)) 65 | except socket.error: 66 | launch_server() 67 | sleep(0.5) 68 | s.connect((TCP_IP, TCP_PORT)) 69 | 70 | s.send(dumps(("emu", (addr,code, get_bits(), server_print)))) 71 | error = False 72 | 73 | while True: 74 | data = s.recv(BUFFER_SIZE) 75 | if not data: break 76 | func, args = loads(data) 77 | 78 | if func == "result": 79 | break 80 | if func == "error": 81 | ea_warning(args) 82 | error = True 83 | break 84 | 85 | s.send(dumps(globals()[func](*args))) 86 | 87 | s.close() 88 | 89 | if not error and annotate: 90 | 91 | rip = get_rg("RIP") 92 | 93 | if rip in args: 94 | del args[rip] 95 | 96 | for c, v in args.items(): 97 | v = [i for i in v if i[0] not in ("rip", "eip")] 98 | comment = GetCommentEx(c, 0) 99 | 100 | if v: 101 | annotation = " ".join(a + "=" + hex(b).replace("L", "") for a, b in v) 102 | if comment and "e:" in comment: 103 | comment = comment[:comment.find("e:")].strip(" ") 104 | MakeComm(c, (comment if comment else "").ljust(10) + " e: " + annotation) 105 | else: 106 | if comment and "e:" in comment: 107 | comment = comment[:comment.find("e:")].strip(" ") 108 | MakeComm(c, (comment if comment else "").ljust(10) + " e: " + "No reg changes") 109 | 110 | 111 | def launch_server(): 112 | 113 | # Launch emulation server as a seperate process (see top for details why) 114 | global server_running 115 | Popen("python \"%sea_emu_server.py\"" % root_dir, shell=True if name=="posix" else False) 116 | 117 | server_running = True 118 | 119 | def close_server(arg): 120 | 121 | global server_running 122 | 123 | server_running = False 124 | 125 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 126 | s.connect((TCP_IP, TCP_PORT)) 127 | s.send(dumps(("quit", (0, 0, 0, 0)))) 128 | 129 | 130 | def ea_emulate(): 131 | 132 | global form 133 | global a 134 | global server_running 135 | 136 | if not server_running: 137 | launch_server() 138 | 139 | a = QtWidgets.QFrame() 140 | form = Emulate_UI() 141 | form.setupUi(a) 142 | if hooked: 143 | form.checkBox.click() 144 | 145 | form.checkBox.stateChanged.connect(toggle_hooking) 146 | form.pushButton.clicked.connect(a.close) 147 | form.pushButton_2.clicked.connect(send) 148 | form.checkBox_3.stateChanged.connect(set_annotate) 149 | form.checkBox_2.stateChanged.connect(set_server_print) 150 | # a.setWindowFlags(a.windowFlags() | QtCore.Qt.WindowStaysOnTopHint) 151 | a.closeEvent = close_server 152 | a.show() 153 | 154 | 155 | 156 | 157 | def toggle_hooking(state): 158 | 159 | global h 160 | global hooked 161 | 162 | if state: 163 | if not hooked: 164 | h = Hook() 165 | h.hook() 166 | hooked = True 167 | else: 168 | h.unhook() 169 | hooks = False 170 | 171 | 172 | def set_annotate(state): 173 | global annotate 174 | annotate = True if state else False 175 | 176 | 177 | def set_server_print(state): 178 | global server_print 179 | server_print = True if state else False 180 | 181 | 182 | TCP_IP = '127.0.0.1'; 183 | TCP_PORT = 28745; 184 | BUFFER_SIZE = 0x4000; 185 | comments = [] 186 | 187 | file_name = None 188 | h = None 189 | hooked = False 190 | form = None 191 | a = None 192 | bp = None 193 | server_running = False 194 | annotate = True 195 | server_print = True 196 | 197 | -------------------------------------------------------------------------------- /ea_view.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from api_funcs import * 3 | from cPickle import dump 4 | from copy import copy 5 | from ea_UI import View_UI 6 | from ea_utils import QtWidgets, a_sync, cPrint, config, get_bits, get_mem_recursive, parse_mem, save_config, ea_warning, style 7 | from idaapi import * 8 | from idautils import * 9 | from idc import * 10 | from time import sleep 11 | 12 | 13 | class Hook(DBG_Hooks): 14 | 15 | def __init__(self): 16 | DBG_Hooks.__init__(self) 17 | 18 | def dbg_bpt(self, tid, ea): 19 | if get_bp(ea) == 9: 20 | send() 21 | return 0 22 | 23 | def dbg_step_into(self): 24 | send() 25 | return 0 26 | 27 | def dbg_step_until_ret(self): 28 | send() 29 | return 0 30 | 31 | def dbg_step_over(self): 32 | send() 33 | return 0 34 | 35 | 36 | def anchor_scrollbar(): 37 | 38 | global scroll 39 | 40 | while view_open: 41 | if not scroll: 42 | sleep(0.005) 43 | else: 44 | for x in range(100): 45 | form.listWidget.verticalScrollBar().setValue(form.listWidget.verticalScrollBar().maximum()) 46 | sleep(0.005) 47 | scroll = False 48 | 49 | 50 | def deref_mem(): 51 | 52 | results = [[], []] 53 | 54 | int_size = 4 if get_bits() else 8 55 | 56 | for i, reg in [(i, get_rg(i)) for i in (x64_registers if int_size == 8 else x86_registers)]: 57 | regions = [] 58 | get_mem_recursive(reg, regions, int_size=int_size) 59 | results[0].append((i, regions)) 60 | for i in range(0, config["stack_display_length"]): 61 | regions = [] 62 | get_mem_recursive(get_rg("RSP" if int_size == 8 else "ESP") + (i*int_size), regions, int_size=int_size) 63 | results[1].append((i*int_size, regions)) 64 | 65 | return results 66 | 67 | 68 | def format_mem(results, append=True): 69 | 70 | global scroll 71 | 72 | regs, stack = results 73 | int_size = 4 if get_bits() else 8 74 | string = copy(style[0]) 75 | string += "
" 76 | string += "".join((i + " "*(4-len(i)) + parse_mem(mem) + "\n") + "
" for i, mem in regs) 77 | string = string[:-4] 78 | string += "
" 79 | form.textEdit.clear() 80 | form.textEdit.insertHtml(string) 81 | 82 | string = copy(style[0]) 83 | string += "
" 84 | string += "".join((cPrint("red", ("RSP" if int_size == 8 else "ESP") + "+%s " % "{:03x}".format(i)) + parse_mem(mem)) + "
" for i, mem in stack) 85 | string += "
" 86 | form.textEdit_2.clear() 87 | form.textEdit_2.insertHtml(string) 88 | offset = GetFuncOffset(get_rg("RIP" if int_size == 8 else "EIP")) 89 | 90 | if append: 91 | form.listWidget.addItem(offset if offset else hex(cpu.rip if int_size == 8 else cpu.eip).replace("L", "")) 92 | scroll = True 93 | 94 | 95 | def select_item(item): 96 | format_mem(states[form.listWidget.currentRow()], append=False) 97 | 98 | 99 | def close(event): 100 | global view_open 101 | view_open = False 102 | clear() 103 | h.unhook() 104 | 105 | 106 | def send(): 107 | 108 | results = deref_mem() 109 | states.append(results) 110 | format_mem(results) 111 | form.listWidget.setCurrentRow(len(states) - 1) 112 | 113 | 114 | def clear(): 115 | form.listWidget.clear() 116 | del states[:] 117 | 118 | 119 | def dump_state(): 120 | with open("./" + str(int(time.time())), "wb") as w: 121 | dump(states, w) 122 | 123 | 124 | def set_warning_display(state): 125 | config["show_rewind_warning"] = False if state else True 126 | save_config() 127 | 128 | 129 | def rewind(warning=True): 130 | 131 | if warning and config["show_rewind_warning"]: 132 | ea_warning("Rewind will restore programme state in the scope of the context shown by EA View.\n" 133 | "Changes made outside this scope (eg. heap, data sections) will not be restored. Continue?", 134 | buttons=(("Yes", lambda :rewind(warning=False), True), ("No", None, True)), 135 | checkboxes=(("Don't show this warning again", set_warning_display, False),)) 136 | return 137 | 138 | regs, stack = states[form.listWidget.currentRow()] 139 | 140 | for i, v in regs: 141 | v = v[0][v[0].find("0x") + 2:] 142 | end = v.find("<") 143 | v = int(v[:end] if end != -1 else v, 16) 144 | set_rg(i,v) 145 | 146 | rsp = get_rg("RSP" if get_bits() == 8 else "ESP") 147 | stack_mem = "" 148 | 149 | for i, v in stack: 150 | v = v[1][v[1].find("0x") + 2:] 151 | end = v.find("<") 152 | v = "".join(reversed((v[:end] if end != -1 else v).decode("HEX"))) 153 | stack_mem += v 154 | 155 | dbg_write_memory(rsp, stack_mem) 156 | 157 | 158 | def change_stack_length(x): 159 | config["stack_display_length"] = x 160 | save_config() 161 | 162 | 163 | def ea_view(): 164 | 165 | global h 166 | global form 167 | global a 168 | 169 | a = QtWidgets.QFrame() 170 | form = View_UI() 171 | form.setupUi(a) 172 | form.textEdit.setReadOnly(True) 173 | form.textEdit_2.setReadOnly(True) 174 | form.listWidget.itemClicked.connect(select_item) 175 | form.listWidget.itemClicked.connect(select_item) 176 | form.pushButton.clicked.connect(dump_state) 177 | form.pushButton_2.clicked.connect(clear) 178 | form.pushButton_3.clicked.connect(rewind) 179 | form.textEdit.setLineWrapMode(form.textEdit.NoWrap) 180 | form.textEdit_2.setLineWrapMode(form.textEdit.NoWrap) 181 | form.spinBox.valueChanged.connect(lambda x: change_stack_length(x)) 182 | form.spinBox.setValue(config["stack_display_length"]) 183 | a.closeEvent = close 184 | a.show() 185 | a_sync(anchor_scrollbar) 186 | 187 | h = Hook() 188 | h.hook() 189 | 190 | 191 | x64_registers = ("RAX", "RBX","RCX", "RDX","RDI", "RSI", "RSP", "RBP", "RIP", 192 | "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15") 193 | 194 | x86_registers = ("EAX", "EBX","ECX", "EDX","EDI", "ESI", "ESP", "EBP", "EIP") 195 | 196 | states = [] 197 | h = None 198 | scroll = False 199 | view_open = True 200 | form = False 201 | a = False 202 | anchor_scrollbarr = False 203 | -------------------------------------------------------------------------------- /ui/heap.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Form 4 | 5 | 6 | 7 | 0 8 | 0 9 | 970 10 | 551 11 | 12 | 13 | 14 | 15 | 16777215 16 | 16777215 17 | 18 | 19 | 20 | EA Heap 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | In Use Chunks 31 | 32 | 33 | 34 | 35 | 36 | 37 | Enable Malloc Trace 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 0 51 | 0 52 | 53 | 54 | 55 | 56 | 200 57 | 16777215 58 | 59 | 60 | 61 | Bins 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 0 70 | 0 71 | 72 | 73 | 74 | 75 | 0 76 | 0 77 | 78 | 79 | 80 | 81 | 16777215 82 | 16777215 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 0 92 | 0 93 | 94 | 95 | 96 | 97 | 200 98 | 16777215 99 | 100 | 101 | 102 | Fastbins 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 0 111 | 0 112 | 113 | 114 | 115 | 116 | 0 117 | 0 118 | 119 | 120 | 121 | 122 | 16777215 123 | 16777215 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 0 133 | 0 134 | 135 | 136 | 137 | 138 | 200 139 | 16777215 140 | 141 | 142 | 143 | Bin Chunks 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 0 152 | 0 153 | 154 | 155 | 156 | 157 | 0 158 | 0 159 | 160 | 161 | 162 | 163 | 16777215 164 | 16777215 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | Set Offsets 175 | 176 | 177 | 178 | 179 | 180 | 181 | Refresh 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 0 194 | 0 195 | 196 | 197 | 198 | 199 | 10 200 | 16777215 201 | 202 | 203 | 204 | Qt::Vertical 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 1 213 | 1 214 | 215 | 216 | 217 | 218 | 0 219 | 0 220 | 221 | 222 | 223 | Qt::Vertical 224 | 225 | 226 | 227 | 228 | QLayout::SetDefaultConstraint 229 | 230 | 231 | 232 | 233 | HexDump 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | Chunk Info 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | splitter 260 | line 261 | 262 | 263 | 264 | 265 | -------------------------------------------------------------------------------- /ea_emu_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import socket 4 | import sys 5 | 6 | from cPickle import dumps, loads 7 | from collections import OrderedDict 8 | from copy import copy 9 | from time import sleep 10 | from traceback import format_tb 11 | 12 | try: 13 | from unicorn import * 14 | from unicorn.x86_const import * 15 | found_unicorn = True 16 | except: 17 | found_unicorn = False 18 | 19 | try: 20 | from capstone import * 21 | found_capstone = True 22 | except: 23 | found_capstone = False 24 | 25 | 26 | def debug(type, value, traceback): 27 | print "".join(format_tb(traceback, None)) 28 | print type 29 | print value 30 | raw_input() 31 | 32 | 33 | def get(func, args): 34 | conn.send(dumps((func, args))) 35 | data = loads(conn.recv(BUFFER_SIZE)) 36 | return data 37 | 38 | 39 | def mem_to_int(val): 40 | return int("".join(list(reversed(val))).encode("HEX"),16) 41 | 42 | 43 | def lookup_reg(target, uc): 44 | return uc.reg_read(reg_total[target]) if target in reg_total else eval(target) 45 | 46 | 47 | def dbg_read_memory(mem, size): 48 | return get("dbg_read_memory", (mem, size)) 49 | 50 | 51 | def get_rg(rg): 52 | return get("get_rg", (rg,)) 53 | 54 | 55 | def get_mem(addr, uc): 56 | 57 | size = 0x1000 58 | rounded = addr & 0xfffffffffffff000 59 | uc.mem_map(rounded, size) 60 | 61 | while True: 62 | mem = dbg_read_memory(rounded, size) 63 | size -= 0x10 64 | if mem: 65 | break 66 | if not size: 67 | return 0 68 | 69 | mapped_mem[rounded] = size 70 | uc.mem_write(rounded, mem) 71 | 72 | return 1 73 | 74 | 75 | def hook_code(uc, address, size, user_data): 76 | 77 | global last 78 | global reg_state 79 | 80 | new_reg_state = get_state(uc) 81 | 82 | reg_changes = [(i, new_reg_state[i]) for i in new_reg_state if new_reg_state[i] != reg_state[i]] 83 | 84 | if last not in annotations: 85 | annotations[last] = reg_changes 86 | 87 | reg_state = new_reg_state 88 | 89 | if server_print: 90 | if address in instructions: 91 | print (hex(address) + ": " + " ".join(instructions[address])).ljust(50) + "".join("%s: %s; "%(a,hex(b)) for a, b in reg_changes) 92 | elif dbg: 93 | print "Unmapped instruction %s" % address 94 | 95 | if address == 0: 96 | uc.emu_stop() 97 | 98 | last = address 99 | 100 | 101 | def hook_err(uc, access, address, size, value, user_data, real=False): 102 | 103 | rounded = address & 0xfffffffffffff000 104 | size = 0x1000 105 | 106 | if access == UC_MEM_WRITE_UNMAPPED: 107 | uc.mem_map(rounded, size) 108 | return True 109 | 110 | elif access == UC_MEM_READ_UNMAPPED: 111 | if get_mem(address, uc): 112 | return True 113 | 114 | return False 115 | 116 | 117 | def get_state(uc): 118 | return {name: uc.reg_read(reg) for name, reg in x86_regs.items() if name != "rip"} 119 | 120 | 121 | def emulate(address=False, code=False, _32_bits=True): 122 | 123 | if found_capstone and found_unicorn: 124 | 125 | global instructions 126 | global reg_state 127 | global last 128 | global annotations 129 | 130 | annotations = {} 131 | reg_dict = x86_regs if _32_bits else x64_regs 132 | reg_vals = {r: get_rg(r.upper()) for r in reg_dict} 133 | 134 | if not address: 135 | address = reg_vals["EIP" if _32_bits else "RIP"] 136 | if not code: 137 | code = dbg_read_memory(address, 200) 138 | 139 | address = int(address) 140 | rounded = address & 0xfffffffffffff000 141 | last = address 142 | md = Cs(CS_ARCH_X86, CS_MODE_32 if _32_bits else CS_MODE_64) 143 | instructions = OrderedDict((i.address, (i.mnemonic, i.op_str)) for i in md.disasm(code[address - rounded:], address)) 144 | 145 | if dbg: 146 | print reg_vals 147 | print instructions 148 | 149 | uc = Uc(UC_ARCH_X86, UC_MODE_32 if _32_bits else UC_MODE_64) 150 | uc.mem_map(rounded, 0x1000) 151 | uc.mem_write(rounded, code) 152 | 153 | for name, reg in reg_dict.items(): 154 | if name in reg_vals: 155 | uc.reg_write(reg, reg_vals[name]) 156 | 157 | uc.reg_write(reg_dict["eip" if _32_bits else "rip"], address) 158 | uc.hook_add(UC_HOOK_CODE, hook_code) 159 | uc.hook_add(UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_FETCH_UNMAPPED, hook_err) 160 | 161 | reg_state = get_state(uc) 162 | 163 | try: 164 | print "Emulating instructions:" 165 | uc.emu_start(address, address + 200, timeout=1000000) 166 | except UcError as e: 167 | if dbg: 168 | print e 169 | 170 | print "Finished emulating\n" 171 | 172 | return "result", annotations 173 | 174 | else: 175 | found_neither = True if not found_unicorn and not found_capstone else False 176 | error = ("Could not find " + 177 | ("Capstone or Unicorn" if found_neither else "Capstone" if not found_capstone else "Unicorn") + 178 | " in your Python Library, Please install " + ("them" if found_neither else "it") + 179 | " to enable emulation") 180 | 181 | return "error", error 182 | 183 | 184 | def server(): 185 | 186 | global conn 187 | global server_print 188 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 189 | 190 | error = False 191 | 192 | try: 193 | s.bind((TCP_IP, TCP_PORT)) 194 | except socket.error as e: 195 | error = True 196 | if e.args[0] == 10048: 197 | 198 | # Check if server already running 199 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 200 | s.connect((TCP_IP, TCP_PORT)) 201 | s.send(dumps(("ping",(0,0,0,0)))) 202 | if s.recv(0x10) == "pong": 203 | print "An instance of the server is already running. This window will close in 2 seconds" 204 | sleep(2) 205 | else: 206 | print "Error: Port %s is in use" % TCP_PORT 207 | raw_input() 208 | else: 209 | raise 210 | 211 | if not error: 212 | 213 | s.listen(1) 214 | 215 | while True: 216 | conn, addr = s.accept() 217 | res = conn.recv(0x5000) 218 | cmd, (addr, code, bits, server_print) = loads(res) 219 | 220 | if cmd == "ping": 221 | conn.send("pong") 222 | conn.close() 223 | elif cmd == "quit": 224 | conn.close() 225 | break 226 | elif cmd == "emu": 227 | conn.send(dumps(emulate(addr, code, bits))) 228 | conn.close() 229 | else: 230 | print "Unrecognized cmd: " + cmd 231 | conn.close() 232 | 233 | sys.excepthook = debug 234 | TCP_IP = '127.0.0.1' 235 | TCP_PORT = 28745 236 | BUFFER_SIZE = 0x5000 237 | 238 | annotations = {} 239 | mapped_mem = {} 240 | reg_state = None 241 | instructions = False 242 | conn = None 243 | registers = None 244 | 245 | x86_regs = dict([('eax', UC_X86_REG_EAX), ('ebx', UC_X86_REG_EBX), 246 | ('ecx', UC_X86_REG_ECX), ('edx', UC_X86_REG_EDX), 247 | ('esi', UC_X86_REG_ESI), ('edi', UC_X86_REG_EDI), 248 | ('esp', UC_X86_REG_ESP), ('ebp', UC_X86_REG_EBP), 249 | ('eip', UC_X86_REG_EIP)]) 250 | 251 | x64_regs = dict([('rax', UC_X86_REG_RAX), ('rbx', UC_X86_REG_RBX), 252 | ('rcx', UC_X86_REG_RCX), ('rdx', UC_X86_REG_RDX), 253 | ('rsi', UC_X86_REG_RSI), ('rdi', UC_X86_REG_RDI), 254 | ('rsp', UC_X86_REG_RSP), ('rbp', UC_X86_REG_RBP), 255 | ('r8', UC_X86_REG_R8), ('r9', UC_X86_REG_R9), 256 | ('r10', UC_X86_REG_R10), ('r11', UC_X86_REG_R11), 257 | ('r12', UC_X86_REG_R12), ('r13', UC_X86_REG_R13), 258 | ('r14', UC_X86_REG_R14), ('r15', UC_X86_REG_R15), 259 | ('rip', UC_X86_REG_RIP) 260 | ]) 261 | 262 | reg_total = copy(x64_regs) 263 | reg_total.update(x86_regs) 264 | 265 | dbg = False 266 | server_print = True 267 | 268 | print "Running emulation server..." 269 | 270 | server() 271 | -------------------------------------------------------------------------------- /ea_utils.py: -------------------------------------------------------------------------------- 1 | from idaapi import * 2 | from idautils import * 3 | from idc import * 4 | from api_funcs import get_rg 5 | from ea_UI import QtCore, QtWidgets, Warning_UI 6 | from json import dump, load 7 | from os import remove 8 | from os.path import isfile 9 | from string import printable 10 | 11 | 12 | def read(file, mode="r"): 13 | with open(file, mode) as f: 14 | return f.read() 15 | 16 | 17 | def write(string, file, type="w"): 18 | with open(file, type) as f: 19 | f.write(string) 20 | 21 | 22 | def cPrint(color, msg): 23 | return ("" % (color)) + msg + "" 24 | 25 | 26 | def parse_mem(mem): 27 | return ("").join(mem) 28 | 29 | 30 | def get_bits(): 31 | 32 | global file_name 33 | global _32_bit 34 | 35 | new_name = get_root_filename() 36 | 37 | if new_name != file_name: 38 | file_name = new_name 39 | 40 | # avoid IDA bug 41 | if get_inf_structure().is_32bit() and get_inf_structure().is_64bit(): 42 | _32_bit = (next((False for i in ("r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15") 43 | if get_rg(i) != 0xffffffffffffffff), True) and 44 | next((False for i in ("rax", "rbx", "rcx", "rdx", "rsi", "rdi", "rbp", "rsp", "rip") 45 | if get_rg(i) > 0xffffffff), True)) 46 | else: 47 | _32_bit = get_inf_structure().is_32bit() 48 | 49 | return _32_bit 50 | 51 | 52 | def get_mem_recursive(mem, matches, prev_mem=False, get_perm=True, int_size=4): 53 | 54 | global iterations 55 | 56 | mem_str = hex(mem)[2:].strip("L").zfill(int_size * 2) 57 | 58 | if get_perm: 59 | try: 60 | perm = bin(GetSegmentAttr(mem, SEGATTR_PERM))[2:].zfill(3) 61 | if "1" in perm: 62 | perm = '(' + "".join(sym if int(v) else "-" for v, sym in zip(perm, ("r", "w", "x"))) + ')' 63 | else: 64 | perm = "" 65 | except: 66 | perm = "" 67 | else: 68 | perm = "" 69 | 70 | offset = None 71 | 72 | if codeSegment and codeStart < mem < codeEnd: 73 | offset = GetFuncOffset(mem) 74 | if offset: 75 | text = cPrint("code", "0x" + mem_str) + cPrint("code", " <" + offset + ">") 76 | code = True 77 | 78 | if not offset: 79 | if perm or not get_perm: 80 | text = cPrint("valid", "0x" + mem_str) 81 | elif next((False for i in mem_str if i != "0"), True): 82 | text = cPrint("null", "0x" + mem_str) # + "(NULL)" 83 | else: 84 | text = "0x" + mem_str 85 | 86 | if next((False for i in reversed(mem_str.decode("HEX")) if i not in printable), True) and prev_mem: 87 | r_mem = dbg_read_memory(prev_mem, 50) 88 | if r_mem: 89 | text += '(' + cPrint("string", '"' + r_mem.split("\x00")[0].replace("\n", "") + '"') + ')' 90 | 91 | code = False 92 | 93 | matches.append(text) 94 | 95 | if not code and iterations < max_iterations: 96 | iterations += 1 97 | next_mem = dbg_read_memory(mem, int_size) 98 | 99 | if next_mem: 100 | get_mem_recursive(int("".join(reversed(next_mem)).encode("HEX"), 16), matches, mem, int_size=int_size) 101 | 102 | iterations = 0 103 | 104 | 105 | def ea_warning(text, buttons=(("OK", None, True),), checkboxes=[], title="EA Warning"): 106 | 107 | global warning 108 | global form 109 | 110 | warning = QtWidgets.QFrame() 111 | form = Warning_UI() 112 | form.setupUi(warning) 113 | form.label.setText(text) 114 | 115 | for button, handler, close_on_click in buttons: 116 | setattr(form, button, QtWidgets.QPushButton(warning)) 117 | getattr(form, button).clicked.connect(handler if handler else warning.close) 118 | getattr(form, button).setText(QtWidgets.QApplication.translate("Dialog", button, None)) 119 | 120 | if close_on_click: 121 | getattr(form, button).clicked.connect(warning.close) 122 | 123 | form.horizontalLayout.addWidget(getattr(form, button)) 124 | 125 | for checkbox, handler, checked in checkboxes: 126 | setattr(form, checkbox, QtWidgets.QCheckBox(warning)) 127 | getattr(form, checkbox).stateChanged.connect(handler) 128 | getattr(form, checkbox).setText(QtWidgets.QApplication.translate("Dialog", checkbox, None)) 129 | getattr(form, checkbox).setChecked(checked) 130 | form.horizontalLayout_2.addWidget(getattr(form, checkbox)) 131 | 132 | warning.setWindowFlags(warning.windowFlags() | QtCore.Qt.WindowStaysOnTopHint) 133 | warning.setWindowTitle(QtWidgets.QApplication.translate("Dialog", title, None)) 134 | warning.show() 135 | 136 | 137 | def set_style(): 138 | 139 | global style 140 | 141 | s = QtCore.QSettings() 142 | s.beginGroup("Font") 143 | s.beginGroup("Disassembly") 144 | font_name = s.value("Name") 145 | 146 | style[0] = str( 147 | ( 148 | "" % ( 158 | (config["current_skin"][0] if config["match_background"] else config["current_skin"][9]), 159 | "consolas", 160 | config["current_skin"][11], 161 | config["current_skin"][10], 162 | config["current_skin"][12], 163 | config["current_skin"][13]) 164 | ) 165 | ) 166 | 167 | 168 | def save_config(): 169 | 170 | with open(root_dir + "config.json", "w") as w: 171 | dump(config, w) 172 | 173 | 174 | def load_config(): 175 | 176 | global config 177 | 178 | init_config = { 179 | "libc_offsets": [0, 0, 0, 0], 180 | "trace_dir": "", 181 | "stack_display_length": 25, 182 | "apply_skin_on_startup": True, 183 | "show_rewind_warning": True, 184 | "match_background": True, 185 | "current_skin": ["1c1c2a", "ffffff", "818181", "00d5ff", "ffffff", "202030", "ffffff", "00e6ff", "ffffff", '1c1c2a', 'FFFFFF', '00FFFF', 'C4F0C5', '737DFF'], 186 | "skins": [["Neon Dark", "212121", "ffffff", "414141", "00fff7", "ffffff", "282828", "ffffff", "00ffea", "ffffff", '212121', 'FFFFFF', '00FFFF', 'C4F0C5', '737DFF'], 187 | ["Neon Blue", "1c1c2a", "ffffff", "818181", "00d5ff", "ffffff", "202030", "ffffff", "00e6ff", "ffffff", '1c1c2a', 'FFFFFF', '00FFFF', 'C4F0C5', '737DFF']] 188 | } 189 | 190 | if not isfile(root_dir + "config.json"): 191 | config = init_config 192 | 193 | else: 194 | try: 195 | with open(root_dir + "config.json", "r") as f: 196 | config = load(f) 197 | except: 198 | print 'IDA EA Error: Config File ("config.json") contained invalid JSON. Reinitializing config...' 199 | remove(root_dir + "config.json") 200 | load_config() 201 | return 202 | 203 | for i,v in init_config.items(): 204 | if i not in config: 205 | config[i] = v 206 | 207 | if len(config["current_skin"]) == 9: 208 | # Add new settings 209 | new_settings = ['212121', 'FFFFFF', '00FFFF', 'C4F0C5', '737DFF'] 210 | config["current_skin"] += new_settings 211 | for i in config["skins"]: 212 | i += new_settings 213 | 214 | # Check config file integrety 215 | if len(config["current_skin"]) != 14: 216 | config["current_skin"] = init_config["current_skin"] 217 | print "IDA EA: Errors in current_skin found, Reinitializing" 218 | 219 | for i in config["skins"][:]: 220 | if len(i) != 15: 221 | config["skins"].remove(i) 222 | print "IDA EA: Errors found in %s skin found, Removing" % i[0] 223 | # Check if skin in init_config 224 | skin_names = [a[0] for a in init_config["skins"]] 225 | if i[0] in skin_names: 226 | config["skins"].append(init_config["skins"][skin_names.index(i[0])]) 227 | print "IDA EA: Reinitialized %s skin" % i[0] 228 | 229 | for k in init_config: 230 | if type(config[k]) != type(init_config[k]): 231 | config[k] = init_config[k] 232 | print "IDA EA: Reinitialized incorrect value %s in config file" % k 233 | 234 | save_config() 235 | 236 | 237 | 238 | def a_sync(func, ThreadClass=QtCore.QThread): 239 | 240 | # if reference to QThread is not global, 241 | # python's garbage collection cleans up QThread whilst running causing a crash in IDA 242 | # to prevent this we have an array of global thread references which expands as nessecary 243 | 244 | thread_idx = next((i for i, v in enumerate(threads) if not v.isRunning()), False) 245 | thread = ThreadClass() 246 | 247 | if thread_idx is not False: 248 | threads[thread_idx] = thread 249 | else: 250 | threads.append(thread) 251 | 252 | thread.run = func 253 | thread.start() 254 | 255 | 256 | max_iterations = 10 257 | iterations = 0 258 | 259 | codeSegment = get_segm_by_name(".text") 260 | 261 | if codeSegment: 262 | codeStart = codeSegment.startEA 263 | codeEnd = codeSegment.endEA 264 | 265 | file_name = None 266 | _32_bit = None 267 | root_dir = __file__[:max(__file__.rfind("/"), __file__.rfind("\\"), 0)] + "/" 268 | warning = None 269 | config = None 270 | threads = [] 271 | style = [""] 272 | 273 | load_config() 274 | set_style() 275 | 276 | 277 | -------------------------------------------------------------------------------- /ea_heap.py: -------------------------------------------------------------------------------- 1 | from api_funcs import * 2 | from ea_UI import Heap_UI, Set_Offset_UI 3 | from ea_utils import QtCore, QtWidgets, config, ea_warning, get_bits, read, root_dir, save_config 4 | from idaapi import * 5 | from idautils import * 6 | from idc import * 7 | from re import findall 8 | 9 | class Hook(DBG_Hooks): 10 | 11 | def __init__(self): 12 | DBG_Hooks.__init__(self) 13 | 14 | def dbg_bpt(self, tid, bptea): 15 | 16 | if bptea == malloc_addr: 17 | addr = get_rg("RAX") - int_size*2 18 | c = chunk(*(to_list(dbg_read_memory(addr, 6 * int_size)) + [addr])) 19 | addr = hex(addr).replace("L", "") 20 | 21 | if not form.listWidget_4.findItems(addr, QtCore.Qt.MatchFlag.MatchExactly): 22 | form.listWidget_4.addItem(addr) 23 | 24 | chunkmap_2[addr] = c 25 | update_chunk(c) 26 | get_malloc_state() 27 | 28 | return 0 29 | 30 | 31 | class field(): 32 | 33 | def __init__(self,val,size): 34 | self.val = val 35 | self.size = size 36 | 37 | 38 | class malloc_state(): 39 | 40 | def __init__(self, address): 41 | self.mutex = field(0, 0.5 if int_size == 8 else 1) 42 | self.flags = field(0, 0.5 if int_size == 8 else 1) 43 | self.fastbinsY = field([1],10) 44 | self.top = field(0,1) 45 | self.last_remainder = field(0,1) 46 | self.bins = field([1], 254) 47 | self.binmap = field([0.5], 4) 48 | self.next = field(0,1) 49 | self.next_free = field(0,1) 50 | self.attached_threads = field(0,1) 51 | self.system_mem = field(0,1) 52 | self.max_system_mem = field(0,1) 53 | 54 | # Not a member of glibc malloc_state 55 | self.address = address 56 | 57 | 58 | class chunk(): 59 | 60 | def __init__(self, prev_size, size, fd, bk, fd_nextsize, bk_nextsize, address): 61 | self.prev_size = prev_size 62 | self.size = size & 0xfffffffc 63 | self.fd = fd 64 | self.bk = bk 65 | self.fd_nextsize =fd_nextsize 66 | self.bk_nextsize = bk_nextsize 67 | self.prev_in_use = size & 0x1 68 | self.is_mmapped = 1 if size & 0x2 else 0 69 | 70 | # Not a member of glibc chunk 71 | self.data = "" 72 | self.address = address 73 | 74 | def __str__(self): 75 | 76 | a = ("prev_size" ,"size" ,"fd", "bk", "fd_nextsize", "bk_nextsize") 77 | 78 | return ( "Chunk @ " + hex(getattr(self, "address")) + " = {\n" + 79 | "".join( " " + i + " = " + hex(getattr(self, i)) + "\n" for i in a) + "\n" + 80 | " prev_in_use = " + ("True" if self.prev_in_use else "False") + "\n" 81 | " is_mmapped = " + ("True" if self.is_mmapped else "False") + "\n" 82 | + "}") 83 | 84 | 85 | def to_hex(x): 86 | return hex(x).replace("L","") 87 | 88 | 89 | def to_list(x, chunk_size = 8): 90 | return [ to_int(x[i:i+chunk_size]) for i in range(0, len(x), chunk_size) ] 91 | 92 | 93 | def to_int(x): 94 | 95 | a = "".join(reversed(x)).encode("HEX") 96 | if len(a) % 2: 97 | a = "0" + a 98 | 99 | return int(a, 16) 100 | 101 | 102 | def update_chunk(c): 103 | 104 | next_chunk = dbg_read_memory(c.address, 6 * int_size) 105 | 106 | if next_chunk: 107 | c = chunk(*(to_list(next_chunk) + [c.address])) 108 | c.data = dbg_read_memory(c.address + 2 * int_size, min(c.size, 0x500)).encode("HEX") 109 | 110 | if c.data: 111 | c.data = " ".join(c.data[i:i + 2] for i in range(0, len(c.data), 2)) 112 | else: 113 | c.data = "" 114 | 115 | return c 116 | 117 | 118 | def fill_field(malloc_state, field, mem, current, list=False): 119 | 120 | field_size = getattr(malloc_state,field).size 121 | 122 | if list: 123 | var_size = getattr(malloc_state,field).val.pop() 124 | setattr(malloc_state, field, to_list(mem[current:int(current + int_size * var_size * field_size)], int(int_size*var_size))) 125 | else: 126 | var_size = 1 127 | setattr(malloc_state, field, to_int(mem[current:int(current + int_size * field_size)])) 128 | 129 | current += int(int_size * field_size * var_size) 130 | 131 | return current 132 | 133 | 134 | def get_malloc_state(): 135 | 136 | main_arena = malloc_state(main_arena_addr) 137 | 138 | print main_arena 139 | 140 | mem = dbg_read_memory(main_arena.address, 2200) 141 | current = 0 142 | fields = ["mutex", "flags", "fastbinsY", "top", "last_remainder", "bins", 143 | "binmap", "next", "next_free", "attached_threads", "system_mem", "max_system_mem"] 144 | 145 | for field in fields: 146 | current = fill_field(main_arena, field, mem, current, 147 | True if isinstance(getattr(main_arena, field).val, list) else False) 148 | 149 | main_arena.fastbinsY = [[item] for item in main_arena.fastbinsY] 150 | main_arena.bins = [[item] for item in main_arena.bins] 151 | form.listWidget.clear() 152 | form.listWidget_3.clear() 153 | 154 | for n, bin in enumerate(main_arena.fastbinsY): 155 | if bin and bin[0]: 156 | get_chunks(bin, main_arena.address) 157 | if bin: 158 | name = "Fastbin %s" % hex(n) 159 | form.listWidget.addItem(name) 160 | binmap[name] = bin 161 | elif bin: 162 | bin.pop() 163 | 164 | for n, bin in enumerate(main_arena.bins): 165 | if bin and not (main_arena.address < bin[0] < main_arena.address + 2200): 166 | get_chunks(bin, main_arena.address) 167 | if bin: 168 | name = "Bin %s" % hex(n) 169 | form.listWidget_3.addItem(name) 170 | binmap[name] = bin 171 | elif bin: 172 | bin.pop() 173 | 174 | 175 | def get_chunks(bin, state_addr): 176 | 177 | next_chunk = True 178 | chunks = [] 179 | addr = bin.pop() 180 | 181 | while next_chunk: 182 | next_chunk = dbg_read_memory(addr, 6 * int_size) 183 | 184 | if next_chunk: 185 | c = chunk(*(to_list(next_chunk) + [addr])) 186 | bin.append(c) 187 | chunks.append(c.fd) 188 | c.data = dbg_read_memory(addr + 2 * int_size, min(c.size, 0x500)).encode("HEX") 189 | c.data = " ".join(c.data[i:i+2] for i in range(0, len(c.data), 2)) 190 | if state_addr < c.fd < state_addr + 2200: 191 | break 192 | 193 | addr = c.fd 194 | else: 195 | break 196 | 197 | 198 | def get_main_arena(): 199 | 200 | global base_addr 201 | 202 | for addr in Segments(): 203 | if findall("libc_.*\.so",SegName(addr)): 204 | seg = getseg(addr) 205 | 206 | if seg.perm | SEGPERM_EXEC == seg.perm: 207 | return addr 208 | 209 | 210 | def select_bin(item): 211 | 212 | global chunkmap 213 | 214 | form.listWidget_2.clear() 215 | for chunk in binmap[item.text()]: 216 | form.listWidget_2.addItem(hex(chunk.address)) 217 | chunkmap[hex(chunk.address).replace("L", "")] = chunk 218 | 219 | 220 | def select_chunk(item, chunkmap): 221 | 222 | chunk = chunkmap[item.text()] = update_chunk(chunkmap[item.text()]) 223 | form.textEdit.clear() 224 | form.textEdit.insertHtml("" + "

" + chunk.data + "

") 225 | 226 | string = (chunk_template) % ( 227 | to_hex(chunk.address), 228 | to_hex(chunk.prev_size), 229 | to_hex(chunk.size), 230 | to_hex(chunk.fd), 231 | to_hex(chunk.bk), 232 | to_hex(chunk.fd_nextsize), 233 | to_hex(chunk.bk_nextsize), 234 | "True" if chunk.prev_in_use else "False", 235 | "True" if chunk.is_mmapped else "False" 236 | ) 237 | 238 | form.textEdit_2.clear() 239 | form.textEdit_2.insertHtml(string) 240 | 241 | 242 | def set_config(restart): 243 | 244 | global b 245 | 246 | b = QtWidgets.QWidget() 247 | form = Set_Offset_UI() 248 | form.setupUi(b) 249 | b.show() 250 | 251 | form.pushButton.clicked.connect(lambda: get_text(form, restart)) 252 | 253 | 254 | def get_text(form, restart): 255 | 256 | global malloc_offset 257 | global main_arena_offset 258 | 259 | offsets = [form.lineEdit.text(), form.lineEdit_2.text(), form.lineEdit_3.text(), form.lineEdit_4.text()] 260 | 261 | for x in range(4): 262 | if offsets[x][:2] == "0x": 263 | offsets[x] = int(offsets[x][2:], 16) 264 | else: 265 | offsets[x] = int(offsets[x]) 266 | 267 | config["libc_offsets"] = offsets 268 | main_arena_offset, malloc_offset = offsets[:2] if int_size == 8 else offsets[2:] 269 | b.close() 270 | save_config() 271 | 272 | if restart: 273 | ea_heap() 274 | 275 | 276 | def ea_heap(): 277 | 278 | global form 279 | global a 280 | global item_no 281 | global hook 282 | global main_arena_addr 283 | global malloc_addr 284 | 285 | if "ELF" not in get_file_type_name(): 286 | ea_warning("Executable must be ELF fomat (glibc)") 287 | 288 | else: 289 | if main_arena_offset == 0 and malloc_offset == 0: 290 | set_config(True) 291 | else: 292 | if not is_debugger_on(): 293 | ea_warning("Application must be running") 294 | else: 295 | base_addr = get_main_arena() 296 | 297 | if not base_addr: 298 | ea_warning("Could not find C Library in Segments") 299 | 300 | else: 301 | malloc_addr = find_ins("ret", base_addr + malloc_offset) 302 | main_arena_addr = base_addr + main_arena_offset 303 | 304 | a = QtWidgets.QWidget() 305 | form = Heap_UI() 306 | form.setupUi(a) 307 | form.textEdit.setReadOnly(True) 308 | form.textEdit_2.setReadOnly(True) 309 | a.show() 310 | hook = Hook() 311 | hook.hook() 312 | a.closeEvent = lambda x: hook.unhook() 313 | form.listWidget.itemClicked.connect(select_bin) 314 | form.listWidget_3.itemClicked.connect(select_bin) 315 | form.listWidget_2.itemClicked.connect(lambda x: select_chunk(x, chunkmap)) 316 | form.listWidget_4.itemClicked.connect(lambda x: select_chunk(x, chunkmap_2)) 317 | form.pushButton_2.clicked.connect(lambda :set_config(False)) 318 | form.pushButton.clicked.connect(get_malloc_state) 319 | 320 | form.checkBox.stateChanged.connect(lambda x: ( 321 | add_bp(malloc_addr, 10), hook.hook()) if x else (add_bp(malloc_addr, 2), hook.unhook())) 322 | 323 | get_malloc_state() 324 | 325 | 326 | chunk_template = read(root_dir + "chunk_template.html") 327 | int_size = 4 if get_bits() else 8 328 | 329 | main_arena_offset, malloc_offset = config["libc_offsets"][:2] if int_size == 4 else config["libc_offsets"][2:] 330 | 331 | chunkmap = {} 332 | chunkmap_2 = {} 333 | binmap = {} 334 | 335 | form = None 336 | a = None 337 | b = None 338 | hook = None 339 | base_addr = None 340 | main_arena_addr = None 341 | malloc_addr = None 342 | -------------------------------------------------------------------------------- /ui/restyle.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Form 4 | 5 | 6 | 7 | 0 8 | 0 9 | 412 10 | 548 11 | 12 | 13 | 14 | EA Reskin 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | Save As 28 | 29 | 30 | 31 | 32 | 33 | 34 | Delete 35 | 36 | 37 | 38 | 39 | 40 | 41 | Apply Skin On startup 42 | 43 | 44 | true 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | IDA: 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 0 66 | 0 67 | 68 | 69 | 70 | 71 | 0 72 | 0 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | true 84 | 85 | 86 | 87 | 0 88 | 0 89 | 90 | 91 | 92 | Background Color 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 0 105 | 0 106 | 107 | 108 | 109 | 110 | 0 111 | 0 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | true 123 | 124 | 125 | 126 | 0 127 | 0 128 | 129 | 130 | 131 | Text Color 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 0 144 | 0 145 | 146 | 147 | 148 | 149 | 0 150 | 0 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | true 162 | 163 | 164 | 165 | 0 166 | 0 167 | 168 | 169 | 170 | Handles 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 0 183 | 0 184 | 185 | 186 | 187 | 188 | 0 189 | 0 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | true 201 | 202 | 203 | 204 | 0 205 | 0 206 | 207 | 208 | 209 | Button Outline 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 0 222 | 0 223 | 224 | 225 | 226 | 227 | 0 228 | 0 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | true 240 | 241 | 242 | 243 | 0 244 | 0 245 | 246 | 247 | 248 | Menu Selected 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 0 261 | 0 262 | 263 | 264 | 265 | 266 | 0 267 | 0 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | true 279 | 280 | 281 | 282 | 0 283 | 0 284 | 285 | 286 | 287 | List Headers 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 0 300 | 0 301 | 302 | 303 | 304 | 305 | 0 306 | 0 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | true 318 | 319 | 320 | 321 | 0 322 | 0 323 | 324 | 325 | 326 | List Selected 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 0 339 | 0 340 | 341 | 342 | 343 | 344 | 0 345 | 0 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | true 357 | 358 | 359 | 360 | 0 361 | 0 362 | 363 | 364 | 365 | Field Hover 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 0 378 | 0 379 | 380 | 381 | 382 | 383 | 0 384 | 0 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | true 396 | 397 | 398 | 399 | 0 400 | 0 401 | 402 | 403 | 404 | Tab Selected 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | EA View: 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 0 424 | 0 425 | 426 | 427 | 428 | 429 | 0 430 | 0 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | Match IDA Background 442 | 443 | 444 | 445 | 446 | 447 | 448 | true 449 | 450 | 451 | 452 | 0 453 | 0 454 | 455 | 456 | 457 | Background Color 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 0 470 | 0 471 | 472 | 473 | 474 | 475 | 0 476 | 0 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | true 488 | 489 | 490 | 491 | 0 492 | 0 493 | 494 | 495 | 496 | Executable Memory 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 0 509 | 0 510 | 511 | 512 | 513 | 514 | 0 515 | 0 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | true 527 | 528 | 529 | 530 | 0 531 | 0 532 | 533 | 534 | 535 | Readable/Writeable Memory 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 0 548 | 0 549 | 550 | 551 | 552 | 553 | 0 554 | 0 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | true 566 | 567 | 568 | 569 | 0 570 | 0 571 | 572 | 573 | 574 | String 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 0 587 | 0 588 | 589 | 590 | 591 | 592 | 0 593 | 0 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | true 605 | 606 | 607 | 608 | 0 609 | 0 610 | 611 | 612 | 613 | Null 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | Apply 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 16777215 633 | 16777215 634 | 635 | 636 | 637 | Set Code Colors 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | -------------------------------------------------------------------------------- /ea_UI.py: -------------------------------------------------------------------------------- 1 | from idaapi import IDA_SDK_VERSION 2 | 3 | if IDA_SDK_VERSION < 690: 4 | try: 5 | # Hack to maintain backward compatibility with 6.8 6 | from PySide import QtGui as QtWidgets, QtGui, QtCore 7 | except: 8 | print "IDA EA Error: Couldn't Find PySide Bindings, Trying PyQt" 9 | from PyQt4 import QtGui as QtWidgets, QtGui, QtCore 10 | else: 11 | print "Warning: IDA EA untested with IDA >=6.9" 12 | from PyQt5 import QtGui, QtCore, QtWidgets 13 | 14 | 15 | class Warning_UI(object): 16 | def setupUi(self, Dialog): 17 | Dialog.setObjectName("Dialog") 18 | Dialog.resize(328, 47) 19 | Dialog.setWindowTitle("") 20 | self.verticalLayout = QtGui.QVBoxLayout(Dialog) 21 | self.verticalLayout.setObjectName("verticalLayout") 22 | self.label = QtGui.QLabel(Dialog) 23 | self.label.setText("") 24 | self.label.setObjectName("label") 25 | self.verticalLayout.addWidget(self.label) 26 | self.horizontalLayout_2 = QtGui.QHBoxLayout() 27 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 28 | self.verticalLayout.addLayout(self.horizontalLayout_2) 29 | self.horizontalLayout = QtGui.QHBoxLayout() 30 | self.horizontalLayout.setObjectName("horizontalLayout") 31 | self.verticalLayout.addLayout(self.horizontalLayout) 32 | QtCore.QMetaObject.connectSlotsByName(Dialog) 33 | 34 | 35 | class View_UI(object): 36 | def setupUi(self, Form): 37 | Form.setObjectName("Form") 38 | Form.resize(1210, 694) 39 | Form.setMaximumSize(QtCore.QSize(16777215, 16777215)) 40 | self.gridLayout = QtWidgets.QGridLayout(Form) 41 | self.gridLayout.setObjectName("gridLayout") 42 | self.verticalLayout_3 = QtWidgets.QVBoxLayout() 43 | self.verticalLayout_3.setObjectName("verticalLayout_3") 44 | self.label_7 = QtWidgets.QLabel(Form) 45 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) 46 | sizePolicy.setHorizontalStretch(0) 47 | sizePolicy.setVerticalStretch(0) 48 | sizePolicy.setHeightForWidth(self.label_7.sizePolicy().hasHeightForWidth()) 49 | self.label_7.setSizePolicy(sizePolicy) 50 | self.label_7.setMaximumSize(QtCore.QSize(200, 16777215)) 51 | self.label_7.setObjectName("label_7") 52 | self.verticalLayout_3.addWidget(self.label_7) 53 | self.listWidget = QtWidgets.QListWidget(Form) 54 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) 55 | sizePolicy.setHorizontalStretch(0) 56 | sizePolicy.setVerticalStretch(0) 57 | sizePolicy.setHeightForWidth(self.listWidget.sizePolicy().hasHeightForWidth()) 58 | self.listWidget.setSizePolicy(sizePolicy) 59 | self.listWidget.setMinimumSize(QtCore.QSize(0, 0)) 60 | self.listWidget.setMaximumSize(QtCore.QSize(16777215, 16777215)) 61 | self.listWidget.setObjectName("listWidget") 62 | self.verticalLayout_3.addWidget(self.listWidget) 63 | self.horizontalLayout = QtWidgets.QHBoxLayout() 64 | self.horizontalLayout.setObjectName("horizontalLayout") 65 | self.spinBox = QtWidgets.QSpinBox(Form) 66 | self.spinBox.setObjectName("spinBox") 67 | self.horizontalLayout.addWidget(self.spinBox) 68 | self.label_3 = QtWidgets.QLabel(Form) 69 | self.label_3.setObjectName("label_3") 70 | self.horizontalLayout.addWidget(self.label_3) 71 | self.verticalLayout_3.addLayout(self.horizontalLayout) 72 | self.horizontalLayout_3 = QtWidgets.QHBoxLayout() 73 | self.horizontalLayout_3.setObjectName("horizontalLayout_3") 74 | self.pushButton_3 = QtWidgets.QPushButton(Form) 75 | self.pushButton_3.setObjectName("pushButton_3") 76 | self.horizontalLayout_3.addWidget(self.pushButton_3) 77 | self.pushButton_2 = QtWidgets.QPushButton(Form) 78 | self.pushButton_2.setObjectName("pushButton_2") 79 | self.horizontalLayout_3.addWidget(self.pushButton_2) 80 | self.pushButton = QtWidgets.QPushButton(Form) 81 | self.pushButton.setObjectName("pushButton") 82 | self.horizontalLayout_3.addWidget(self.pushButton) 83 | self.verticalLayout_3.addLayout(self.horizontalLayout_3) 84 | self.gridLayout.addLayout(self.verticalLayout_3, 0, 0, 1, 1) 85 | self.line = QtWidgets.QFrame(Form) 86 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) 87 | sizePolicy.setHorizontalStretch(0) 88 | sizePolicy.setVerticalStretch(0) 89 | sizePolicy.setHeightForWidth(self.line.sizePolicy().hasHeightForWidth()) 90 | self.line.setSizePolicy(sizePolicy) 91 | self.line.setMaximumSize(QtCore.QSize(10, 16777215)) 92 | self.line.setFrameShape(QtWidgets.QFrame.VLine) 93 | self.line.setFrameShadow(QtWidgets.QFrame.Sunken) 94 | self.line.setObjectName("line") 95 | self.gridLayout.addWidget(self.line, 0, 1, 1, 1) 96 | self.splitter = QtWidgets.QSplitter(Form) 97 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) 98 | sizePolicy.setHorizontalStretch(1) 99 | sizePolicy.setVerticalStretch(1) 100 | sizePolicy.setHeightForWidth(self.splitter.sizePolicy().hasHeightForWidth()) 101 | self.splitter.setSizePolicy(sizePolicy) 102 | self.splitter.setOrientation(QtCore.Qt.Vertical) 103 | self.splitter.setObjectName("splitter") 104 | self.layoutWidget = QtWidgets.QWidget(self.splitter) 105 | self.layoutWidget.setObjectName("layoutWidget") 106 | self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.layoutWidget) 107 | self.verticalLayout_2.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint) 108 | self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) 109 | self.verticalLayout_2.setObjectName("verticalLayout_2") 110 | self.label = QtWidgets.QLabel(self.layoutWidget) 111 | self.label.setObjectName("label") 112 | self.verticalLayout_2.addWidget(self.label) 113 | self.textEdit = QtWidgets.QTextEdit(self.layoutWidget) 114 | self.textEdit.setObjectName("textEdit") 115 | self.verticalLayout_2.addWidget(self.textEdit) 116 | self.layoutWidget1 = QtWidgets.QWidget(self.splitter) 117 | self.layoutWidget1.setObjectName("layoutWidget1") 118 | self.verticalLayout = QtWidgets.QVBoxLayout(self.layoutWidget1) 119 | self.verticalLayout.setContentsMargins(0, 0, 0, 0) 120 | self.verticalLayout.setObjectName("verticalLayout") 121 | self.line_2 = QtWidgets.QFrame(self.layoutWidget1) 122 | self.line_2.setFrameShape(QtWidgets.QFrame.HLine) 123 | self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken) 124 | self.line_2.setObjectName("line_2") 125 | self.verticalLayout.addWidget(self.line_2) 126 | self.label_2 = QtWidgets.QLabel(self.layoutWidget1) 127 | self.label_2.setObjectName("label_2") 128 | self.verticalLayout.addWidget(self.label_2) 129 | self.textEdit_2 = QtWidgets.QTextEdit(self.layoutWidget1) 130 | self.textEdit_2.setObjectName("textEdit_2") 131 | self.verticalLayout.addWidget(self.textEdit_2) 132 | self.gridLayout.addWidget(self.splitter, 0, 2, 1, 1) 133 | 134 | self.retranslateUi(Form) 135 | QtCore.QMetaObject.connectSlotsByName(Form) 136 | 137 | def retranslateUi(self, Form): 138 | Form.setWindowTitle(QtWidgets.QApplication.translate("Form", "EA View", None)) 139 | self.label_7.setText(QtWidgets.QApplication.translate("Form", "History", None)) 140 | self.label_3.setText(QtWidgets.QApplication.translate("Form", "Stack Display Length", None)) 141 | self.pushButton_3.setText(QtWidgets.QApplication.translate("Form", "Rewind", None)) 142 | self.pushButton_2.setText(QtWidgets.QApplication.translate("Form", "Clear", None)) 143 | self.pushButton.setText(QtWidgets.QApplication.translate("Form", "Dump", None)) 144 | self.label.setText(QtWidgets.QApplication.translate("Form", "Registers", None)) 145 | self.label_2.setText(QtWidgets.QApplication.translate("Form", "Stack", None)) 146 | 147 | 148 | class Set_Offset_UI(object): 149 | 150 | def setupUi(self, Form): 151 | Form.setObjectName("Form") 152 | Form.resize(400, 270) 153 | self.verticalLayout = QtWidgets.QVBoxLayout(Form) 154 | self.verticalLayout.setObjectName("verticalLayout") 155 | self.horizontalLayout_3 = QtWidgets.QHBoxLayout() 156 | self.horizontalLayout_3.setObjectName("horizontalLayout_3") 157 | self.textBrowser = QtWidgets.QTextBrowser(Form) 158 | self.textBrowser.setObjectName("textBrowser") 159 | self.horizontalLayout_3.addWidget(self.textBrowser) 160 | self.verticalLayout.addLayout(self.horizontalLayout_3) 161 | self.label_6 = QtWidgets.QLabel(Form) 162 | self.label_6.setObjectName("label_6") 163 | self.verticalLayout.addWidget(self.label_6) 164 | self.horizontalLayout_2 = QtWidgets.QHBoxLayout() 165 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 166 | self.lineEdit = QtWidgets.QLineEdit(Form) 167 | self.lineEdit.setObjectName("lineEdit") 168 | self.horizontalLayout_2.addWidget(self.lineEdit) 169 | self.label = QtWidgets.QLabel(Form) 170 | self.label.setMinimumSize(QtCore.QSize(100, 0)) 171 | self.label.setObjectName("label") 172 | self.horizontalLayout_2.addWidget(self.label) 173 | self.verticalLayout.addLayout(self.horizontalLayout_2) 174 | self.horizontalLayout_4 = QtWidgets.QHBoxLayout() 175 | self.horizontalLayout_4.setObjectName("horizontalLayout_4") 176 | self.lineEdit_2 = QtWidgets.QLineEdit(Form) 177 | self.lineEdit_2.setObjectName("lineEdit_2") 178 | self.horizontalLayout_4.addWidget(self.lineEdit_2) 179 | self.label_2 = QtWidgets.QLabel(Form) 180 | self.label_2.setMinimumSize(QtCore.QSize(100, 0)) 181 | self.label_2.setObjectName("label_2") 182 | self.horizontalLayout_4.addWidget(self.label_2) 183 | self.verticalLayout.addLayout(self.horizontalLayout_4) 184 | self.label_5 = QtWidgets.QLabel(Form) 185 | self.label_5.setObjectName("label_5") 186 | self.verticalLayout.addWidget(self.label_5) 187 | self.horizontalLayout_6 = QtWidgets.QHBoxLayout() 188 | self.horizontalLayout_6.setObjectName("horizontalLayout_6") 189 | self.lineEdit_4 = QtWidgets.QLineEdit(Form) 190 | self.lineEdit_4.setObjectName("lineEdit_4") 191 | self.horizontalLayout_6.addWidget(self.lineEdit_4) 192 | self.label_4 = QtWidgets.QLabel(Form) 193 | self.label_4.setMinimumSize(QtCore.QSize(100, 0)) 194 | self.label_4.setObjectName("label_4") 195 | self.horizontalLayout_6.addWidget(self.label_4) 196 | self.verticalLayout.addLayout(self.horizontalLayout_6) 197 | self.horizontalLayout_5 = QtWidgets.QHBoxLayout() 198 | self.horizontalLayout_5.setObjectName("horizontalLayout_5") 199 | self.lineEdit_3 = QtWidgets.QLineEdit(Form) 200 | self.lineEdit_3.setObjectName("lineEdit_3") 201 | self.horizontalLayout_5.addWidget(self.lineEdit_3) 202 | self.label_3 = QtWidgets.QLabel(Form) 203 | self.label_3.setMinimumSize(QtCore.QSize(100, 0)) 204 | self.label_3.setObjectName("label_3") 205 | self.horizontalLayout_5.addWidget(self.label_3) 206 | self.verticalLayout.addLayout(self.horizontalLayout_5) 207 | self.pushButton = QtWidgets.QPushButton(Form) 208 | self.pushButton.setObjectName("pushButton") 209 | self.verticalLayout.addWidget(self.pushButton) 210 | 211 | self.retranslateUi(Form) 212 | QtCore.QMetaObject.connectSlotsByName(Form) 213 | 214 | def retranslateUi(self, Form): 215 | Form.setWindowTitle(QtWidgets.QApplication.translate("Form", "Form", None)) 216 | self.textBrowser.setHtml(QtWidgets.QApplication.translate("Form", "\n" 217 | "\n" 220 | "

Run the script "get_offsets.py" (located in the plugin main directory) on the linux system you are debugging and enter the offsets provided, this is only required once.

", None)) 221 | self.label_6.setText(QtWidgets.QApplication.translate("Form", "32-bit Offsets:", None)) 222 | self.label.setText(QtWidgets.QApplication.translate("Form", "main_arena offset", None)) 223 | self.label_2.setText(QtWidgets.QApplication.translate("Form", "malloc offset", None)) 224 | self.label_5.setText(QtWidgets.QApplication.translate("Form", "64-bit Offsets:", None)) 225 | self.label_4.setText(QtWidgets.QApplication.translate("Form", "main_arena offset", None)) 226 | self.label_3.setText(QtWidgets.QApplication.translate("Form", "malloc offset", None)) 227 | self.pushButton.setText(QtWidgets.QApplication.translate("Form", "OK", None)) 228 | 229 | 230 | class Heap_UI(object): 231 | def setupUi(self, Form): 232 | Form.setObjectName("Form") 233 | Form.resize(970, 551) 234 | Form.setMaximumSize(QtCore.QSize(16777215, 16777215)) 235 | self.gridLayout = QtWidgets.QGridLayout(Form) 236 | self.gridLayout.setObjectName("gridLayout") 237 | self.verticalLayout_3 = QtWidgets.QVBoxLayout() 238 | self.verticalLayout_3.setObjectName("verticalLayout_3") 239 | self.horizontalLayout = QtWidgets.QHBoxLayout() 240 | self.horizontalLayout.setObjectName("horizontalLayout") 241 | self.label_3 = QtWidgets.QLabel(Form) 242 | self.label_3.setObjectName("label_3") 243 | self.horizontalLayout.addWidget(self.label_3) 244 | self.checkBox = QtWidgets.QCheckBox(Form) 245 | self.checkBox.setObjectName("checkBox") 246 | self.horizontalLayout.addWidget(self.checkBox) 247 | self.verticalLayout_3.addLayout(self.horizontalLayout) 248 | self.listWidget_4 = QtWidgets.QListWidget(Form) 249 | self.listWidget_4.setObjectName("listWidget_4") 250 | self.verticalLayout_3.addWidget(self.listWidget_4) 251 | self.label_9 = QtWidgets.QLabel(Form) 252 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) 253 | sizePolicy.setHorizontalStretch(0) 254 | sizePolicy.setVerticalStretch(0) 255 | sizePolicy.setHeightForWidth(self.label_9.sizePolicy().hasHeightForWidth()) 256 | self.label_9.setSizePolicy(sizePolicy) 257 | self.label_9.setMaximumSize(QtCore.QSize(200, 16777215)) 258 | self.label_9.setObjectName("label_9") 259 | self.verticalLayout_3.addWidget(self.label_9) 260 | self.listWidget_3 = QtWidgets.QListWidget(Form) 261 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) 262 | sizePolicy.setHorizontalStretch(0) 263 | sizePolicy.setVerticalStretch(0) 264 | sizePolicy.setHeightForWidth(self.listWidget_3.sizePolicy().hasHeightForWidth()) 265 | self.listWidget_3.setSizePolicy(sizePolicy) 266 | self.listWidget_3.setMinimumSize(QtCore.QSize(0, 0)) 267 | self.listWidget_3.setMaximumSize(QtCore.QSize(16777215, 16777215)) 268 | self.listWidget_3.setObjectName("listWidget_3") 269 | self.verticalLayout_3.addWidget(self.listWidget_3) 270 | self.label_7 = QtWidgets.QLabel(Form) 271 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) 272 | sizePolicy.setHorizontalStretch(0) 273 | sizePolicy.setVerticalStretch(0) 274 | sizePolicy.setHeightForWidth(self.label_7.sizePolicy().hasHeightForWidth()) 275 | self.label_7.setSizePolicy(sizePolicy) 276 | self.label_7.setMaximumSize(QtCore.QSize(200, 16777215)) 277 | self.label_7.setObjectName("label_7") 278 | self.verticalLayout_3.addWidget(self.label_7) 279 | self.listWidget = QtWidgets.QListWidget(Form) 280 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) 281 | sizePolicy.setHorizontalStretch(0) 282 | sizePolicy.setVerticalStretch(0) 283 | sizePolicy.setHeightForWidth(self.listWidget.sizePolicy().hasHeightForWidth()) 284 | self.listWidget.setSizePolicy(sizePolicy) 285 | self.listWidget.setMinimumSize(QtCore.QSize(0, 0)) 286 | self.listWidget.setMaximumSize(QtCore.QSize(16777215, 16777215)) 287 | self.listWidget.setObjectName("listWidget") 288 | self.verticalLayout_3.addWidget(self.listWidget) 289 | self.label_8 = QtWidgets.QLabel(Form) 290 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) 291 | sizePolicy.setHorizontalStretch(0) 292 | sizePolicy.setVerticalStretch(0) 293 | sizePolicy.setHeightForWidth(self.label_8.sizePolicy().hasHeightForWidth()) 294 | self.label_8.setSizePolicy(sizePolicy) 295 | self.label_8.setMaximumSize(QtCore.QSize(200, 16777215)) 296 | self.label_8.setObjectName("label_8") 297 | self.verticalLayout_3.addWidget(self.label_8) 298 | self.listWidget_2 = QtWidgets.QListWidget(Form) 299 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) 300 | sizePolicy.setHorizontalStretch(0) 301 | sizePolicy.setVerticalStretch(0) 302 | sizePolicy.setHeightForWidth(self.listWidget_2.sizePolicy().hasHeightForWidth()) 303 | self.listWidget_2.setSizePolicy(sizePolicy) 304 | self.listWidget_2.setMinimumSize(QtCore.QSize(0, 0)) 305 | self.listWidget_2.setMaximumSize(QtCore.QSize(16777215, 16777215)) 306 | self.listWidget_2.setObjectName("listWidget_2") 307 | self.verticalLayout_3.addWidget(self.listWidget_2) 308 | self.horizontalLayout_3 = QtWidgets.QHBoxLayout() 309 | self.horizontalLayout_3.setObjectName("horizontalLayout_3") 310 | self.pushButton_2 = QtWidgets.QPushButton(Form) 311 | self.pushButton_2.setObjectName("pushButton_2") 312 | self.horizontalLayout_3.addWidget(self.pushButton_2) 313 | self.pushButton = QtWidgets.QPushButton(Form) 314 | self.pushButton.setObjectName("pushButton") 315 | self.horizontalLayout_3.addWidget(self.pushButton) 316 | self.verticalLayout_3.addLayout(self.horizontalLayout_3) 317 | self.gridLayout.addLayout(self.verticalLayout_3, 0, 0, 1, 1) 318 | self.line = QtWidgets.QFrame(Form) 319 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) 320 | sizePolicy.setHorizontalStretch(0) 321 | sizePolicy.setVerticalStretch(0) 322 | sizePolicy.setHeightForWidth(self.line.sizePolicy().hasHeightForWidth()) 323 | self.line.setSizePolicy(sizePolicy) 324 | self.line.setMaximumSize(QtCore.QSize(10, 16777215)) 325 | self.line.setFrameShape(QtWidgets.QFrame.VLine) 326 | self.line.setFrameShadow(QtWidgets.QFrame.Sunken) 327 | self.line.setObjectName("line") 328 | self.gridLayout.addWidget(self.line, 0, 1, 1, 1) 329 | self.splitter = QtWidgets.QSplitter(Form) 330 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) 331 | sizePolicy.setHorizontalStretch(1) 332 | sizePolicy.setVerticalStretch(1) 333 | sizePolicy.setHeightForWidth(self.splitter.sizePolicy().hasHeightForWidth()) 334 | self.splitter.setSizePolicy(sizePolicy) 335 | self.splitter.setMinimumSize(QtCore.QSize(0, 0)) 336 | self.splitter.setOrientation(QtCore.Qt.Vertical) 337 | self.splitter.setObjectName("splitter") 338 | self.layoutWidget = QtWidgets.QWidget(self.splitter) 339 | self.layoutWidget.setObjectName("layoutWidget") 340 | self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.layoutWidget) 341 | self.verticalLayout_2.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint) 342 | self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) 343 | self.verticalLayout_2.setObjectName("verticalLayout_2") 344 | self.label = QtWidgets.QLabel(self.layoutWidget) 345 | self.label.setObjectName("label") 346 | self.verticalLayout_2.addWidget(self.label) 347 | self.textEdit = QtWidgets.QTextEdit(self.layoutWidget) 348 | self.textEdit.setObjectName("textEdit") 349 | self.verticalLayout_2.addWidget(self.textEdit) 350 | self.layoutWidget1 = QtWidgets.QWidget(self.splitter) 351 | self.layoutWidget1.setObjectName("layoutWidget1") 352 | self.verticalLayout = QtWidgets.QVBoxLayout(self.layoutWidget1) 353 | self.verticalLayout.setContentsMargins(0, 0, 0, 0) 354 | self.verticalLayout.setObjectName("verticalLayout") 355 | self.label_2 = QtWidgets.QLabel(self.layoutWidget1) 356 | self.label_2.setObjectName("label_2") 357 | self.verticalLayout.addWidget(self.label_2) 358 | self.textEdit_2 = QtWidgets.QTextEdit(self.layoutWidget1) 359 | self.textEdit_2.setObjectName("textEdit_2") 360 | self.verticalLayout.addWidget(self.textEdit_2) 361 | self.gridLayout.addWidget(self.splitter, 0, 2, 1, 1) 362 | 363 | self.retranslateUi(Form) 364 | QtCore.QMetaObject.connectSlotsByName(Form) 365 | 366 | def retranslateUi(self, Form): 367 | Form.setWindowTitle(QtWidgets.QApplication.translate("Form", "EA Heap", None)) 368 | self.label_3.setText(QtWidgets.QApplication.translate("Form", "In Use Chunks", None)) 369 | self.checkBox.setText(QtWidgets.QApplication.translate("Form", "Enable Malloc Trace", None)) 370 | self.label_9.setText(QtWidgets.QApplication.translate("Form", "Bins", None)) 371 | self.label_7.setText(QtWidgets.QApplication.translate("Form", "Fastbins", None)) 372 | self.label_8.setText(QtWidgets.QApplication.translate("Form", "Bin Chunks", None)) 373 | self.pushButton_2.setText(QtWidgets.QApplication.translate("Form", "Set Offsets", None)) 374 | self.pushButton.setText(QtWidgets.QApplication.translate("Form", "Refresh", None)) 375 | self.label.setText(QtWidgets.QApplication.translate("Form", "HexDump", None)) 376 | self.label_2.setText(QtWidgets.QApplication.translate("Form", "Chunk Info", None)) 377 | 378 | 379 | class Reskin_UI(object): 380 | def setupUi(self, Form): 381 | Form.setObjectName("Form") 382 | Form.resize(395, 548) 383 | self.verticalLayout = QtWidgets.QVBoxLayout(Form) 384 | self.verticalLayout.setObjectName("verticalLayout") 385 | self.horizontalLayout_10 = QtWidgets.QHBoxLayout() 386 | self.horizontalLayout_10.setObjectName("horizontalLayout_10") 387 | self.comboBox = QtWidgets.QComboBox(Form) 388 | self.comboBox.setObjectName("comboBox") 389 | self.horizontalLayout_10.addWidget(self.comboBox) 390 | self.horizontalLayout_12 = QtWidgets.QHBoxLayout() 391 | self.horizontalLayout_12.setObjectName("horizontalLayout_12") 392 | self.pushButton_18 = QtWidgets.QPushButton(Form) 393 | self.pushButton_18.setObjectName("pushButton_18") 394 | self.horizontalLayout_12.addWidget(self.pushButton_18) 395 | self.pushButton_19 = QtWidgets.QPushButton(Form) 396 | self.pushButton_19.setObjectName("pushButton_19") 397 | self.horizontalLayout_12.addWidget(self.pushButton_19) 398 | self.checkBox = QtWidgets.QCheckBox(Form) 399 | self.checkBox.setObjectName("checkBox") 400 | self.horizontalLayout_12.addWidget(self.checkBox) 401 | self.horizontalLayout_10.addLayout(self.horizontalLayout_12) 402 | self.verticalLayout.addLayout(self.horizontalLayout_10) 403 | self.label = QtWidgets.QLabel(Form) 404 | self.label.setObjectName("label") 405 | self.verticalLayout.addWidget(self.label) 406 | self.horizontalLayout = QtWidgets.QHBoxLayout() 407 | self.horizontalLayout.setObjectName("horizontalLayout") 408 | self.pushButton = QtWidgets.QPushButton(Form) 409 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 410 | sizePolicy.setHorizontalStretch(0) 411 | sizePolicy.setVerticalStretch(0) 412 | sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth()) 413 | self.pushButton.setSizePolicy(sizePolicy) 414 | self.pushButton.setMinimumSize(QtCore.QSize(0, 0)) 415 | self.pushButton.setText("") 416 | self.pushButton.setObjectName("pushButton") 417 | self.horizontalLayout.addWidget(self.pushButton) 418 | self.pushButton_2 = QtWidgets.QPushButton(Form) 419 | self.pushButton_2.setEnabled(True) 420 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) 421 | sizePolicy.setHorizontalStretch(0) 422 | sizePolicy.setVerticalStretch(0) 423 | sizePolicy.setHeightForWidth(self.pushButton_2.sizePolicy().hasHeightForWidth()) 424 | self.pushButton_2.setSizePolicy(sizePolicy) 425 | self.pushButton_2.setObjectName("pushButton_2") 426 | self.horizontalLayout.addWidget(self.pushButton_2) 427 | self.verticalLayout.addLayout(self.horizontalLayout) 428 | self.horizontalLayout_14 = QtWidgets.QHBoxLayout() 429 | self.horizontalLayout_14.setObjectName("horizontalLayout_14") 430 | self.pushButton_23 = QtWidgets.QPushButton(Form) 431 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 432 | sizePolicy.setHorizontalStretch(0) 433 | sizePolicy.setVerticalStretch(0) 434 | sizePolicy.setHeightForWidth(self.pushButton_23.sizePolicy().hasHeightForWidth()) 435 | self.pushButton_23.setSizePolicy(sizePolicy) 436 | self.pushButton_23.setMinimumSize(QtCore.QSize(0, 0)) 437 | self.pushButton_23.setText("") 438 | self.pushButton_23.setObjectName("pushButton_23") 439 | self.horizontalLayout_14.addWidget(self.pushButton_23) 440 | self.pushButton_24 = QtWidgets.QPushButton(Form) 441 | self.pushButton_24.setEnabled(True) 442 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) 443 | sizePolicy.setHorizontalStretch(0) 444 | sizePolicy.setVerticalStretch(0) 445 | sizePolicy.setHeightForWidth(self.pushButton_24.sizePolicy().hasHeightForWidth()) 446 | self.pushButton_24.setSizePolicy(sizePolicy) 447 | self.pushButton_24.setObjectName("pushButton_24") 448 | self.horizontalLayout_14.addWidget(self.pushButton_24) 449 | self.verticalLayout.addLayout(self.horizontalLayout_14) 450 | self.horizontalLayout_15 = QtWidgets.QHBoxLayout() 451 | self.horizontalLayout_15.setObjectName("horizontalLayout_15") 452 | self.pushButton_25 = QtWidgets.QPushButton(Form) 453 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 454 | sizePolicy.setHorizontalStretch(0) 455 | sizePolicy.setVerticalStretch(0) 456 | sizePolicy.setHeightForWidth(self.pushButton_25.sizePolicy().hasHeightForWidth()) 457 | self.pushButton_25.setSizePolicy(sizePolicy) 458 | self.pushButton_25.setMinimumSize(QtCore.QSize(0, 0)) 459 | self.pushButton_25.setText("") 460 | self.pushButton_25.setObjectName("pushButton_25") 461 | self.horizontalLayout_15.addWidget(self.pushButton_25) 462 | self.pushButton_26 = QtWidgets.QPushButton(Form) 463 | self.pushButton_26.setEnabled(True) 464 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) 465 | sizePolicy.setHorizontalStretch(0) 466 | sizePolicy.setVerticalStretch(0) 467 | sizePolicy.setHeightForWidth(self.pushButton_26.sizePolicy().hasHeightForWidth()) 468 | self.pushButton_26.setSizePolicy(sizePolicy) 469 | self.pushButton_26.setObjectName("pushButton_26") 470 | self.horizontalLayout_15.addWidget(self.pushButton_26) 471 | self.verticalLayout.addLayout(self.horizontalLayout_15) 472 | self.horizontalLayout_5 = QtWidgets.QHBoxLayout() 473 | self.horizontalLayout_5.setObjectName("horizontalLayout_5") 474 | self.pushButton_9 = QtWidgets.QPushButton(Form) 475 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 476 | sizePolicy.setHorizontalStretch(0) 477 | sizePolicy.setVerticalStretch(0) 478 | sizePolicy.setHeightForWidth(self.pushButton_9.sizePolicy().hasHeightForWidth()) 479 | self.pushButton_9.setSizePolicy(sizePolicy) 480 | self.pushButton_9.setMinimumSize(QtCore.QSize(0, 0)) 481 | self.pushButton_9.setText("") 482 | self.pushButton_9.setObjectName("pushButton_9") 483 | self.horizontalLayout_5.addWidget(self.pushButton_9) 484 | self.pushButton_10 = QtWidgets.QPushButton(Form) 485 | self.pushButton_10.setEnabled(True) 486 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) 487 | sizePolicy.setHorizontalStretch(0) 488 | sizePolicy.setVerticalStretch(0) 489 | sizePolicy.setHeightForWidth(self.pushButton_10.sizePolicy().hasHeightForWidth()) 490 | self.pushButton_10.setSizePolicy(sizePolicy) 491 | self.pushButton_10.setObjectName("pushButton_10") 492 | self.horizontalLayout_5.addWidget(self.pushButton_10) 493 | self.verticalLayout.addLayout(self.horizontalLayout_5) 494 | self.horizontalLayout_7 = QtWidgets.QHBoxLayout() 495 | self.horizontalLayout_7.setObjectName("horizontalLayout_7") 496 | self.pushButton_13 = QtWidgets.QPushButton(Form) 497 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 498 | sizePolicy.setHorizontalStretch(0) 499 | sizePolicy.setVerticalStretch(0) 500 | sizePolicy.setHeightForWidth(self.pushButton_13.sizePolicy().hasHeightForWidth()) 501 | self.pushButton_13.setSizePolicy(sizePolicy) 502 | self.pushButton_13.setMinimumSize(QtCore.QSize(0, 0)) 503 | self.pushButton_13.setText("") 504 | self.pushButton_13.setObjectName("pushButton_13") 505 | self.horizontalLayout_7.addWidget(self.pushButton_13) 506 | self.pushButton_14 = QtWidgets.QPushButton(Form) 507 | self.pushButton_14.setEnabled(True) 508 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) 509 | sizePolicy.setHorizontalStretch(0) 510 | sizePolicy.setVerticalStretch(0) 511 | sizePolicy.setHeightForWidth(self.pushButton_14.sizePolicy().hasHeightForWidth()) 512 | self.pushButton_14.setSizePolicy(sizePolicy) 513 | self.pushButton_14.setObjectName("pushButton_14") 514 | self.horizontalLayout_7.addWidget(self.pushButton_14) 515 | self.verticalLayout.addLayout(self.horizontalLayout_7) 516 | self.horizontalLayout_16 = QtWidgets.QHBoxLayout() 517 | self.horizontalLayout_16.setObjectName("horizontalLayout_16") 518 | self.pushButton_27 = QtWidgets.QPushButton(Form) 519 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 520 | sizePolicy.setHorizontalStretch(0) 521 | sizePolicy.setVerticalStretch(0) 522 | sizePolicy.setHeightForWidth(self.pushButton_27.sizePolicy().hasHeightForWidth()) 523 | self.pushButton_27.setSizePolicy(sizePolicy) 524 | self.pushButton_27.setMinimumSize(QtCore.QSize(0, 0)) 525 | self.pushButton_27.setText("") 526 | self.pushButton_27.setObjectName("pushButton_27") 527 | self.horizontalLayout_16.addWidget(self.pushButton_27) 528 | self.pushButton_28 = QtWidgets.QPushButton(Form) 529 | self.pushButton_28.setEnabled(True) 530 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) 531 | sizePolicy.setHorizontalStretch(0) 532 | sizePolicy.setVerticalStretch(0) 533 | sizePolicy.setHeightForWidth(self.pushButton_28.sizePolicy().hasHeightForWidth()) 534 | self.pushButton_28.setSizePolicy(sizePolicy) 535 | self.pushButton_28.setObjectName("pushButton_28") 536 | self.horizontalLayout_16.addWidget(self.pushButton_28) 537 | self.verticalLayout.addLayout(self.horizontalLayout_16) 538 | self.horizontalLayout_13 = QtWidgets.QHBoxLayout() 539 | self.horizontalLayout_13.setObjectName("horizontalLayout_13") 540 | self.pushButton_21 = QtWidgets.QPushButton(Form) 541 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 542 | sizePolicy.setHorizontalStretch(0) 543 | sizePolicy.setVerticalStretch(0) 544 | sizePolicy.setHeightForWidth(self.pushButton_21.sizePolicy().hasHeightForWidth()) 545 | self.pushButton_21.setSizePolicy(sizePolicy) 546 | self.pushButton_21.setMinimumSize(QtCore.QSize(0, 0)) 547 | self.pushButton_21.setText("") 548 | self.pushButton_21.setObjectName("pushButton_21") 549 | self.horizontalLayout_13.addWidget(self.pushButton_21) 550 | self.pushButton_22 = QtWidgets.QPushButton(Form) 551 | self.pushButton_22.setEnabled(True) 552 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) 553 | sizePolicy.setHorizontalStretch(0) 554 | sizePolicy.setVerticalStretch(0) 555 | sizePolicy.setHeightForWidth(self.pushButton_22.sizePolicy().hasHeightForWidth()) 556 | self.pushButton_22.setSizePolicy(sizePolicy) 557 | self.pushButton_22.setObjectName("pushButton_22") 558 | self.horizontalLayout_13.addWidget(self.pushButton_22) 559 | self.verticalLayout.addLayout(self.horizontalLayout_13) 560 | self.horizontalLayout_8 = QtWidgets.QHBoxLayout() 561 | self.horizontalLayout_8.setObjectName("horizontalLayout_8") 562 | self.pushButton_15 = QtWidgets.QPushButton(Form) 563 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 564 | sizePolicy.setHorizontalStretch(0) 565 | sizePolicy.setVerticalStretch(0) 566 | sizePolicy.setHeightForWidth(self.pushButton_15.sizePolicy().hasHeightForWidth()) 567 | self.pushButton_15.setSizePolicy(sizePolicy) 568 | self.pushButton_15.setMinimumSize(QtCore.QSize(0, 0)) 569 | self.pushButton_15.setText("") 570 | self.pushButton_15.setObjectName("pushButton_15") 571 | self.horizontalLayout_8.addWidget(self.pushButton_15) 572 | self.pushButton_16 = QtWidgets.QPushButton(Form) 573 | self.pushButton_16.setEnabled(True) 574 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) 575 | sizePolicy.setHorizontalStretch(0) 576 | sizePolicy.setVerticalStretch(0) 577 | sizePolicy.setHeightForWidth(self.pushButton_16.sizePolicy().hasHeightForWidth()) 578 | self.pushButton_16.setSizePolicy(sizePolicy) 579 | self.pushButton_16.setObjectName("pushButton_16") 580 | self.horizontalLayout_8.addWidget(self.pushButton_16) 581 | self.verticalLayout.addLayout(self.horizontalLayout_8) 582 | self.horizontalLayout_6 = QtWidgets.QHBoxLayout() 583 | self.horizontalLayout_6.setObjectName("horizontalLayout_6") 584 | self.pushButton_11 = QtWidgets.QPushButton(Form) 585 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 586 | sizePolicy.setHorizontalStretch(0) 587 | sizePolicy.setVerticalStretch(0) 588 | sizePolicy.setHeightForWidth(self.pushButton_11.sizePolicy().hasHeightForWidth()) 589 | self.pushButton_11.setSizePolicy(sizePolicy) 590 | self.pushButton_11.setMinimumSize(QtCore.QSize(0, 0)) 591 | self.pushButton_11.setText("") 592 | self.pushButton_11.setObjectName("pushButton_11") 593 | self.horizontalLayout_6.addWidget(self.pushButton_11) 594 | self.pushButton_12 = QtWidgets.QPushButton(Form) 595 | self.pushButton_12.setEnabled(True) 596 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) 597 | sizePolicy.setHorizontalStretch(0) 598 | sizePolicy.setVerticalStretch(0) 599 | sizePolicy.setHeightForWidth(self.pushButton_12.sizePolicy().hasHeightForWidth()) 600 | self.pushButton_12.setSizePolicy(sizePolicy) 601 | self.pushButton_12.setObjectName("pushButton_12") 602 | self.horizontalLayout_6.addWidget(self.pushButton_12) 603 | self.verticalLayout.addLayout(self.horizontalLayout_6) 604 | self.label_2 = QtWidgets.QLabel(Form) 605 | self.label_2.setObjectName("label_2") 606 | self.verticalLayout.addWidget(self.label_2) 607 | self.horizontalLayout_23 = QtWidgets.QHBoxLayout() 608 | self.horizontalLayout_23.setObjectName("horizontalLayout_23") 609 | self.pushButton_43 = QtWidgets.QPushButton(Form) 610 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 611 | sizePolicy.setHorizontalStretch(0) 612 | sizePolicy.setVerticalStretch(0) 613 | sizePolicy.setHeightForWidth(self.pushButton_43.sizePolicy().hasHeightForWidth()) 614 | self.pushButton_43.setSizePolicy(sizePolicy) 615 | self.pushButton_43.setMinimumSize(QtCore.QSize(0, 0)) 616 | self.pushButton_43.setText("") 617 | self.pushButton_43.setObjectName("pushButton_43") 618 | self.horizontalLayout_23.addWidget(self.pushButton_43) 619 | self.checkBox_2 = QtWidgets.QCheckBox(Form) 620 | self.checkBox_2.setObjectName("checkBox_2") 621 | self.horizontalLayout_23.addWidget(self.checkBox_2) 622 | self.pushButton_44 = QtWidgets.QPushButton(Form) 623 | self.pushButton_44.setEnabled(True) 624 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) 625 | sizePolicy.setHorizontalStretch(0) 626 | sizePolicy.setVerticalStretch(0) 627 | sizePolicy.setHeightForWidth(self.pushButton_44.sizePolicy().hasHeightForWidth()) 628 | self.pushButton_44.setSizePolicy(sizePolicy) 629 | self.pushButton_44.setObjectName("pushButton_44") 630 | self.horizontalLayout_23.addWidget(self.pushButton_44) 631 | self.verticalLayout.addLayout(self.horizontalLayout_23) 632 | self.horizontalLayout_2 = QtWidgets.QHBoxLayout() 633 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 634 | self.pushButton_3 = QtWidgets.QPushButton(Form) 635 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 636 | sizePolicy.setHorizontalStretch(0) 637 | sizePolicy.setVerticalStretch(0) 638 | sizePolicy.setHeightForWidth(self.pushButton_3.sizePolicy().hasHeightForWidth()) 639 | self.pushButton_3.setSizePolicy(sizePolicy) 640 | self.pushButton_3.setMinimumSize(QtCore.QSize(0, 0)) 641 | self.pushButton_3.setText("") 642 | self.pushButton_3.setObjectName("pushButton_3") 643 | self.horizontalLayout_2.addWidget(self.pushButton_3) 644 | self.pushButton_4 = QtWidgets.QPushButton(Form) 645 | self.pushButton_4.setEnabled(True) 646 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) 647 | sizePolicy.setHorizontalStretch(0) 648 | sizePolicy.setVerticalStretch(0) 649 | sizePolicy.setHeightForWidth(self.pushButton_4.sizePolicy().hasHeightForWidth()) 650 | self.pushButton_4.setSizePolicy(sizePolicy) 651 | self.pushButton_4.setObjectName("pushButton_4") 652 | self.horizontalLayout_2.addWidget(self.pushButton_4) 653 | self.verticalLayout.addLayout(self.horizontalLayout_2) 654 | self.horizontalLayout_18 = QtWidgets.QHBoxLayout() 655 | self.horizontalLayout_18.setObjectName("horizontalLayout_18") 656 | self.pushButton_31 = QtWidgets.QPushButton(Form) 657 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 658 | sizePolicy.setHorizontalStretch(0) 659 | sizePolicy.setVerticalStretch(0) 660 | sizePolicy.setHeightForWidth(self.pushButton_31.sizePolicy().hasHeightForWidth()) 661 | self.pushButton_31.setSizePolicy(sizePolicy) 662 | self.pushButton_31.setMinimumSize(QtCore.QSize(0, 0)) 663 | self.pushButton_31.setText("") 664 | self.pushButton_31.setObjectName("pushButton_31") 665 | self.horizontalLayout_18.addWidget(self.pushButton_31) 666 | self.pushButton_32 = QtWidgets.QPushButton(Form) 667 | self.pushButton_32.setEnabled(True) 668 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) 669 | sizePolicy.setHorizontalStretch(0) 670 | sizePolicy.setVerticalStretch(0) 671 | sizePolicy.setHeightForWidth(self.pushButton_32.sizePolicy().hasHeightForWidth()) 672 | self.pushButton_32.setSizePolicy(sizePolicy) 673 | self.pushButton_32.setObjectName("pushButton_32") 674 | self.horizontalLayout_18.addWidget(self.pushButton_32) 675 | self.verticalLayout.addLayout(self.horizontalLayout_18) 676 | self.horizontalLayout_17 = QtWidgets.QHBoxLayout() 677 | self.horizontalLayout_17.setObjectName("horizontalLayout_17") 678 | self.pushButton_29 = QtWidgets.QPushButton(Form) 679 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 680 | sizePolicy.setHorizontalStretch(0) 681 | sizePolicy.setVerticalStretch(0) 682 | sizePolicy.setHeightForWidth(self.pushButton_29.sizePolicy().hasHeightForWidth()) 683 | self.pushButton_29.setSizePolicy(sizePolicy) 684 | self.pushButton_29.setMinimumSize(QtCore.QSize(0, 0)) 685 | self.pushButton_29.setText("") 686 | self.pushButton_29.setObjectName("pushButton_29") 687 | self.horizontalLayout_17.addWidget(self.pushButton_29) 688 | self.pushButton_30 = QtWidgets.QPushButton(Form) 689 | self.pushButton_30.setEnabled(True) 690 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) 691 | sizePolicy.setHorizontalStretch(0) 692 | sizePolicy.setVerticalStretch(0) 693 | sizePolicy.setHeightForWidth(self.pushButton_30.sizePolicy().hasHeightForWidth()) 694 | self.pushButton_30.setSizePolicy(sizePolicy) 695 | self.pushButton_30.setObjectName("pushButton_30") 696 | self.horizontalLayout_17.addWidget(self.pushButton_30) 697 | self.verticalLayout.addLayout(self.horizontalLayout_17) 698 | self.horizontalLayout_9 = QtWidgets.QHBoxLayout() 699 | self.horizontalLayout_9.setObjectName("horizontalLayout_9") 700 | self.pushButton_33 = QtWidgets.QPushButton(Form) 701 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) 702 | sizePolicy.setHorizontalStretch(0) 703 | sizePolicy.setVerticalStretch(0) 704 | sizePolicy.setHeightForWidth(self.pushButton_33.sizePolicy().hasHeightForWidth()) 705 | self.pushButton_33.setSizePolicy(sizePolicy) 706 | self.pushButton_33.setMinimumSize(QtCore.QSize(0, 0)) 707 | self.pushButton_33.setText("") 708 | self.pushButton_33.setObjectName("pushButton_33") 709 | self.horizontalLayout_9.addWidget(self.pushButton_33) 710 | self.pushButton_34 = QtWidgets.QPushButton(Form) 711 | self.pushButton_34.setEnabled(True) 712 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) 713 | sizePolicy.setHorizontalStretch(0) 714 | sizePolicy.setVerticalStretch(0) 715 | sizePolicy.setHeightForWidth(self.pushButton_34.sizePolicy().hasHeightForWidth()) 716 | self.pushButton_34.setSizePolicy(sizePolicy) 717 | self.pushButton_34.setObjectName("pushButton_34") 718 | self.horizontalLayout_9.addWidget(self.pushButton_34) 719 | self.verticalLayout.addLayout(self.horizontalLayout_9) 720 | self.horizontalLayout_11 = QtWidgets.QHBoxLayout() 721 | self.horizontalLayout_11.setObjectName("horizontalLayout_11") 722 | self.pushButton_20 = QtWidgets.QPushButton(Form) 723 | self.pushButton_20.setObjectName("pushButton_20") 724 | self.horizontalLayout_11.addWidget(self.pushButton_20) 725 | self.pushButton_17 = QtWidgets.QPushButton(Form) 726 | self.pushButton_17.setMaximumSize(QtCore.QSize(16777215, 16777215)) 727 | self.pushButton_17.setObjectName("pushButton_17") 728 | self.horizontalLayout_11.addWidget(self.pushButton_17) 729 | self.verticalLayout.addLayout(self.horizontalLayout_11) 730 | 731 | self.retranslateUi(Form) 732 | QtCore.QMetaObject.connectSlotsByName(Form) 733 | 734 | def retranslateUi(self, Form): 735 | Form.setWindowTitle(QtWidgets.QApplication.translate("Form", "EA Reskin", None)) 736 | self.pushButton_18.setText(QtWidgets.QApplication.translate("Form", "Save As", None)) 737 | self.pushButton_19.setText(QtWidgets.QApplication.translate("Form", "Delete", None)) 738 | self.checkBox.setText(QtWidgets.QApplication.translate("Form", "Apply Skin On startup", None)) 739 | self.label.setText(QtWidgets.QApplication.translate("Form", "IDA:", None)) 740 | self.pushButton_2.setText(QtWidgets.QApplication.translate("Form", "Background Color", None)) 741 | self.pushButton_24.setText(QtWidgets.QApplication.translate("Form", "Text Color", None)) 742 | self.pushButton_26.setText(QtWidgets.QApplication.translate("Form", "Handles", None)) 743 | self.pushButton_10.setText(QtWidgets.QApplication.translate("Form", "Button Outline", None)) 744 | self.pushButton_14.setText(QtWidgets.QApplication.translate("Form", "Menu Selected", None)) 745 | self.pushButton_28.setText(QtWidgets.QApplication.translate("Form", "List Headers", None)) 746 | self.pushButton_22.setText(QtWidgets.QApplication.translate("Form", "List Selected", None)) 747 | self.pushButton_16.setText(QtWidgets.QApplication.translate("Form", "Field Hover", None)) 748 | self.pushButton_12.setText(QtWidgets.QApplication.translate("Form", "Tab Selected", None)) 749 | self.label_2.setText(QtWidgets.QApplication.translate("Form", "EA View:", None)) 750 | self.checkBox_2.setText(QtWidgets.QApplication.translate("Form", "Match IDA Background", None)) 751 | self.pushButton_44.setText(QtWidgets.QApplication.translate("Form", "Background Color", None)) 752 | self.pushButton_4.setText(QtWidgets.QApplication.translate("Form", "Executable Memory", None)) 753 | self.pushButton_32.setText(QtWidgets.QApplication.translate("Form", "Readable/Writeable Memory", None)) 754 | self.pushButton_30.setText(QtWidgets.QApplication.translate("Form", "String", None)) 755 | self.pushButton_34.setText(QtWidgets.QApplication.translate("Form", "Null", None)) 756 | self.pushButton_20.setText(QtWidgets.QApplication.translate("Form", "Apply", None)) 757 | self.pushButton_17.setText(QtWidgets.QApplication.translate("Form", "Set Code Colors", None)) 758 | 759 | 760 | 761 | class Name_UI(object): 762 | def setupUi(self, Form): 763 | Form.setObjectName("Form") 764 | Form.resize(400, 69) 765 | self.verticalLayout = QtWidgets.QVBoxLayout(Form) 766 | self.verticalLayout.setObjectName("verticalLayout") 767 | self.horizontalLayout = QtWidgets.QHBoxLayout() 768 | self.horizontalLayout.setObjectName("horizontalLayout") 769 | self.label = QtWidgets.QLabel(Form) 770 | self.label.setObjectName("label") 771 | self.horizontalLayout.addWidget(self.label) 772 | self.lineEdit = QtWidgets.QLineEdit(Form) 773 | self.lineEdit.setObjectName("lineEdit") 774 | self.horizontalLayout.addWidget(self.lineEdit) 775 | self.verticalLayout.addLayout(self.horizontalLayout) 776 | self.pushButton = QtWidgets.QPushButton(Form) 777 | self.pushButton.setObjectName("pushButton") 778 | self.verticalLayout.addWidget(self.pushButton) 779 | 780 | self.retranslateUi(Form) 781 | QtCore.QMetaObject.connectSlotsByName(Form) 782 | 783 | def retranslateUi(self, Form): 784 | Form.setWindowTitle(QtWidgets.QApplication.translate("Form", "Set Name", None)) 785 | self.label.setText(QtWidgets.QApplication.translate("Form", "Name:", None)) 786 | self.pushButton.setText(QtWidgets.QApplication.translate("Form", "Save", None)) 787 | 788 | 789 | 790 | class Cmd_UI(object): 791 | def setupUi(self, Form): 792 | Form.setObjectName("Form") 793 | Form.resize(677, 378) 794 | self.verticalLayout_2 = QtWidgets.QVBoxLayout(Form) 795 | self.verticalLayout_2.setObjectName("verticalLayout_2") 796 | self.textEdit = QtWidgets.QTextEdit(Form) 797 | self.textEdit.setObjectName("textEdit") 798 | self.verticalLayout_2.addWidget(self.textEdit) 799 | self.horizontalLayout_2 = QtWidgets.QHBoxLayout() 800 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 801 | self.label = QtWidgets.QLabel(Form) 802 | self.label.setObjectName("label") 803 | self.horizontalLayout_2.addWidget(self.label) 804 | self.lineEdit = QtWidgets.QLineEdit(Form) 805 | self.lineEdit.setObjectName("lineEdit") 806 | self.horizontalLayout_2.addWidget(self.lineEdit) 807 | self.pushButton = QtWidgets.QPushButton(Form) 808 | self.pushButton.setObjectName("pushButton") 809 | self.horizontalLayout_2.addWidget(self.pushButton) 810 | self.verticalLayout_2.addLayout(self.horizontalLayout_2) 811 | 812 | self.retranslateUi(Form) 813 | QtCore.QMetaObject.connectSlotsByName(Form) 814 | 815 | def retranslateUi(self, Form): 816 | Form.setWindowTitle(QtWidgets.QApplication.translate("Form", "EA CMD", None)) 817 | self.label.setText(QtWidgets.QApplication.translate("Form", "CMD:", None)) 818 | self.pushButton.setText(QtWidgets.QApplication.translate("Form", "Go!", None)) 819 | 820 | 821 | class Trace_UI(object): 822 | def setupUi(self, Form): 823 | Form.setObjectName("Form") 824 | Form.resize(403, 219) 825 | self.verticalLayout = QtWidgets.QVBoxLayout(Form) 826 | self.verticalLayout.setObjectName("verticalLayout") 827 | self.horizontalLayout_4 = QtWidgets.QHBoxLayout() 828 | self.horizontalLayout_4.setObjectName("horizontalLayout_4") 829 | self.label_4 = QtWidgets.QLabel(Form) 830 | self.label_4.setObjectName("label_4") 831 | self.horizontalLayout_4.addWidget(self.label_4) 832 | self.pushButton_4 = QtWidgets.QPushButton(Form) 833 | self.pushButton_4.setObjectName("pushButton_4") 834 | self.horizontalLayout_4.addWidget(self.pushButton_4) 835 | self.verticalLayout.addLayout(self.horizontalLayout_4) 836 | self.line = QtWidgets.QFrame(Form) 837 | self.line.setFrameShape(QtWidgets.QFrame.HLine) 838 | self.line.setFrameShadow(QtWidgets.QFrame.Sunken) 839 | self.line.setObjectName("line") 840 | self.verticalLayout.addWidget(self.line) 841 | self.label_3 = QtWidgets.QLabel(Form) 842 | self.label_3.setObjectName("label_3") 843 | self.verticalLayout.addWidget(self.label_3) 844 | self.horizontalLayout = QtWidgets.QHBoxLayout() 845 | self.horizontalLayout.setObjectName("horizontalLayout") 846 | self.lineEdit = QtWidgets.QLineEdit(Form) 847 | self.lineEdit.setObjectName("lineEdit") 848 | self.horizontalLayout.addWidget(self.lineEdit) 849 | self.pushButton = QtWidgets.QPushButton(Form) 850 | self.pushButton.setObjectName("pushButton") 851 | self.horizontalLayout.addWidget(self.pushButton) 852 | self.verticalLayout.addLayout(self.horizontalLayout) 853 | self.label_2 = QtWidgets.QLabel(Form) 854 | self.label_2.setObjectName("label_2") 855 | self.verticalLayout.addWidget(self.label_2) 856 | self.horizontalLayout_2 = QtWidgets.QHBoxLayout() 857 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 858 | self.checkBox = QtWidgets.QCheckBox(Form) 859 | self.checkBox.setObjectName("checkBox") 860 | self.horizontalLayout_2.addWidget(self.checkBox) 861 | self.checkBox_2 = QtWidgets.QCheckBox(Form) 862 | self.checkBox_2.setObjectName("checkBox_2") 863 | self.horizontalLayout_2.addWidget(self.checkBox_2) 864 | self.verticalLayout.addLayout(self.horizontalLayout_2) 865 | self.label = QtWidgets.QLabel(Form) 866 | self.label.setObjectName("label") 867 | self.verticalLayout.addWidget(self.label) 868 | self.horizontalLayout_3 = QtWidgets.QHBoxLayout() 869 | self.horizontalLayout_3.setObjectName("horizontalLayout_3") 870 | self.radioButton_2 = QtWidgets.QRadioButton(Form) 871 | self.radioButton_2.setObjectName("radioButton_2") 872 | self.horizontalLayout_3.addWidget(self.radioButton_2) 873 | self.radioButton = QtWidgets.QRadioButton(Form) 874 | self.radioButton.setObjectName("radioButton") 875 | self.horizontalLayout_3.addWidget(self.radioButton) 876 | self.verticalLayout.addLayout(self.horizontalLayout_3) 877 | self.pushButton_2 = QtWidgets.QPushButton(Form) 878 | self.pushButton_2.setObjectName("pushButton_2") 879 | self.verticalLayout.addWidget(self.pushButton_2) 880 | 881 | self.retranslateUi(Form) 882 | QtCore.QMetaObject.connectSlotsByName(Form) 883 | 884 | def retranslateUi(self, Form): 885 | Form.setWindowTitle(QtWidgets.QApplication.translate("Form", "Form", None)) 886 | self.label_4.setText(QtWidgets.QApplication.translate("Form", "Dump Browser:", None)) 887 | self.pushButton_4.setText(QtWidgets.QApplication.translate("Form", "Open Dump", None)) 888 | self.label_3.setText(QtWidgets.QApplication.translate("Form", "Dump Location:", None)) 889 | self.pushButton.setText(QtWidgets.QApplication.translate("Form", "Select Folder", None)) 890 | self.label_2.setText(QtWidgets.QApplication.translate("Form", "Include Regs:", None)) 891 | self.checkBox.setText(QtWidgets.QApplication.translate("Form", "General", None)) 892 | self.checkBox_2.setText(QtWidgets.QApplication.translate("Form", "Floating Point", None)) 893 | self.label.setText(QtWidgets.QApplication.translate("Form", "Dump On:", None)) 894 | self.radioButton_2.setText(QtWidgets.QApplication.translate("Form", "Exit", None)) 895 | self.radioButton.setText(QtWidgets.QApplication.translate("Form", "Breakpoint Hit", None)) 896 | self.pushButton_2.setText(QtWidgets.QApplication.translate("Form", "Go!", None)) 897 | 898 | 899 | class Emulate_UI(object): 900 | def setupUi(self, Form): 901 | Form.setObjectName("Form") 902 | Form.resize(376, 87) 903 | self.verticalLayout = QtWidgets.QVBoxLayout(Form) 904 | self.verticalLayout.setObjectName("verticalLayout") 905 | self.label = QtWidgets.QLabel(Form) 906 | self.label.setObjectName("label") 907 | self.verticalLayout.addWidget(self.label) 908 | self.horizontalLayout = QtWidgets.QHBoxLayout() 909 | self.horizontalLayout.setObjectName("horizontalLayout") 910 | self.checkBox_3 = QtWidgets.QCheckBox(Form) 911 | self.checkBox_3.setChecked(True) 912 | self.checkBox_3.setObjectName("checkBox_3") 913 | self.horizontalLayout.addWidget(self.checkBox_3) 914 | self.checkBox_2 = QtWidgets.QCheckBox(Form) 915 | self.checkBox_2.setChecked(True) 916 | self.checkBox_2.setObjectName("checkBox_2") 917 | self.horizontalLayout.addWidget(self.checkBox_2) 918 | self.checkBox = QtWidgets.QCheckBox(Form) 919 | self.checkBox.setObjectName("checkBox") 920 | self.horizontalLayout.addWidget(self.checkBox) 921 | self.verticalLayout.addLayout(self.horizontalLayout) 922 | self.horizontalLayout_2 = QtWidgets.QHBoxLayout() 923 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 924 | self.pushButton = QtWidgets.QPushButton(Form) 925 | self.pushButton.setObjectName("pushButton") 926 | self.horizontalLayout_2.addWidget(self.pushButton) 927 | self.pushButton_2 = QtWidgets.QPushButton(Form) 928 | self.pushButton_2.setObjectName("pushButton_2") 929 | self.horizontalLayout_2.addWidget(self.pushButton_2) 930 | self.verticalLayout.addLayout(self.horizontalLayout_2) 931 | 932 | self.retranslateUi(Form) 933 | QtCore.QMetaObject.connectSlotsByName(Form) 934 | 935 | def retranslateUi(self, Form): 936 | Form.setWindowTitle(QtWidgets.QApplication.translate("Form", "EA Emulate", None)) 937 | self.label.setText(QtWidgets.QApplication.translate("Form", "Options:", None)) 938 | self.checkBox_3.setText(QtWidgets.QApplication.translate("Form", "Annotate In IDA", None)) 939 | self.checkBox_2.setText(QtWidgets.QApplication.translate("Form", "Print In Server Window", None)) 940 | self.checkBox.setText(QtWidgets.QApplication.translate("Form", "Emulate On Break", None)) 941 | self.pushButton.setText(QtWidgets.QApplication.translate("Form", "Done", None)) 942 | self.pushButton_2.setText(QtWidgets.QApplication.translate("Form", "Emulate!", None)) 943 | 944 | --------------------------------------------------------------------------------