node/lib/metasm/metasm/exe_format/coff_encode.rb
def create_relocation_tables
		@relocations = []

		# create a fake binding with all exports, to find only-image_base-dependant relocs targets
		# not foolproof, but works in standard cases
		startaddr = curaddr = label_at(@encoded, 0, 'coff_start')
		binding = {}
		@sections.each { |s|
			binding.update s.encoded.binding(curaddr)
			curaddr = Expression[curaddr, :+, s.encoded.virtsize]
		}

		# for each section.encoded, make as many RelocationTables as needed
		@sections.each { |s|

			# rt.base_addr temporarily holds the offset from section_start, and is fixed up to rva before '@reloc << rt'
			rt = RelocationTable.new

			s.encoded.reloc.each { |off, rel|
				# check that the relocation looks like "program_start + integer" when bound using the fake binding
				# XXX allow :i32 etc
				if rel.endianness == @endianness and [:u32, :a32, :u64, :a64].include?(rel.type) and
				rel.target.bind(binding).reduce.kind_of?(Expression) and
				Expression[rel.target, :-, startaddr].bind(binding).reduce.kind_of?(::Integer)
					# winner !

					# build relocation
					r = RelocationTable::Relocation.new
					r.offset = off & 0xfff
					r.type = { :u32 => 'HIGHLOW', :u64 => 'DIR64', :a32 => 'HIGHLOW', :a64 => 'DIR64' }[rel.type]

					# check if we need to start a new relocation table
					if rt.base_addr and (rt.base_addr & ~0xfff) != (off & ~0xfff)
						rt.base_addr = Expression[[label_at(s.encoded, 0, 'sect_start'), :-, startaddr], :+, rt.base_addr]
						@relocations << rt
						rt = RelocationTable.new
					end

					# initialize reloc table base address if needed
					rt.base_addr ||= off & ~0xfff

					(rt.relocs ||= []) << r
				elsif $DEBUG and not rel.target.bind(binding).reduce.kind_of?(Integer)
					puts "W: COFF: Ignoring weird relocation #{rel.inspect} when building relocation tables"
				end
			}

			if rt and rt.relocs
				rt.base_addr = Expression[[label_at(s.encoded, 0, 'sect_start'), :-, startaddr], :+, rt.base_addr]
				@relocations << rt
			end
		}
	end
# creates the @relocations from sections.encoded.reloc
creates the @relocations from sections.encoded.reloc
creates the @relocations from sections . encoded . reloc
def create_relocation_tables
		@relocations = []
		startaddr = curaddr = label_at(@encoded, 0, 'coff_start')
		binding = {}
		@sections.each { |s|
			binding.update s.encoded.binding(curaddr)
			curaddr = Expression[curaddr, :+, s.encoded.virtsize]
		}
		@sections.each { |s|
			rt = RelocationTable.new
			s.encoded.reloc.each { |off, rel|
				if rel.endianness == @endianness and [:u32, :a32, :u64, :a64].include?(rel.type) and
				rel.target.bind(binding).reduce.kind_of?(Expression) and
				Expression[rel.target, :-, startaddr].bind(binding).reduce.kind_of?(::Integer)
					r = RelocationTable::Relocation.new
					r.offset = off & 0xfff
					r.type = { :u32 => 'HIGHLOW', :u64 => 'DIR64', :a32 => 'HIGHLOW', :a64 => 'DIR64' }[rel.type]
					if rt.base_addr and (rt.base_addr & ~0xfff) != (off & ~0xfff)
						rt.base_addr = Expression[[label_at(s.encoded, 0, 'sect_start'), :-, startaddr], :+, rt.base_addr]
						@relocations << rt
						rt = RelocationTable.new
					end
					rt.base_addr ||= off & ~0xfff
					(rt.relocs ||= []) << r
				elsif $DEBUG and not rel.target.bind(binding).reduce.kind_of?(Integer)
					puts "W: COFF: Ignoring weird relocation #{rel.inspect} when building relocation tables"
				end
			}
			if rt and rt.relocs
				rt.base_addr = Expression[[label_at(s.encoded, 0, 'sect_start'), :-, startaddr], :+, rt.base_addr]
				@relocations << rt
			end
		}
	end
def create_relocation_tables @relocations = [ ] startaddr = curaddr = label_at ( @encoded , 0 , 'coff_start' ) binding = { } @sections . each { | s | binding . update s . encoded . binding ( curaddr ) curaddr = Expression [ curaddr , :+ , s . encoded . virtsize ] } @sections . each { | s | rt = RelocationTable . new s . encoded . reloc . each { | off , rel | if rel . endianness == @endianness and [ :u32 , :a32 , :u64 , :a64 ] . include? ( rel . type ) and rel . target . bind ( binding ) . reduce . kind_of? ( Expression ) and Expression [ rel . target , :- , startaddr ] . bind ( binding ) . reduce . kind_of? ( :: Integer ) r = RelocationTable :: Relocation . new r . offset = off & 0xfff r . type = { :u32 => 'HIGHLOW' , :u64 => 'DIR64' , :a32 => 'HIGHLOW' , :a64 => 'DIR64' } [ rel . type ] if rt . base_addr and ( rt . base_addr & ~ 0xfff ) != ( off & ~ 0xfff ) rt . base_addr = Expression [ [ label_at ( s . encoded , 0 , 'sect_start' ) , :- , startaddr ] , :+ , rt . base_addr ] @relocations << rt rt = RelocationTable . new end rt . base_addr ||= off & ~ 0xfff ( rt . relocs ||= [ ] ) << r elsif $DEBUG and not rel . target . bind ( binding ) . reduce . kind_of? ( Integer ) puts "W: COFF: Ignoring weird relocation #{rel.inspect} when building relocation tables" end } if rt and rt . relocs rt . base_addr = Expression [ [ label_at ( s . encoded , 0 , 'sect_start' ) , :- , startaddr ] , :+ , rt . base_addr ] @relocations << rt end } end
creates the @relocations from sections.encoded.reloc
creates the @relocations from sections . encoded . reloc
# create a fake binding with all exports, to find only-image_base-dependant relocs targets # not foolproof, but works in standard cases # for each section.encoded, make as many RelocationTables as needed # rt.base_addr temporarily holds the offset from section_start, and is fixed up to rva before '@reloc << rt' # check that the relocation looks like "program_start + integer" when bound using the fake binding # XXX allow :i32 etc # winner ! # build relocation # check if we need to start a new relocation table # initialize reloc table base address if needed