class Metasm::Windows7Heap

Attributes

chunkkey_flags[RW]

4-byte xor key to decrypt the chunk headers

chunkkey_size[RW]

4-byte xor key to decrypt the chunk headers

chunkkey_unusedbytes[RW]

4-byte xor key to decrypt the chunk headers

Public Instance Methods

each_heap_segment(ar) { |ptr, sa-ptr| ... } click to toggle source
# File samples/dbg-plugins/heapscan/heapscan.rb, line 621
def each_heap_segment(ar)
        if ar.encodeflagmask != 0
                @chunkkey_size = ar.encoding.size
                @chunkkey_flags = ar.encoding.flags
                @chunkkey_unusedbytes = ar.encoding.unusedbytes
        else
                @chunkkey_size = 0
                @chunkkey_flags = 0
                @chunkkey_unusedbytes = 0
        end

        each_listentry(ar.segmentlist, '_HEAP_SEGMENT', 0x10) { |sg|
                skiplist = []
                each_listentry(sg.ucrsegmentlist, '_HEAP_UCR_DESCRIPTOR', 8) { |ucr|
                        skiplist << [ucr.address, ucr.size]
                }

                ptr = sg.firstentry
                ptrend = sg.lastvalidentry + @hsz
                skiplist.delete_if { |sa, sl| sa < ptr or sa + sl > ptrend }
                skiplist << [ptrend, 1]
                skiplist.sort.each { |sa, sl|
                        yield(ptr, sa-ptr)
                        ptr = sa + sl
                }
        }
end
scan_chunks_xr() click to toggle source
# File samples/dbg-plugins/heapscan/heapscan.rb, line 696
def scan_chunks_xr
        @xrchunksto = {}
        @xrchunksfrom = {}
        @chunks.each { |a, l|
                pagecache(a, l).unpack('L*').each { |p|
                        if @chunks[p]
                                (@xrchunksto[a] ||= []) << p
                                (@xrchunksfrom[p] ||= []) << a
                        end
                }
        }
end
scan_frontend(ar) click to toggle source
# File samples/dbg-plugins/heapscan/heapscan.rb, line 662
def scan_frontend(ar)
        return if ar.frontendheaptype != 2
        lfh = @cp.decode_c_struct('_LFH_HEAP', @dbg.memory, ar.frontendheap)
        lfh.localdata[0].segmentinfo.to_array.each { |sinfo|
                sinfo.cacheditems.to_array.each { |ssp|
                        next if not ssp
                        subseg = @cp.decode_c_struct('_HEAP_SUBSEGMENT', @dbg.memory, ssp)
                        scan_lfh_ss(subseg)
                }
        }
end
scan_heap_segment(first, len) click to toggle source
# File samples/dbg-plugins/heapscan/heapscan.rb, line 649
def scan_heap_segment(first, len)
        off = 0
        heapcpy = pagecache(first, len)
        while off < len
                he = @cp.decode_c_struct('_HEAP_ENTRY', heapcpy, off)
                sz = (he.Size ^ @chunkkey_size)*8
                if (he.Flags ^ @chunkkey_flags) & 1 == 1
                        @chunks[first+off+@hsz] = sz - (he.UnusedBytes ^ @chunkkey_unusedbytes)
                end
                off += sz
        end
end
scan_lfh_ss(subseg) click to toggle source
# File samples/dbg-plugins/heapscan/heapscan.rb, line 674
        def scan_lfh_ss(subseg)
                up = subseg.userblocks
                return if not up
                bs = subseg.blocksize
                bc = subseg.blockcount
                list = Array.new(bc) { |i| up + 0x10 + bs*8*i }

                free = []
                ptr = subseg.freeentryoffset
                subseg.depth.times { 
                        free << (up + 8*ptr)
                        ptr = @dbg.memory[up + 8*ptr + 8, 2].unpack('v')[0]
                }
@foo ||= 0
@foo += 1
p @foo if @foo % 10 == 0

                up += 0x10
                list -= free
                list.each { |p| @chunks[p+8] = bs*8 - (@cp.decode_c_struct('_HEAP_ENTRY', @dbg.memory, p).unusedbytes & 0x7f) }
        end