mirror of
https://github.com/AlexAltea/orbital.git
synced 2025-04-02 10:32:05 -04:00
99 lines
4.1 KiB
Python
99 lines
4.1 KiB
Python
#!/usr/bin/env python
|
|
|
|
import idaapi
|
|
import idautils
|
|
import re
|
|
import sys
|
|
import collections
|
|
|
|
# Configuration
|
|
generate_markdown_rows = True
|
|
sys_ioctl_addr = 0x438C00
|
|
backtrack_limit_ioctl = 100
|
|
backtrack_limit_esi = 100
|
|
|
|
ioctl_dict = {}
|
|
|
|
for string in idautils.Strings():
|
|
ioctl_name = ""
|
|
|
|
# First heuristic
|
|
match = re.search("ioctl\( ([0-9A-Z_]+) ([0-9A-Z_]+) \)", str(string))
|
|
if match:
|
|
ioctl_name = "SCE_{}_IOCTL_{}".format(match.group(1), match.group(2))
|
|
else:
|
|
match = re.search("ioctl\(([0-9A-Z_]+)\)", str(string))
|
|
if match:
|
|
ioctl_name = match.group(1)
|
|
else:
|
|
match = re.search("([0-9A-Z_]+) ioctl failed", str(string))
|
|
if match:
|
|
ioctl_name = match.group(1)
|
|
|
|
if match:
|
|
ioctl_dict[ioctl_name] = 0
|
|
for str_data_ref in DataRefsTo(string.ea):
|
|
for str_code_ref in CodeRefsTo(str_data_ref, True):
|
|
backtrack_esi_times = 0
|
|
instr_esi = str_code_ref
|
|
|
|
while backtrack_esi_times < backtrack_limit_esi:
|
|
prev_instr_esi = DecodePreviousInstruction(instr_esi)
|
|
if prev_instr_esi == None:
|
|
break
|
|
if prev_instr_esi.get_canon_mnem() == "mov":
|
|
if prev_instr_esi.Op1.reg == 6: # esi
|
|
ioctl_val_candidate = prev_instr_esi.Op2.value
|
|
if ioctl_val_candidate != 0:
|
|
ioctl_dict[ioctl_name] = prev_instr_esi.Op2.value & 0xFFFFFFFF
|
|
break
|
|
instr_esi = prev_instr_esi.ea
|
|
backtrack_esi_times += 1
|
|
|
|
# Second heuristic, stricter than the first one, so don't change the order
|
|
match = re.search("SCE_([0-9A-Z_]+)_IOCTL_([0-9A-Z_]+)", str(string))
|
|
if match:
|
|
ioctl_name = "SCE_{}_IOCTL_{}".format(match.group(1), match.group(2))
|
|
|
|
if ioctl_name not in ioctl_dict:
|
|
ioctl_dict[ioctl_name] = 0
|
|
for str_data_ref in DataRefsTo(string.ea):
|
|
for str_code_ref in CodeRefsTo(str_data_ref, True):
|
|
backtrack_ioctl_times = 0
|
|
instr_ioctl = str_code_ref
|
|
while backtrack_ioctl_times < backtrack_limit_ioctl:
|
|
prev_instr_ioctl = DecodePreviousInstruction(instr_ioctl)
|
|
if prev_instr_ioctl == None:
|
|
break
|
|
if prev_instr_ioctl.get_canon_mnem() == "call":
|
|
if prev_instr_ioctl.Op1.addr == sys_ioctl_addr:
|
|
backtrack_esi_times = 0
|
|
|
|
instr_esi = instr_ioctl
|
|
while backtrack_esi_times < backtrack_limit_esi:
|
|
prev_instr_esi = DecodePreviousInstruction(instr_esi)
|
|
if prev_instr_esi == None:
|
|
break
|
|
if prev_instr_esi.get_canon_mnem() == "mov":
|
|
if prev_instr_esi.Op1.reg == 6: # esi
|
|
ioctl_val_candidate = prev_instr_esi.Op2.value
|
|
if ioctl_val_candidate != 0:
|
|
ioctl_dict[ioctl_name] = prev_instr_esi.Op2.value & 0xFFFFFFFF
|
|
break
|
|
instr_esi = prev_instr_esi.ea
|
|
backtrack_esi_times += 1
|
|
instr_ioctl = prev_instr_ioctl.ea
|
|
backtrack_ioctl_times += 1
|
|
|
|
if ioctl_dict:
|
|
ioctl_dict_ordered = collections.OrderedDict(sorted(ioctl_dict.items()))
|
|
|
|
print("Found the following IOCTLs:")
|
|
if generate_markdown_rows:
|
|
for ioctl_name, ioctl_value in ioctl_dict_ordered.iteritems():
|
|
print("| *{: <37} | 0x{:08X} |".format(str(ioctl_name)+'*', ioctl_value))
|
|
else:
|
|
for ioctl_name, ioctl_value in ioctl_dict_ordered.iteritems():
|
|
print("{: <37} 0x{:08X}".format(ioctl_name, ioctl_value))
|
|
else:
|
|
print("No IOCTLs found.")
|