Exemple #1
0
def make(opts):
  log.info('[+] Loading context of %s'%(opts.dump1))
  context = context.get_context(opts.dump1) #'../../outputs/skype.1.a') # TODO 
  # refresh
  if len(context.structures) != len(context.structures_addresses):
    log.info('[+] Refreshing from %d structures cached'%( len(context.structures) ))
    mallocRev = MallocReverser()
    context = mallocRev.reverse(context)
    mallocRev.check_inuse(context)
    log.info('[+] Final %d structures from malloc blocs'%( len(context.structures) ))

  
  heap1 = context.mappings.getHeap()
  log.info('[+] Loading mappings of %s'%(opts.dump2))
  newmappings = dump_loader.load( opts.dump2)  
  heap2 = newmappings.getHeap()
  log.info('[+] finding diff values with %s'%(opts.dump2))
  addrs = cmd_cmp(heap1, heap2, heap1.start)
  
  # now compare with structures addresses
  structures = []
  realloc=0
  log.info('[+] Looking at %d differences'%( len(addrs) ))
  st = []
  # joined iteration, found structure affected
  # use info from malloc : structures.start + .size 
  addr_iter = iter(addrs)
  structs_addr_iter = iter(context.malloc_addresses)
  structs_size_iter = iter(context.malloc_sizes) 
  try:
    addr = addr_iter.next()
    st_addr = structs_addr_iter.next()
    st_size = structs_size_iter.next()
    cnt=1
    while True:
        
      while (addr - st_addr) >= st_size : # find st containing offset
        st_addr = structs_addr_iter.next()
        st_size = structs_size_iter.next()
      # check for gaps
      if (addr - st_addr) < 0: # went to far - no struct overlapping
        while (addr - st_addr) < 0: # addr is in between two struct - dump all addr stuck out of malloc_chunks
          addr = addr_iter.next()
          pass
        continue
      
      #
      if 0 <= (addr - st_addr) < st_size: # check if offset is really in st ( should be always if your not dumb/there no holes )
        structures.append( context.structures[ st_addr ]) # tag the structure as different
        cnt+=1
      else: 
        ## (addr - st_addr) < 0 # impossible by previous while
        ## (addr - st_addr) >= st_size # then continur
        continue

      while (addr - st_addr) < st_size : # enumerate offsets in st range
        addr = addr_iter.next()
        cnt+=1
  except StopIteration,e:
    pass
    def setUpClass(self):
        # self.context3 = context.get_context('test/src/test-ctypes3.dump')
        self.context6 = context.get_context("test/src/test-ctypes6.32.dump")
        from haystack.reverse.heuristics import dsa

        self.dsa = dsa.DSASimple(self.context6.mappings)
        self.st = self.context6.listStructures()[0]
 def test_string_overlap(self):
     context6 = context.get_context('test/src/test-ctypes6.dump')
     for s in context6.listStructures():
         #s.resolvePointers()
         self.dsa.analyze_fields(s)
         log.debug(s.toString())
     self.assertTrue(True)  # test no error
 def test_string_overlap(self):
     context6 = context.get_context('test/src/test-ctypes6.32.dump')
     for s in context6.listStructures():
         # s.resolvePointers()
         self.dsa.analyze_fields(s)
         log.debug(s.toString())
     self.assertTrue(True)  # test no error
 def test_closestFloorValue(self):
   lst = numpy.asarray(range(0,100,10))
   self.assertEquals(utils.closestFloorValue(41, lst), (40,4))
   self.assertEquals(utils.closestFloorValue(40, lst), (40,4))
   with self.assertRaises(ValueError):
     utils.closestFloorValue(-1, lst)
   
   ctx = context.get_context('test/src/test-ctypes3.dump')
   lst = ctx._structures_addresses
Exemple #6
0
def test4():
    dumpname = '/home/jal/outputs/dumps/ssh/ssh.1'  # 23418'
    #dumpname = '/home/jal/outputs/dumps/skype/skype.1/skype.1.a'
    print('[+] load context', dumpname)
    ctx = context.get_context(dumpname)
    mappings = ctx.mappings

    for ptr, name in ctx._function_names.items():
        print('@%x -> %s::%s' % (ptr, mappings.get_mapping_for_address(ptr).pathname, name))
Exemple #7
0
    def test_closestFloorValue(self):
        lst = numpy.asarray(range(0, 100, 10))
        self.assertEquals(utils.closestFloorValue(41, lst), (40, 4))
        self.assertEquals(utils.closestFloorValue(40, lst), (40, 4))
        with self.assertRaises(ValueError):
            utils.closestFloorValue(-1, lst)

        ctx = context.get_context('test/src/test-ctypes3.dump')
        lst = ctx._structures_addresses
def makeSignatures(dumpname):
    from haystack.reverse import context
    log.debug('\t[-] Loading the context for a dumpname.')
    ctx = context.get_context(dumpname)
    heap = ctx.heap

    log.info('[+] Make the signatures.')
    sigMaker = SignatureMaker(heap)
    sig = sigMaker.search()
    return ctx, sig
def makeSizeCaches(dumpname):
    ''' gets all allocators instances from the dump, order them by size.'''
    from haystack.reverse import context
    log.debug('\t[-] Loading the context for a dumpname.')
    ctx = context.get_context(dumpname)
    log.debug('\t[-] Make the size dictionnaries.')
    sizeCache = StructureSizeCache(ctx)
    sizeCache.cacheSizes()

    return ctx, sizeCache
Exemple #10
0
def makeSignatures(dumpname):
    from haystack.reverse import context
    log.debug('\t[-] Loading the context for a dumpname.')
    ctx = context.get_context(dumpname)
    heap = ctx.heap

    log.info('[+] Make the signatures.')
    sigMaker = SignatureMaker(heap)
    sig = sigMaker.search()
    return ctx, sig
Exemple #11
0
def makeSizeCaches(dumpname):
    ''' gets all allocators instances from the dump, order them by size.'''
    from haystack.reverse import context
    log.debug('\t[-] Loading the context for a dumpname.')
    ctx = context.get_context(dumpname)
    log.debug('\t[-] Make the size dictionnaries.')
    sizeCache = StructureSizeCache(ctx)
    sizeCache.cacheSizes()

    return ctx, sizeCache
def reverseLookup(opt):
  from haystack.reverse import context
  log.info('[+] Load context')
  ctx = context.get_context(opt.dumpname)
  addr = opt.struct_addr

  log.info('[+] find offsets of struct_addr:%x'%(addr))
  i = -1
  structs = set()
  try:
    structs = ctx.listStructuresForPointerValue(addr)
  except ValueError,e:
    log.info('[+] Found no structures.')
    return
Exemple #13
0
def reverseInstances(dumpname):
  from haystack.reverse import context
  log.debug ('[+] Loading the memory dump ')
  ctx = context.get_context(dumpname)
  try:
    if not os.access(Config.getStructsCacheDir(ctx.dumpname), os.F_OK):    
      os.mkdir(Config.getStructsCacheDir(ctx.dumpname))
    
    # we use common allocators to find structures.
    #log.debug('Reversing malloc')
    #mallocRev = MallocReverser()
    #ctx = mallocRev.reverse(ctx)
    #mallocRev.check_inuse(ctx)

    # try to find some logical constructs.
    log.debug('Reversing DoubleLinkedListReverser')
    doublelink = DoubleLinkedListReverser()
    ctx = doublelink.reverse(ctx)

    # decode bytes contents to find basic types.
    log.debug('Reversing Fields')
    fr = FieldReverser()
    ctx = fr.reverse(ctx)

    # identify pointer relation between structures
    log.debug('Reversing PointerFields')
    pfr = PointerFieldReverser()
    ctx = pfr.reverse(ctx)

    # graph pointer relations between structures
    log.debug('Reversing PointerGraph')
    ptrgraph = PointerGraphReverser()
    ctx = ptrgraph.reverse(ctx)
    ptrgraph._saveStructures(ctx)

    #save to file 
    save_headers(ctx)
    #fr._saveStructures(ctx)
    ##libRev = KnowStructReverser('libQt')
    ##ctx = libRev.reverse(ctx)
    # we have more enriched context
    
    
    # etc
  except KeyboardInterrupt,e:
    #except IOError,e:
    log.warning(e)
    log.info('[+] %d structs extracted'%(  context.structuresCount()) )
    raise e
    pass
Exemple #14
0
def reverseInstances(dumpname):
    from haystack.reverse import context
    log.debug('[+] Loading the memory dump ')
    ctx = context.get_context(dumpname)
    try:
        if not os.access(Config.getStructsCacheDir(ctx.dumpname), os.F_OK):
            os.mkdir(Config.getStructsCacheDir(ctx.dumpname))

        # we use common allocators to find structures.
        #log.debug('Reversing malloc')
        #mallocRev = MallocReverser()
        #ctx = mallocRev.reverse(ctx)
        #mallocRev.check_inuse(ctx)

        # try to find some logical constructs.
        log.debug('Reversing DoubleLinkedListReverser')
        doublelink = DoubleLinkedListReverser()
        ctx = doublelink.reverse(ctx)

        # decode bytes contents to find basic types.
        log.debug('Reversing Fields')
        fr = FieldReverser()
        ctx = fr.reverse(ctx)

        # identify pointer relation between structures
        log.debug('Reversing PointerFields')
        pfr = PointerFieldReverser()
        ctx = pfr.reverse(ctx)

        # graph pointer relations between structures
        log.debug('Reversing PointerGraph')
        ptrgraph = PointerGraphReverser()
        ctx = ptrgraph.reverse(ctx)
        ptrgraph._saveStructures(ctx)

        #save to file
        save_headers(ctx)
        #fr._saveStructures(ctx)
        ##libRev = KnowStructReverser('libQt')
        ##ctx = libRev.reverse(ctx)
        # we have more enriched context

        # etc
    except KeyboardInterrupt, e:
        #except IOError,e:
        log.warning(e)
        log.info('[+] %d structs extracted' % (context.structuresCount()))
        raise e
        pass
Exemple #15
0
def make(opts):
    fname = opts.gexf

    # if __name__ == '__main__':
    # if False:
    # ctx = context.get_context('../../outputs/skype.1.a')
    ctx = context.get_context(opts.dumpname)

    # digraph=networkx.readwrite.gexf.read_gexf(  '../../outputs/skype.1.a.gexf')
    digraph = networkx.readwrite.gexf.read_gexf(opts.gexf.name)
    heap = ctx.mappings.get_heap()

    # only add heap structure with links
    edges = [(x, y) for x, y in digraph.edges() if int(x, 16) in heap and int(y, 16) in heap]
    graph = networkx.DiGraph()
    graph.add_edges_from(edges)

    printGraph(graph, os.path.basename(opts.dumpname))
Exemple #16
0
def make(opts):
    fname = opts.gexf

    #if __name__ == '__main__':
    #if False:
    #ctx = context.get_context('../../outputs/skype.1.a')
    ctx = context.get_context(opts.dumpname)

    #digraph=networkx.readwrite.gexf.read_gexf(  '../../outputs/skype.1.a.gexf')
    digraph = networkx.readwrite.gexf.read_gexf(opts.gexf.name)
    heap = ctx.mappings.getHeap()

    # only add heap structure with links
    edges = [(x, y) for x, y in digraph.edges()
             if int(x, 16) in heap and int(y, 16) in heap]
    graph = networkx.DiGraph()
    graph.add_edges_from(edges)

    printGraph(graph, os.path.basename(opts.dumpname))
Exemple #17
0
 def test_get_context(self):
     '''FIXME: maybe not the best idea to use a reverser in a 
     haystack.base test unit'''
     from haystack.reverse import context
     self.putty = context.get_context('test/dumps/putty/putty.1.dump')
     mappings = self.putty.mappings
     # print ''.join(['%s\n'%(m) for m in mappings])
     with self.assertRaises(ValueError):
         mappings.get_context(0x0)
     with self.assertRaises(ValueError):
         mappings.get_context(0xb76e12d3)
     #[heap] children
     self.assertEquals(
         mappings.get_context(0x0062d000).heap,
         mappings.get_mapping_for_address(0x005c0000))
     self.assertEquals(
         mappings.get_context(0x0063e123).heap,
         mappings.get_mapping_for_address(0x005c0000))
     self.putty.reset()
     self.putty = None
 def setUpClass(self):
   self.ssh = context.get_context('test/dumps/ssh/ssh.1')
   self.putty = context.get_context('test/dumps/putty/putty.1.dump')
   pass
 def setUpClass(self):
     self.ssh = context.get_context('test/dumps/ssh/ssh.1')
     self.putty = context.get_context('test/dumps/putty/putty.1.dump')
     pass
Exemple #20
0
 def _listStructures(self):
     from haystack.reverse import context
     self.context = context.get_context(self.mappings.name)
     self.show_structures_allocated(self.context)
     return
Exemple #21
0
def make(opts):
    log.info('[+] Loading context of %s' % (opts.dump1))
    # '../../outputs/skype.1.a') # TODO
    ctx = context.get_context(opts.dump1)
    # refresh
    if len(ctx.structures) != len(ctx.structures_addresses):
        log.info(
            '[+] Refreshing from %d allocators cached' %
            (len(
                ctx.structures)))
        # FIXME, I think its now an heapwalker, not a reverser
        mallocRev = reversers.MallocReverser()
        ctx = mallocRev.reverse(ctx)
        mallocRev.check_inuse(ctx)
        log.info(
            '[+] Final %d allocators from malloc blocs' %
            (len(
                ctx.structures)))
    finder = ctx.get_memory_handler().get_heap_finder()
    heap1 = finder.list_heap_walkers()[0]
    log.info('[+] Loading _memory_handler of %s' % (opts.dump2))
    newmappings = dump_loader.load(opts.dump2)
    finder2 = newmappings.get_heap_finder()
    heap2 = finder2.list_heap_walkers()[0]
    log.info('[+] finding diff values with %s' % (opts.dump2))
    addrs = cmd_cmp(heap1, heap2, heap1.start)

    # now compare with allocators addresses
    structures = []
    realloc = 0
    log.info('[+] Looking at %d differences' % (len(addrs)))
    st = []
    # joined iteration, found structure affected
    # use info from malloc : allocators.start + .size
    addr_iter = iter(addrs)
    structs_addr_iter = iter(ctx.malloc_addresses)
    structs_size_iter = iter(ctx.malloc_sizes)
    try:
        addr = addr_iter.next()
        st_addr = structs_addr_iter.next()
        st_size = structs_size_iter.next()
        cnt = 1
        while True:

            while (addr - st_addr) >= st_size:  # find st containing offset
                st_addr = structs_addr_iter.next()
                st_size = structs_size_iter.next()
            # check for gaps
            if (addr - st_addr) < 0:  # went to far - no struct overlapping
                # addr is in between two struct - dump all addr stuck out of
                # malloc_chunks
                while (addr - st_addr) < 0:
                    addr = addr_iter.next()
                    pass
                continue

            #
            # check if offset is really in st ( should be always if your not
            # dumb/there no holes )
            if 0 <= (addr - st_addr) < st_size:
                # tag the structure as different
                structures.append(ctx.structures[st_addr])
                cnt += 1
            else:
                # (addr - st_addr) < 0 # impossible by previous while
                # (addr - st_addr) >= st_size # then continur
                continue

            while (addr - st_addr) < st_size:  # enumerate offsets in st range
                addr = addr_iter.next()
                cnt += 1
    except StopIteration as e:
        pass
    addrs_found = cnt

    log.info(
        '[+] On %d diffs, found %d structs with different values. realloc: %d' %
        (addrs_found, len(structures), realloc))
    log.info('[+] Outputing to file (will be long-ish)')

    print_diff_files(opts, context, newmappings, structures)
 def setUpClass(self):
     self.ssh1 = context.get_context('test/dumps/ssh/ssh.1')
 def setUpClass(self):
     self.context6 = context.get_context('test/src/test-ctypes6.dump')
Exemple #24
0
 def setUpClass(self):
     self.ssh1 = context.get_context("test/dumps/ssh/ssh.1")
 def setUp(self):
     model.reset()
     # os.chdir()
     self.context = context.get_context('test/src/test-ctypes3.32.dump')
     self.dsa = dsa.DSASimple(self.context.config)
 def test_reverseInstances(self):
     log.info('START test test_reverseInstances')
     ctx = context.get_context('test/dumps/ssh/ssh.1')
     dumpname = 'test/dumps/ssh/ssh.1'
     ctx = ctx.config.cleanCache(dumpname)
     ctx = reversers.reverseInstances(dumpname)
Exemple #27
0
 def setUpClass(self):
     self.context6 = context.get_context("test/src/test-ctypes6.dump")
Exemple #28
0
def make(opts):
    log.info('[+] Loading context of %s' % (opts.dump1))
    context = context.get_context(
        opts.dump1)  #'../../outputs/skype.1.a') # TODO
    # refresh
    if len(context.structures) != len(context.structures_addresses):
        log.info('[+] Refreshing from %d structures cached' %
                 (len(context.structures)))
        mallocRev = MallocReverser()
        context = mallocRev.reverse(context)
        mallocRev.check_inuse(context)
        log.info('[+] Final %d structures from malloc blocs' %
                 (len(context.structures)))

    heap1 = context.mappings.getHeap()
    log.info('[+] Loading mappings of %s' % (opts.dump2))
    newmappings = dump_loader.load(opts.dump2)
    heap2 = newmappings.getHeap()
    log.info('[+] finding diff values with %s' % (opts.dump2))
    addrs = cmd_cmp(heap1, heap2, heap1.start)

    # now compare with structures addresses
    structures = []
    realloc = 0
    log.info('[+] Looking at %d differences' % (len(addrs)))
    st = []
    # joined iteration, found structure affected
    # use info from malloc : structures.start + .size
    addr_iter = iter(addrs)
    structs_addr_iter = iter(context.malloc_addresses)
    structs_size_iter = iter(context.malloc_sizes)
    try:
        addr = addr_iter.next()
        st_addr = structs_addr_iter.next()
        st_size = structs_size_iter.next()
        cnt = 1
        while True:

            while (addr - st_addr) >= st_size:  # find st containing offset
                st_addr = structs_addr_iter.next()
                st_size = structs_size_iter.next()
            # check for gaps
            if (addr - st_addr) < 0:  # went to far - no struct overlapping
                while (
                        addr - st_addr
                ) < 0:  # addr is in between two struct - dump all addr stuck out of malloc_chunks
                    addr = addr_iter.next()
                    pass
                continue

            #
            if 0 <= (
                    addr - st_addr
            ) < st_size:  # check if offset is really in st ( should be always if your not dumb/there no holes )
                structures.append(context.structures[st_addr]
                                  )  # tag the structure as different
                cnt += 1
            else:
                ## (addr - st_addr) < 0 # impossible by previous while
                ## (addr - st_addr) >= st_size # then continur
                continue

            while (addr - st_addr) < st_size:  # enumerate offsets in st range
                addr = addr_iter.next()
                cnt += 1
    except StopIteration, e:
        pass
 def setUpClass(self):
     #self.context3 = context.get_context('test/src/test-ctypes3.dump')
     self.context6 = context.get_context('test/src/test-ctypes6.dump')
     from haystack.reverse.heuristics import dsa
     self.dsa = dsa.DSASimple()
     self.st = self.context6.listStructures()[0]
 def setUp(self):    
   #os.chdir()
   self.context = context.get_context('test/src/test-ctypes3.dump')
 def test_reverseInstances(self):
   ctx = context.get_context('test/dumps/ssh/ssh.1')
   dumpname = 'test/dumps/ssh/ssh.1'
   ctx = Config.cleanCache(dumpname)
   ctx = reversers.reverseInstances(dumpname)
 def setUpClass(self):
     from haystack.reverse.heuristics import dsa
     self.context = context.get_context('test/src/test-ctypes3.32.dump')
     self.dsa = dsa.DSASimple(self.context.config)
     self.pta = dsa.EnrichedPointerFields(self.context.config)
     pass
Exemple #33
0
 def setUpClass(self):
   self.context = None #context.get_context('test/src/test-ctypes3.dump')
   self.putty7124 = context.get_context('test/dumps/putty/putty.7124.dump')
   self.dsa = DSASimple()
Exemple #34
0
def test3():
    ''' reverse fn pointer names by trying to rebase the ptr value to a local ld_open '''

    # load local memdump
    # map all librairies
    # go through all pointers in librairies
    # try to dl_addr the pointers by rebasing.
    #from haystack import dump_loader
    #dump = memory_loader.load('/home/jal/outputs/dumps/ssh/ssh.1')

    IGNORES = ['None', '[heap]', '[stack]', '[vdso]']

    dumpname = '/home/jal/outputs/dumps/ssh/ssh.1'  # 23418'
    #dumpname = '/home/jal/outputs/dumps/skype/skype.1/skype.1.a'
    print('[+] load context', dumpname)
    ctx = context.get_context(dumpname)
    mappings = ctx.mappings
    ldso = dict()
    for m in mappings:
        if m.pathname not in IGNORES and m.pathname not in ldso:
            try:
                ldso[m.pathname] = ctypes.CDLL(m.pathname)
            except OSError as e:
                IGNORES.append(m.pathname)

    print('[+] context loaded')
    # mmap_libdl = [ m for m in _memory_handler if 'ld-2.13' in m.pathname ] #and 'x' in m.permissions]
    #hptrs = ctx._pointers_values_heap
    # print '[+] %d pointers in heap to heap '%( len(hptrs) )

    # looking in [heap] pointing to elsewhere
    all_ptrs = ctx.listPointerValueInHeap()
    print('[+] %d pointers in heap to elsewhere ' % (len(all_ptrs)))

    localmappings = getMappings()

    #crypto = _memory_handler.get_mapping('/lib/i386-linux-gnu/libcrypto.so.1.0.0')
    # for lm in crypto:
    #  print lm

    # print '---'
    #crypto = localmappings.get_mapping('/lib/i386-linux-gnu/libcrypto.so.1.0.0')
    # for lm in crypto:
    #  print lm

    # return
    for ptr in set(all_ptrs):
        # get dump mmap
        m = mappings.get_mapping_for_address(ptr)
        if m.pathname not in IGNORES:
            # find the right localmmap
            localmaps = localmappings._get_mapping(m.pathname)
            found = False
            for localm in localmaps:
                if localm.offset == m.offset and localm.permissions == m.permissions:
                    # found it
                    found = True
                    caddr = ptr - m.start + localm.start  # rebase
                    dl_name, fnaddr = getname(caddr)
                    if dl_name is not None:
                        #sym = libdl.dlsym( ldso[m.pathname]._handle, dl_name, 'xxx')
                        #fnaddr = struct.unpack('L',struct.pack('l', sym) )[0]
                        if fnaddr == caddr:  # reverse check
                            print('[+] REBASE 0x%x -> 0x%x p:%s|%s|=%s  off:%x|%x|=%s %s fn: %s @%x' % (
                                ptr, caddr, m.permissions, localm.permissions, localm.permissions == m.permissions,
                                m.offset, localm.offset, m.offset == localm.offset, m.pathname, dl_name, fnaddr))
                            # yield (ptr, m, dl_name)
                        else:
                            # continue
                            print('[-] MIDDLE 0x%x -> 0x%x p:%s|%s|=%s  off:%x|%x|=%s %s fn: %s @%x' % (
                                ptr, caddr, m.permissions, localm.permissions, localm.permissions == m.permissions,
                                m.offset, localm.offset, m.offset == localm.offset, m.pathname, dl_name, fnaddr))
                    else:
                        continue
                        print('FAIL REBASE (not public ?) 0x%x -> 0x%x p:%s|%s|=%s  off:%x|%x|=%s  %s fn: %s ' % (
                            ptr, caddr, m.permissions, localm.permissions, localm.permissions == m.permissions,
                            m.offset, localm.offset, m.offset == localm.offset, m.pathname, dl_name))
                        pass
                    break
            if not found:
                continue
                print('[+] not a fn pointer %x\n' % (ptr), m, '\n   ---dump  Vs local ---- \n', '\n'.join(map(str, localmaps)))
    # pass
    for name, lib in ldso.items():
        ret = libdl.dlclose(lib._handle)

    return
def main():
    from haystack.reverse import context
    ctx = context.get_context('test/dumps/skype/skype.1/skype.1.f')
    from haystack.reverse import structure
    it = structure.cacheLoadAllLazy(ctx)

    structs = []
    for i in range(10000):
        structs.append(it.next())

    [s.toString() for addr, s in structs]

    #51 Mo

    structure.CacheWrapper.refs.size = 5
    for i in range(5):
        structure.CacheWrapper.refs[i] = i

    #51 Mo

    from meliae import scanner
    scanner.dump_all_objects('filename.json')

    from meliae import loader
    om = loader.load('filename.json')
    s = om.summarize()
    s
    '''
  Total 206750 objects, 150 types, Total size = 27.2MiB (28495037 bytes)
   Index   Count   %      Size   % Cum     Max Kind
       0   75801  36   7529074  26  26   27683 str
       1   11507   5   6351864  22  48     552 Field
       2      16   0   5926913  20  69 2653328 numpy.ndarray
       3   10000   4   1680000   5  75     168 CacheWrapper
       4    2099   1   1158648   4  79     552 AnonymousStructInstance
       5    1182   0    857136   3  82   98440 dict
       6   18630   9    745200   2  85      40 weakref
       7   14136   6    633148   2  87   43812 list
  '''
    # clearly Field instances keep some place....
    # most 10000 Anonymous intances are not int memory now

    om.compute_referrers()

    # om[ addr].parents
    # om[ addr].children

    # get the biggest Field
    f_addr = s.summaries[1].max_address
    om[f_addr]

    #Field(179830860 552B 21refs 1par)

    om[f_addr].parents
    # [179834316]
    # >>> om[ 179834316 ]
    # list(179834316 132B 19refs 1par)  <- list of fields in Struct

    l_addr = om[f_addr].parents[0]
    om[l_addr].parents
    # [179849516]
    # >>> om[ 179849516 ]
    # AnonymousStructInstance(179849516 552B 23refs 19par)

    anon_addr = om[l_addr].parents[0]
    om[anon_addr]
    #179849516 is a anon struct
    import networkx
    import matplotlib.pyplot as plt

    graphme()
Exemple #36
0
def main():
    from haystack.reverse import context
    ctx = context.get_context('test/dumps/skype/skype.1/skype.1.f')
    from haystack.reverse import structure
    it = structure.cacheLoadAllLazy(ctx)

    structs = []
    for i in range(10000):
        structs.append(it.next())

    [s.toString() for addr, s in structs]

    # 51 Mo

    structure.CacheWrapper.refs.size = 5
    for i in range(5):
        structure.CacheWrapper.refs[i] = i

    # 51 Mo

    from meliae import scanner
    scanner.dump_all_objects('filename.json')

    from meliae import loader
    om = loader.load('filename.json')
    s = om.summarize()
    s
    '''
  Total 206750 objects, 150 types, Total size = 27.2MiB (28495037 bytes)
   Index   Count   %      Size   % Cum     Max Kind
       0   75801  36   7529074  26  26   27683 str
       1   11507   5   6351864  22  48     552 Field
       2      16   0   5926913  20  69 2653328 numpy.ndarray
       3   10000   4   1680000   5  75     168 CacheWrapper
       4    2099   1   1158648   4  79     552 AnonymousStructInstance
       5    1182   0    857136   3  82   98440 dict
       6   18630   9    745200   2  85      40 weakref
       7   14136   6    633148   2  87   43812 list
  '''
    # clearly Field instances keep some place....
    # most 10000 Anonymous intances are not int memory now

    om.compute_referrers()

    # om[ addr].parents
    # om[ addr].children

    # get the biggest Field
    f_addr = s.summaries[1].max_address
    om[f_addr]

    # Field(179830860 552B 21refs 1par)

    om[f_addr].parents
    # [179834316]
    # >>> om[ 179834316 ]
    # list(179834316 132B 19refs 1par)  <- list of fields in Struct

    l_addr = om[f_addr].parents[0]
    om[l_addr].parents
    # [179849516]
    # >>> om[ 179849516 ]
    # AnonymousStructInstance(179849516 552B 23refs 19par)

    anon_addr = om[l_addr].parents[0]
    om[anon_addr]
    # 179849516 is a anon struct
    import networkx
    import matplotlib.pyplot as plt

    graphme()
Exemple #37
0
def make(opts):
    log.info('[+] Loading context of %s' % (opts.dump1))
    # '../../outputs/skype.1.a') # TODO
    ctx = context.get_context(opts.dump1)
    # refresh
    if len(ctx.structures) != len(ctx.structures_addresses):
        log.info('[+] Refreshing from %d allocators cached' %
                 (len(ctx.structures)))
        # FIXME, I think its now an heapwalker, not a reverser
        mallocRev = reversers.MallocReverser()
        ctx = mallocRev.reverse(ctx)
        mallocRev.check_inuse(ctx)
        log.info('[+] Final %d allocators from malloc blocs' %
                 (len(ctx.structures)))
    finder = ctx.get_memory_handler().get_heap_finder()
    heap1 = finder.get_heap_mappings()[0]
    log.info('[+] Loading _memory_handler of %s' % (opts.dump2))
    newmappings = dump_loader.load(opts.dump2)
    finder2 = newmappings.get_heap_finder()
    heap2 = finder2.get_heap_mappings()[0]
    log.info('[+] finding diff values with %s' % (opts.dump2))
    addrs = cmd_cmp(heap1, heap2, heap1.start)

    # now compare with allocators addresses
    structures = []
    realloc = 0
    log.info('[+] Looking at %d differences' % (len(addrs)))
    st = []
    # joined iteration, found structure affected
    # use info from malloc : allocators.start + .size
    addr_iter = iter(addrs)
    structs_addr_iter = iter(ctx.malloc_addresses)
    structs_size_iter = iter(ctx.malloc_sizes)
    try:
        addr = addr_iter.next()
        st_addr = structs_addr_iter.next()
        st_size = structs_size_iter.next()
        cnt = 1
        while True:

            while (addr - st_addr) >= st_size:  # find st containing offset
                st_addr = structs_addr_iter.next()
                st_size = structs_size_iter.next()
            # check for gaps
            if (addr - st_addr) < 0:  # went to far - no struct overlapping
                # addr is in between two struct - dump all addr stuck out of
                # malloc_chunks
                while (addr - st_addr) < 0:
                    addr = addr_iter.next()
                    pass
                continue

            #
            # check if offset is really in st ( should be always if your not
            # dumb/there no holes )
            if 0 <= (addr - st_addr) < st_size:
                # tag the structure as different
                structures.append(ctx.structures[st_addr])
                cnt += 1
            else:
                # (addr - st_addr) < 0 # impossible by previous while
                # (addr - st_addr) >= st_size # then continur
                continue

            while (addr - st_addr) < st_size:  # enumerate offsets in st range
                addr = addr_iter.next()
                cnt += 1
    except StopIteration as e:
        pass
    addrs_found = cnt

    log.info(
        '[+] On %d diffs, found %d structs with different values. realloc: %d'
        % (addrs_found, len(structures), realloc))
    log.info('[+] Outputing to file (will be long-ish)')

    print_diff_files(opts, context, newmappings, structures)
 def setUpClass(self):
     from haystack.reverse.heuristics import dsa
     self.context = context.get_context('test/src/test-ctypes3.dump')
     self.dsa = dsa.DSASimple()
     self.pta = dsa.EnrichedPointerFields()
     pass