Skip to content

Commit

Permalink
More fixes, bump to v1.6
Browse files Browse the repository at this point in the history
  • Loading branch information
lwerdna committed Aug 20, 2023
1 parent 4843ef9 commit b2db80f
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 36 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,10 @@ The plugin manager only installs and updates at release boundaries. If you want
## Developer Notes

https://docs.binary.ninja/dev/plugins.html

Tests that must pass before PR considered, release made, etc.

* file -> new binary data -> 1f 20 03 d5 1f 20 03 d5 1f 20 03 d5 1f 20 03 d5, create aarch64 function, now use keypatch to assemble at 0, 4, 8, and C the instruction `bl 0x1000`
* fill from [0x4, 0xc) with manually entered bytes AA AA AA AA and get two `orn x10, x21, x10, asr #0x2a`
* now fill from [0x4, 0xc) with assembled `nop`
* now search for `1f .*? d5` and it shoudl hit at every nop
75 changes: 40 additions & 35 deletions keypatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def is_valid_addr(bview, addr):
return False
# otherwise
else:
return addr >= bview.start and addr < (bview.start + len(bview))
return addr >= bview.start and addr < (bview.start + bview.length)

# given a valid address, return least address after the valid that is invalid
def get_invalid_addr(bview, addr):
Expand All @@ -161,7 +161,7 @@ def get_invalid_addr(bview, addr):
return end
# otherwise
else:
return bview.start + len(bv)
return bview.start + bview.length

# disassemble using binaryninja
# returns (<instruction_string>, <instruction_length>)
Expand Down Expand Up @@ -309,7 +309,7 @@ class AssembleTab(QWidget):
def __init__(self, context, parent=None):
super(AssembleTab, self).__init__(parent)
self.context = context
self.bv = context.binaryView
self.bview = context.binaryView

# other QLineEntry widgets to receive bytes upon assembling
self.qles_bytes = []
Expand Down Expand Up @@ -374,7 +374,7 @@ def __init__(self, context, parent=None):
self.qle_address.setText(hex(self.context.address))

# default assembly
(instxt, length) = disassemble_capstone_single(self.bv, context.address)
(instxt, length) = disassemble_capstone_single(self.bview, context.address)
if instxt:
self.qle_assembly.setText(instxt)
self.qle_fixedup.setText(instxt)
Expand Down Expand Up @@ -436,7 +436,7 @@ def re_assemble(self):
(ks, assembly, addr) = (self.ks(), self.asm(), self.addr())

# apply fixup
fixedup = fixup(self.bv, assembly)
fixedup = fixup(self.bview, assembly)
self.qle_fixedup.setText(fixedup)

# assemble
Expand All @@ -447,7 +447,7 @@ def re_assemble(self):

# pad with nops
if self.check_nops.isChecked():
length = disassemble_length(self.bv, self.addr())
length = disassemble_length(self.bview, self.addr())
if length != None and length > len(data):
nop = get_nop(self.arch())
sled = (length // len(nop)) * nop
Expand All @@ -473,10 +473,10 @@ def re_disassemble(self):
addr = self.addr()
data = bytes.fromhex(self.edit_bytes.text())

(disasm, length) = disassemble_capstone_single_data(self.bv, data, addr)
(disasm, length) = disassemble_capstone_single_data(self.bview, data, addr)
# pad with nops
if self.check_nops.isChecked():
length = disassemble_length(self.bv, self.addr())
length = disassemble_length(self.bview, self.addr())
if length != None and length > len(data):
nop = get_nop(self.arch())
sled = (length // len(nop)) * nop
Expand All @@ -500,18 +500,18 @@ def patch(self):
comment = None
try:
if self.check_save_original.isChecked():
(instxt, length) = disassemble_capstone_single(self.bv, self.addr())
(instxt, length) = disassemble_capstone_single(self.bview, self.addr())
if instxt and length:
comment = 'previously: ' + instxt
except Exception as e:
print(e)
pass

try:
with self.bv.undoable_transaction():
self.bv.write(self.addr(), data)
with self.bview.undoable_transaction():
self.bview.write(self.addr(), data)
if comment:
self.bv.set_comment_at(self.addr(), comment)
self.bview.set_comment_at(self.addr(), comment)
except Exception as e:
return

Expand All @@ -531,7 +531,7 @@ class FillRangeTab(QWidget):
def __init__(self, context, parent=None):
super(FillRangeTab, self).__init__(parent)
self.context = context
self.bv = context.binaryView
self.bview = context.binaryView

# this widget is VBox of QGroupBox
layoutV = QVBoxLayout()
Expand Down Expand Up @@ -591,20 +591,20 @@ def __init__(self, context, parent=None):
btn_fill.clicked.connect(self.fill)

# set defaults
nop = get_nop(binja_to_ks[bv_to_arch(self.bv)])
nop = get_nop(binja_to_ks[bv_to_arch(self.bview)])
if nop:
self.qle_bytes.setText(bytes_to_str(nop))

for (sname, section) in self.bv.sections.items():
section = self.bv.sections[sname]
for (sname, section) in self.bview.sections.items():
section = self.bview.sections[sname]
line = '%s [0x%X, 0x%X)' % (sname, section.start, section.start + section.length)
self.qcb_sections.addItem(line)

self.chk_encoding.setChecked(False)
self.chk_manual.setChecked(True)

self.qle_address.setText(hex(self.context.address))
end = get_invalid_addr(self.bv, self.context.address)
end = get_invalid_addr(self.bview, self.context.address)
if end != None:
self.qle_end.setText(hex(end))
btn_fill.setDefault(True)
Expand Down Expand Up @@ -730,7 +730,7 @@ def manual_checked_toggle(self, is_check):
self.chk_encoding.setChecked(not is_check)
self.preview()

# selections -> preview field
# elections -> preview field
def preview(self):
(_, _, fill_len) = self.interval()
if not fill_len: return None
Expand Down Expand Up @@ -779,10 +779,11 @@ def preview_by_size_change(self):

def fill(self):
# get, validate the interval
(left, right, length) = self.interval()
left, right, length = self.interval()
#print(f'filling [0x{left:X}, 0x{right:X}) length 0x{length:X}')
if left == None: return None
for a in [left, right - 1]:
if not is_valid_addr(self.bv, a):
if not is_valid_addr(self.bview, a):
self.error('0x%X invalid write address' % a)
return

Expand All @@ -796,8 +797,8 @@ def fill(self):
data = data[0:length]

# write it
# print('writing 0x%X bytes to 0x%X' % (len(data), left))
self.bv.write(left, data)
#print('writing 0x%X bytes to 0x%X' % (len(data), left))
self.bview.write(left, data)

# ------------------------------------------------------------------------------
# search tool
Expand All @@ -807,7 +808,7 @@ class SearchTab(QWidget):
def __init__(self, context, parent=None):
super(SearchTab, self).__init__(parent)
self.context = context
self.bv = context.binaryView
self.bview = context.binaryView

# this widget is VBox of QGroupBox
layoutV = QVBoxLayout()
Expand Down Expand Up @@ -886,30 +887,34 @@ def search(self):
self.list_results.show()

# loop through each section, searching it
bview = self.bv
width = max([len(sname) for sname in bview.sections])
for sname in bview.sections:
section = bview.sections[sname]
start = section.start
end = section.start + section.length
# print('searching section %s [0x%X, 0x%X)' % (sname, start, end))
bview = self.bview

intervals = []
if bview.sections:
width = max([len(sname) for sname in bview.sections])
intervals = [(n, s.start, s.start + s.length) for n,s in bview.sections.items()]
else:
# some views don't have sections, like File -> New Binary Data
width = 3
intervals = [('raw', bview.start, bview.end)]

for name, start, end in intervals:
#print(f'searching bytes in [0x{start:X}, 0x{end:X})')

# TODO: find better way
# bview.read already bytes type ... no need to convert or copy bytes
buf = bview.read(start, end - start)

for m in regobj.finditer(buf):
addr = section.start + m.start()
addr = start + m.start()

# m.group is bytes type
info = '%s %08X: %s' % (sname.rjust(width), addr, bytes_to_str(m.group()))
info = '%s %08X: %s' % (name.rjust(width), addr, bytes_to_str(m.group()))
self.list_results.addItem(QListWidgetItem(info))

def results_clicked(self, item):
# print('you double clicked %s' % item.text())
m = re.match(r'^.* ([a-fA-F0-9]+):', item.text())
addr = int(m.group(1), 16)
self.bv.navigate(self.bv.view, addr)
self.bview.navigate(self.bview.view, addr)

# ------------------------------------------------------------------------------
# top level tab gui
Expand Down
2 changes: 1 addition & 1 deletion plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@
"capstone"
]
},
"version": "1.5",
"version": "1.6",
"minimumbinaryninjaversion": 2660
}

1 comment on commit b2db80f

@gordboy
Copy link
Contributor

@gordboy gordboy commented on b2db80f Sep 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work my friend.

Moving the menu entry from Tools to Plugins was a great idea. If I find any issues with the other fixes and changes I'll file an Issue, in the usual way.

Please sign in to comment.