Skip to content

Commit

Permalink
sibyl func now works also for PE and RAW binary; -m can be used to de…
Browse files Browse the repository at this point in the history
…fine the base address
  • Loading branch information
LRGH committed Jun 8, 2017
1 parent ee55f6f commit 1868237
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 25 deletions.
6 changes: 5 additions & 1 deletion sibyl/actions/func.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class ActionFunc(Action):
"choices": Machine.available_machine()}),
(["-v", "--verbose"], {"help": "Verbose mode",
"action": "store_true"}),
(["-m", "--mapping-base"], {"help": "Binary mapping address",
"default": "0"}),
(["-d", "--disable-heuristic"], {"help": "Disable an heuristic",
"action": "append",
"choices": heur_names,
Expand All @@ -51,6 +53,8 @@ class ActionFunc(Action):
]

def run(self):
# Parse args
map_addr = int(self.args.mapping_base, 0)
# Architecture
architecture = False
if self.args.architecture:
Expand All @@ -66,7 +70,7 @@ def run(self):
cont = Container.from_stream(open(self.args.filename))
machine = Machine(architecture)
addr_size = machine.ira().pc.size / 4
fh = FuncHeuristic(cont, machine)
fh = FuncHeuristic(cont, machine, map_addr)

# Enable / disable heuristics
for name in self.args.enable_heuristic:
Expand Down
45 changes: 21 additions & 24 deletions sibyl/heuristics/func.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,27 +60,24 @@ def recursive_call(func_heur, addresses=None):

def _virt_find(virt, pattern):
"""Search @pattern in elfesteem @virt instance
Inspired from elf_init.virt.find
"""
regexp = re.compile(pattern)
offset = 0
sections = []
for s in virt.parent.ph:
s_max = s.ph.memsz
if offset < s.ph.vaddr + s_max:
sections.append(s)

if not sections:
raise StopIteration
offset -= sections[0].ph.vaddr
if offset < 0:
offset = 0
for s in sections:
data = virt.parent.content[s.ph.offset:s.ph.offset + s.ph.filesz]
ret = regexp.finditer(data[offset:])
yield ret, s.ph.vaddr
offset = 0

if not hasattr(virt, 'parent'): # RAW data
segments = [ virt ]
get_data = lambda s: s
ret_addr = lambda s, pos: pos.start()
elif hasattr(virt.parent, 'ph'): # ELF
segments = virt.parent.ph
get_data = lambda s: virt.parent.content[s.ph.offset:s.ph.offset+s.ph.filesz]
ret_addr = lambda s, pos: pos.start() + s.ph.vaddr
elif hasattr(virt.parent, 'SHList'): # PE
segments = virt.parent.SHList
get_data = lambda s: str(s.data)
ret_addr = lambda s, pos: virt.parent.rva2virt(s.addr + pos.start())
for s in segments:
data = get_data(s)
for pos in regexp.finditer(data):
yield ret_addr(s, pos)

def pattern_matching(func_heur):
"""Search for function by pattern matching"""
Expand All @@ -95,10 +92,8 @@ def pattern_matching(func_heur):
# Search for function prologs

pattern = "(" + ")|(".join(prologs) + ")"
for find_iter, vaddr_base in _virt_find(data, pattern):
for match in find_iter:
addr = match.start() + vaddr_base
addresses[addr] = 1
for addr in _virt_find(data, pattern):
addresses[func_heur.map_addr+addr] = 1

return addresses

Expand All @@ -112,14 +107,16 @@ class FuncHeuristic(Heuristic):
recursive_call,
]

def __init__(self, cont, machine):
def __init__(self, cont, machine, map_addr=0):
"""
@cont: miasm2's Container instance
@machine: miasm2's Machine instance
@map_addr: base address
"""
super(FuncHeuristic, self).__init__()
self.cont = cont
self.machine = machine
self.map_addr = map_addr

def do_votes(self):
"""Call recursive_call at the end"""
Expand Down

0 comments on commit 1868237

Please sign in to comment.