Closed elbee-cyber closed 6 months ago
This will require redoing GadgetSearch and adding cleaning constants
.constants:
cop_x86 = (
(b'\xff',2,b'\xff[\x10\x11\x12\x13\x16\x17]','call'), # call [reg]
(b'\xf2\xff',3,b'\xf2\xff[\x10\x11\x12\x13\x16\x17]','call'), # bnd call [reg]
(b'\xff',2,b'\xff[\xd0\xd1\xd2\xd3\xd4\xd6\xd7]','call'), # call reg
(b'\xf2\xff',3,b'\xf2\xff[\xd0\xd1\xd2\xd3\xd4\xd6\xd7]','call'), # bnd call reg
(b'\xff\x14\x24',3,b'\xff\x14\x24','call'), # call [rsp]
(b'\xf2\xff\x14\x24',4,b'\xf2\xff[\x14\x24]\x24','call'), # bnd call [rsp]
(b'\xff\x55\x00',3,b'\xff\x55\x00','call'), # call [rbp]
(b'\xf2\xff\x55\x00',4,b'\xf2\xff\x55\x00','call'), # bnd call [rbp]
(b'\xff',3,b'\xff[\x50-\x53\x55-\x57][\x00-\xff]{1}','call'), # call [reg+n]
(b'\xf2\xff',4,b'\xf2\xff[\x50-\x53\x55-\x57][\x00-\xff]{1}','call'), # bnd call [reg+n]
(b'\xe8',5,b'\xe8[\x00-\xff]{4}','call'), # call n
(b'\xff',6,b'\xff[\x90\x91\x92\x93\x94\x96\x97][\x00-\x0ff]{4}','call') # call [reg+n]
)
rop_x86 = (
(b'\xc3',1,b'\xc3','ret'), # ret
(b'\xc2',3,b'\xc2[\x00-\xff]{2}','ret') # ret n
)
jop_x86 = (
(b'\xff',2,b'\xff[\x20\x21\x22\x23\x26\x27]','jmp'), # jmp [reg]
(b'\xf2\xff',3,b'\xf2\xff[\x20\x21\x22\x23\x26\x27]','jmp'), # bnd jmp [reg]
(b'\xff',2,b'\xff[\xe0\xe1\xe2\xe3\xe4\xe6\xe7]','jmp'), # jmp reg
(b'\xf2\xff',3,b'\xf2\xff[\xe0\xe1\xe2\xe3\xe4\xe6\xe7]','jmp'), # bnd jmp reg
(b'\xff\x24\x24',3,b'\xff\x24\x24','jmp'), # jmp [rsp]
(b'\xf2\xff\x24\x24',4,b'\xf2\xff\x24\x24','jmp'), # bnd jmp [rsp]
(b'\xff\x65\x00',3,b'\xff\x65\x00','jmp') # jmp [rbp]
(b'\xf2\xff\x65\x00',4,b'\xf2\xff\x65\x00','jmp'), # bnd jmp [rbp]
(b'\xff',6,b'\xff[\xa0\xa1\xa2\xa3\xa6\xa7][\x00-\x0ff]{4}','jmp'), # jmp [reg+n]
(b'\xf2\xff',7,b'\xf2\xff[\xa0\xa1\xa2\xa3\xa6\xa7][\x00-\x0ff]{4}','jmp'), # bnd jmp [reg+n]
(b'\xff\xa4\x24',7,b'\xff\xa4\x24[\x00-\xff]{4}','jmp'), # jmp [rsp+n]
(b'\xf2\xff\xa4\x24',8,b'\xf2\xff\xa4\x24[\x00-\xff]{4}','jmp'), # bnd jmp [rsp+n]
(b'\xff',3,b'\xff[\x60-\x63\x65-\x67][\x00-\xff]{1}','jmp), # jmp [reg+n]
(b'\xf2\xff',4,b'\xf2\xff[\x60-\x63\x65-\x67][\x00-\xff]{1}','jmp'), # bnd jmp [reg+n]
(b'\xe9',5,b'\xe9[\x00-\xff]{4}','jmp') # jmp n
)
sys_x86 = (
(b'\xcd\x80',2,b'\xcd\x80','int 0x80'), # int 0x80
(b'\x0f\x05',2,b'\x0f\x05','syscall'), # syscall
(b'\x0f\x34',2,b'\0x0f\x34','sysenter'), # sysenter
(b'\x65\xff\x15\x10\x00\x00\x00',7,b'\x65\xff\x15\x10\x00\x00\x00','call gs:[10]') # call gs:[10]
)
ctrl_mnemonics_x86 = (
'jmp',
'ret',
'call',
'jne',
...
)
ctrl_x86 = {
"rop":rop_x86,
"jop":jop_x86,
"cop":cop_x86,
"sys":sys_x86,
"mnemonics":ctrl_mnemonics_x86
}
.gadgetsearch
# Combine ctrl pool based on options
control_insn = build_ctrl_pool()
for ctrl in control_insn:
curr_site = bv.start
# Search all of bv for current ctrl
while curr_site is not None:
# Find ctrl insn header constant
curr_site = bv.find_next_data(curr_site,ctrl[0])
if curr_site is None:
break
# Confirm site actually contains current ctrl insn
if re.match(ctrl[2],bv.read(curr_site,ctrl[1])) != None:
# Saved to increase next curr_site after depth search
save = curr_site
for i in range(0,depth):
if not bv.get_segment_at(curr_site).executable:
break
else:
disasm = capstone_process()
curr_site = save-i
insn = bv.read(curr_site,i+ctrl[1])
# Multi-branch check
if not multibranch_opt:
multibranch = 0
for mnemonic in control_mnemonics:
if mnemonic in disasm:
multibranch += 1
if multibranch > 1:
break
# Broken gadget (original ctrl_insn no longer exists
if disasm == '' or disasm == ' ' or ctrl[3] not in disasm:
continue
# Handle duplicates
if not repeat:
if insn in used_gadgets:
continue
used_gadgets.append(insn)
# All checks passed, save to cache
access['pool_disasm'][curr_site] = disasm
access['pool_asm'][curr_site] = insn
# Next start address for ctrl insn site search
curr_site = save+1
The above psuedocode would also fix #27
We'd store pools in bv so this fixes #22
Use regex matching to find control sites when performing gadget search