node/lib/metasm/metasm/exe_format/elf_encode.rb
def encode_make_segments_from_sections
		# fixed addresses first
		seclist = @sections.find_all { |sec| sec.addr.kind_of? Integer }.sort_by { |sec| sec.addr } | @sections
		seclist.each { |sec|
			next if not sec.flags.to_a.include? 'ALLOC'

			# check if we fit in an existing segment
			loadsegs = @segments.find_all { |seg_| seg_.type == 'LOAD' }

			if sec.addr.kind_of?(::Integer) and seg = loadsegs.find { |seg_|
				seg_.vaddr.kind_of?(::Integer) and seg_.vaddr <= sec.addr and seg_.vaddr + seg_.memsz >= sec.addr + sec.size
			}
				# sections is already inside a segment: we're reencoding an ELF, just patch the section in the segment
				seg.encoded[sec.addr - seg.vaddr, sec.size] = sec.encoded if sec.encoded
				next
			end

			if not seg = loadsegs.find { |seg_|
				sec.flags.to_a.include?('WRITE') == seg_.flags.to_a.include?('W') and
				#sec.flags.to_a.include?('EXECINSTR') == seg_.flags.to_a.include?('X') and
				not seg_.memsz and
				not loadsegs[loadsegs.index(seg_)+1..-1].find { |sseg|
					# check if another segment would overlap if we add the sec to seg_
					o = Expression[sseg.vaddr, :-, [seg_.vaddr, :+, seg_.encoded.length+sec.encoded.length]].reduce
					o.kind_of? ::Integer and o < 0
				}
			}
				# nope, create a new one
				seg = Segment.new
				seg.type = 'LOAD'
				seg.flags = ['R']
				seg.flags << 'W' if sec.flags.include? 'WRITE'
				seg.align = 0x1000
				seg.encoded = EncodedData.new
				seg.offset = new_label('segment_offset')
				seg.vaddr = sec.addr || new_label('segment_address')
				@segments << seg
			end
			seg.flags |= ['X'] if sec.flags.include? 'EXECINSTR'
			seg.encoded.align sec.addralign if sec.addralign
			sec.addr = Expression[seg.vaddr, :+, seg.encoded.length]
			sec.offset = Expression[seg.offset, :+, seg.encoded.length]
			seg.encoded << sec.encoded
		}
	end
# put every ALLOC section in a segment, create segments if needed
# sections with a good offset within a segment are ignored
put every ALLOC section in a segment, create segments if needed
sections with a good offset within a segment are ignored
put every ALLOC section in a segment create segments if needed sections with a good offset within a segment are ignored
def encode_make_segments_from_sections
		seclist = @sections.find_all { |sec| sec.addr.kind_of? Integer }.sort_by { |sec| sec.addr } | @sections
		seclist.each { |sec|
			next if not sec.flags.to_a.include? 'ALLOC'
			loadsegs = @segments.find_all { |seg_| seg_.type == 'LOAD' }
			if sec.addr.kind_of?(::Integer) and seg = loadsegs.find { |seg_|
				seg_.vaddr.kind_of?(::Integer) and seg_.vaddr <= sec.addr and seg_.vaddr + seg_.memsz >= sec.addr + sec.size
			}
				seg.encoded[sec.addr - seg.vaddr, sec.size] = sec.encoded if sec.encoded
				next
			end
			if not seg = loadsegs.find { |seg_|
				sec.flags.to_a.include?('WRITE') == seg_.flags.to_a.include?('W') and
				not seg_.memsz and
				not loadsegs[loadsegs.index(seg_)+1..-1].find { |sseg|
					o = Expression[sseg.vaddr, :-, [seg_.vaddr, :+, seg_.encoded.length+sec.encoded.length]].reduce
					o.kind_of? ::Integer and o < 0
				}
			}
				seg = Segment.new
				seg.type = 'LOAD'
				seg.flags = ['R']
				seg.flags << 'W' if sec.flags.include? 'WRITE'
				seg.align = 0x1000
				seg.encoded = EncodedData.new
				seg.offset = new_label('segment_offset')
				seg.vaddr = sec.addr || new_label('segment_address')
				@segments << seg
			end
			seg.flags |= ['X'] if sec.flags.include? 'EXECINSTR'
			seg.encoded.align sec.addralign if sec.addralign
			sec.addr = Expression[seg.vaddr, :+, seg.encoded.length]
			sec.offset = Expression[seg.offset, :+, seg.encoded.length]
			seg.encoded << sec.encoded
		}
	end
def encode_make_segments_from_sections seclist = @sections . find_all { | sec | sec . addr . kind_of? Integer } . sort_by { | sec | sec . addr } | @sections seclist . each { | sec | next if not sec . flags . to_a . include? 'ALLOC' loadsegs = @segments . find_all { | seg_ | seg_ . type == 'LOAD' } if sec . addr . kind_of? ( :: Integer ) and seg = loadsegs . find { | seg_ | seg_ . vaddr . kind_of? ( :: Integer ) and seg_ . vaddr <= sec . addr and seg_ . vaddr + seg_ . memsz >= sec . addr + sec . size } seg . encoded [ sec . addr - seg . vaddr , sec . size ] = sec . encoded if sec . encoded next end if not seg = loadsegs . find { | seg_ | sec . flags . to_a . include? ( 'WRITE' ) == seg_ . flags . to_a . include? ( 'W' ) and not seg_ . memsz and not loadsegs [ loadsegs . index ( seg_ ) + 1 .. - 1 ] . find { | sseg | o = Expression [ sseg . vaddr , :- , [ seg_ . vaddr , :+ , seg_ . encoded . length + sec . encoded . length ] ] . reduce o . kind_of? :: Integer and o < 0 } } seg = Segment . new seg . type = 'LOAD' seg . flags = [ 'R' ] seg . flags << 'W' if sec . flags . include? 'WRITE' seg . align = 0x1000 seg . encoded = EncodedData . new seg . offset = new_label ( 'segment_offset' ) seg . vaddr = sec . addr || new_label ( 'segment_address' ) @segments << seg end seg . flags |= [ 'X' ] if sec . flags . include? 'EXECINSTR' seg . encoded . align sec . addralign if sec . addralign sec . addr = Expression [ seg . vaddr , :+ , seg . encoded . length ] sec . offset = Expression [ seg . offset , :+ , seg . encoded . length ] seg . encoded << sec . encoded } end
put every ALLOC section in a segment, create segments if needed
sections with a good offset within a segment are ignored
put every ALLOC section in a segment create segments if needed sections with a good offset within a segment are ignored
# fixed addresses first # check if we fit in an existing segment # sections is already inside a segment: we're reencoding an ELF, just patch the section in the segment #sec.flags.to_a.include?('EXECINSTR') == seg_.flags.to_a.include?('X') and # check if another segment would overlap if we add the sec to seg_ # nope, create a new one