Open Ben-Lichtman opened 2 years ago
Here's the hacky workaround I'm using right now to be able to more easily filter gadgets:
import re
import fileinput
pm = r"(?:\+|\-)"
reg = r"([a-z]{2,3})"
sib = pm + r"(?:\d\*)?" + reg
imm = r"(?:0x)?[0-9a-f]"
disp = pm + imm
ws = r"\s*"
mem = f"\[{reg}{ws}(?:{sib})?{ws}(?:{disp})?\]"
insn = r'(?:mov|add|sub|adc|sbb)'
operands = f'(?:{reg},{ws}{reg}|{mem},{ws}{reg}|{reg},{ws}{mem})'
regex = f'{insn} {operands}'
regex = re.compile(regex)
# Customize this to the register you want
chosen = 'a'
# TODO: sort | uniq -f 1
for line in fileinput.input():
m = re.search(regex, line)
# Remove some useless instructions
line = line.replace(' endbr64;', '')
line = re.sub(' nop[^;]*;', '', line)
regs = {}
for l in ['a', 'b', 'c', 'd']:
regs[l] = [f"r{l}x", f"e{l}x", f"{l}x", f"{l}h", f"{l}l"]
for l in ['di', 'si']:
regs[l] = [f"r{l}", f"e{l}", f"{l}", f"{l}h", f"{l}l"]
if m:
for g in m.groups():
if g in regs[chosen]:
print(line.strip().ljust(32, ' '))
break
With this code I can do ropr ./bin | ./filter.py
and then get all gadgets that use any variant of the rax
register. This regex was too complex to put in the -R
flag. It shouldn't be hard for me to extend this further and also be able to ask whether I want to read or write from memory where the memory is indexed by a particular register.
Just sharing this as an example of what types of filters I'm interested in. Essentially I'd like to ask without regex: is this register set, is this register used to read memory from an address, and is this register used to write memory to an address, and I'd like to have these questions answered for any width of the register.
Maybe there's some easier way to achieve this without having the full system you describe, i.e. a gadget that utilizes two particular instructions.
Currently this makes it difficult to look for certain kinds of gadgets - such as a jop gadget which utilizes push then ret etc. There should be a better way to create gadget definitions.