node/lib/metasm/samples/dbg-plugins/heapscan/graphheap.rb
def create_struct(addr)
		raise "no chunk here" if not @heap.chunks[addr]

		ptsz = @dasm.cpu.size/8

		# check if this is a c++ object with RTTI info
		vptr = @dasm.decode_dword(addr)
		rtti = @dasm.decode_dword(vptr-ptsz)
		case OS.shortname
		when 'winos'
			typeinfo = @dasm.decode_dword(rtti+3*ptsz) if rtti
			if typeinfo and s = @dasm.decode_strz(typeinfo+3*ptsz)
				rtti_name = s[/^(.*)@@$/, 1]	# remove trailing @@
			end
		when 'linos'
			typeinfo = @dasm.decode_dword(rtti+ptsz) if rtti
			if typeinfo and s = @dasm.decode_strz(typeinfo)
				rtti_name = s[/^[0-9]+(.*)$/, 1]	# remove leading number
			end
		end

		if rtti_name and st = @heap.cp.toplevel.struct[rtti_name]
			return @heap.chunk_struct[addr] = st
		end

		st = C::Struct.new
		st.name = rtti_name || "chunk_#{'%x' % addr}"
		st.members = []
		li = 0
		(@heap.chunks[addr] / ptsz).times { |i|
			n = 'unk_%x' % (ptsz*i)
			v = @dasm.decode_dword(addr+ptsz*i)
			if i == 0 and rtti_name
				t = C::Pointer.new(C::Pointer.new(C::BaseType.new(:void)))
				n = 'vtable'
			elsif @heap.chunks[v]
				t = C::Pointer.new(C::BaseType.new(:void))
			else
				t = C::BaseType.new("__int#{ptsz*8}".to_sym, :unsigned)
			end
			st.members << C::Variable.new(n, t)
			li = i+1
		}
		(@heap.chunks[addr] % ptsz).times { |i|
			n = 'unk_%x' % (ptsz*li+i)
			t = C::BaseType.new(:char, :unsigned)
			st.members << C::Variable.new(n, t)
		}
		@heap.cp.toplevel.struct[st.name] = st
		@heap.chunk_struct[addr] = st
	end
# create the struct chunk_<addr>, register it in @heap.chunk_struct
create the struct chunk_, register it in @heap.chunk_struct
create the struct chunk_ register it in @heap . chunk_struct
def create_struct(addr)
		raise "no chunk here" if not @heap.chunks[addr]
		ptsz = @dasm.cpu.size/8
		vptr = @dasm.decode_dword(addr)
		rtti = @dasm.decode_dword(vptr-ptsz)
		case OS.shortname
		when 'winos'
			typeinfo = @dasm.decode_dword(rtti+3*ptsz) if rtti
			if typeinfo and s = @dasm.decode_strz(typeinfo+3*ptsz)
				rtti_name = s[/^(.*)@@$/, 1]	
			end
		when 'linos'
			typeinfo = @dasm.decode_dword(rtti+ptsz) if rtti
			if typeinfo and s = @dasm.decode_strz(typeinfo)
				rtti_name = s[/^[0-9]+(.*)$/, 1]	
			end
		end
		if rtti_name and st = @heap.cp.toplevel.struct[rtti_name]
			return @heap.chunk_struct[addr] = st
		end
		st = C::Struct.new
		st.name = rtti_name || "chunk_#{'%x' % addr}"
		st.members = []
		li = 0
		(@heap.chunks[addr] / ptsz).times { |i|
			n = 'unk_%x' % (ptsz*i)
			v = @dasm.decode_dword(addr+ptsz*i)
			if i == 0 and rtti_name
				t = C::Pointer.new(C::Pointer.new(C::BaseType.new(:void)))
				n = 'vtable'
			elsif @heap.chunks[v]
				t = C::Pointer.new(C::BaseType.new(:void))
			else
				t = C::BaseType.new("__int#{ptsz*8}".to_sym, :unsigned)
			end
			st.members << C::Variable.new(n, t)
			li = i+1
		}
		(@heap.chunks[addr] % ptsz).times { |i|
			n = 'unk_%x' % (ptsz*li+i)
			t = C::BaseType.new(:char, :unsigned)
			st.members << C::Variable.new(n, t)
		}
		@heap.cp.toplevel.struct[st.name] = st
		@heap.chunk_struct[addr] = st
	end
def create_struct ( addr ) raise "no chunk here" if not @heap . chunks [ addr ] ptsz = @dasm . cpu . size / 8 vptr = @dasm . decode_dword ( addr ) rtti = @dasm . decode_dword ( vptr - ptsz ) case OS . shortname when 'winos' typeinfo = @dasm . decode_dword ( rtti + 3 * ptsz ) if rtti if typeinfo and s = @dasm . decode_strz ( typeinfo + 3 * ptsz ) rtti_name = s [ / ^(.*)@@$ / , 1 ] end when 'linos' typeinfo = @dasm . decode_dword ( rtti + ptsz ) if rtti if typeinfo and s = @dasm . decode_strz ( typeinfo ) rtti_name = s [ / ^[0-9]+(.*)$ / , 1 ] end end if rtti_name and st = @heap . cp . toplevel . struct [ rtti_name ] return @heap . chunk_struct [ addr ] = st end st = C :: Struct . new st . name = rtti_name || "chunk_#{'%x' % addr}" st . members = [ ] li = 0 ( @heap . chunks [ addr ] / ptsz ) . times { | i | n = 'unk_%x' % ( ptsz * i ) v = @dasm . decode_dword ( addr + ptsz * i ) if i == 0 and rtti_name t = C :: Pointer . new ( C :: Pointer . new ( C :: BaseType . new ( :void ) ) ) n = 'vtable' elsif @heap . chunks [ v ] t = C :: Pointer . new ( C :: BaseType . new ( :void ) ) else t = C :: BaseType . new ( "__int#{ptsz*8}" . to_sym , :unsigned ) end st . members << C :: Variable . new ( n , t ) li = i + 1 } ( @heap . chunks [ addr ] % ptsz ) . times { | i | n = 'unk_%x' % ( ptsz * li + i ) t = C :: BaseType . new ( :char , :unsigned ) st . members << C :: Variable . new ( n , t ) } @heap . cp . toplevel . struct [ st . name ] = st @heap . chunk_struct [ addr ] = st end
create the struct chunk_<addr>, register it in @heap.chunk_struct
create the struct chunk_<addr > register it in @heap . chunk_struct
# check if this is a c++ object with RTTI info # remove trailing @@ # remove leading number
addr