mirror of
https://github.com/vivisect/vivisect
synced 2026-06-08 18:04:23 +00:00
3f8c3141fb
* wip * still some cleanup I wanna do but it's mostly there * back out a few things and make dynamics win more * fixup elf tests * cleanup * moar data * test data
113 lines
3.8 KiB
Python
113 lines
3.8 KiB
Python
"""
|
|
generic workspace analysis module to seek through the undiscovered
|
|
country looking for pointers to interesting things.
|
|
|
|
in a previous life, this analysis code lived inside VivWorkspace.analyze()
|
|
"""
|
|
import logging
|
|
|
|
import envi.exc as e_exc
|
|
import visgraph.exc as g_exc
|
|
import visgraph.graphcore as g_core
|
|
from vivisect.const import RTYPE_BASEPTR, LOC_POINTER
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def analyze(vw):
|
|
|
|
logger.info('...analyzing pointers.')
|
|
|
|
done = {}
|
|
|
|
# Let's analyze Relocations we know are pointers
|
|
for rva, rtype in vw.reloc_by_va.items():
|
|
if rtype != RTYPE_BASEPTR:
|
|
continue
|
|
|
|
for xfr, xto, xtype, xinfo in vw.getXrefsFrom(rva):
|
|
logger.debug('pointer(xref): 0x%x -> 0x%x', xfr, xto)
|
|
try:
|
|
vw.analyzePointer(xto)
|
|
except e_exc.SegmentationViolation:
|
|
continue
|
|
done[xfr] = xto
|
|
|
|
# Now, we'll analyze the pointers placed by the file wrapper (ELF, PE, MACHO, etc...)
|
|
for pva, tva, fname, pname in vw.getVaSetRows('PointersFromFile'):
|
|
if vw.getLocation(pva) is None:
|
|
if tva is None:
|
|
logger.debug('making pointer(fromFile) 0x%x (%r)', pva, pname)
|
|
else:
|
|
logger.debug('making pointer(fromFile) 0x%x -> 0x%x (%r)', pva, tva, pname)
|
|
vw.makePointer(pva, tva, follow=True)
|
|
done[pva] = tva
|
|
|
|
for lva, lsz, lt, li in vw.getLocations(LOC_POINTER):
|
|
tva = vw.readMemoryPtr(lva)
|
|
if not vw.isValidPointer(tva):
|
|
continue
|
|
|
|
if vw.getLocation(tva) is not None:
|
|
# event if it's a pointer, we may not have made a name for it
|
|
if vw.getName(lva) is None:
|
|
done[lva] = tva
|
|
continue
|
|
|
|
logger.debug('following previously discovered pointer 0x%x -> 0x%x', lva, tva)
|
|
try:
|
|
logger.debug('pointer: 0x%x -> 0x%x', lva, tva)
|
|
vw.followPointer(tva)
|
|
done[lva] = tva
|
|
except Exception as e:
|
|
logger.error('followPointer() failed for 0x%.8x (pval: 0x%.8x) (err: %s)', lva, tva, e)
|
|
|
|
# Now, lets find likely free-hanging pointers
|
|
for addr, pval in vw.findPointers():
|
|
if vw.isDeadData(pval):
|
|
continue
|
|
try:
|
|
logger.debug('make pointer(found): 0x%x -> 0x%x', addr, pval)
|
|
vw.makePointer(addr, follow=True)
|
|
done[addr] = pval
|
|
except Exception as e:
|
|
logger.error('makePointer() failed for 0x%.8x (pval: 0x%.8x) (err: %s)', addr, pval, e)
|
|
|
|
# link the possible pointers up
|
|
pgraph = g_core.Graph()
|
|
while done:
|
|
ptr, tgt = done.popitem()
|
|
try:
|
|
pgraph.addNode(ptr)
|
|
except g_exc.DuplicateNode:
|
|
pass
|
|
try:
|
|
pgraph.addNode(tgt)
|
|
except g_exc.DuplicateNode:
|
|
pass
|
|
pgraph.addEdgeByNids(ptr, tgt)
|
|
|
|
leafs = [node for node in pgraph.getNodes() if pgraph.isLeafNode(node)]
|
|
for leaf in leafs:
|
|
va, props = leaf
|
|
name = vw.getName(va)
|
|
# if there's not a name at the bottom, not work making ptr names
|
|
if not name:
|
|
continue
|
|
links = [(ptr, tgt) for edge, ptr, tgt, props in pgraph.getRefsToByNid(va)]
|
|
while links:
|
|
ptr, tgt = links.pop(0)
|
|
pname = vw.getName(ptr)
|
|
if pname:
|
|
continue
|
|
if not vw.isLocType(ptr, LOC_POINTER):
|
|
continue
|
|
|
|
tgtname = vw.getName(tgt)
|
|
if tgtname:
|
|
name = vw._addNamePrefix(tgtname, tgt, 'ptr', '_') + '_%.8x' % ptr
|
|
logger.debug('0x%x: adding name prefix: %r (%r)', tgt, tgtname, name)
|
|
vw.makeName(ptr, name)
|
|
|
|
for edge, n1, n2, props in pgraph.getRefsToByNid(ptr):
|
|
links.append((n1, n2))
|