@@ -143,6 +143,8 @@ def validate_relocations
143143 rela_dyn = @context . sections . find { |section | section . section_name . to_s == ".rela.dyn" }
144144 pt_load = @context . program_headers . find { |ph | ph . type == :LOAD }
145145 dynamic = @context . sections . find { |section | section . section_name . to_s == ".dynamic" }
146+ rela_plt = @context . sections . find { |section | section . section_name . to_s == ".rela.plt" }
147+ failed_messages = [ ]
146148 unless rela_dyn && pt_load && dynamic
147149 data = [
148150 rela_dyn ? nil : ".rela.dyn section" ,
@@ -160,15 +162,25 @@ def validate_relocations
160162 val = 24 if dyn . rela_ent?
161163 next unless val
162164 if dyn . un != val
163- raise Caotral :: Binary :: ELF :: Error , "Invalid dynamic section entry: expected #{ val } , got #{ dyn . un } "
165+ failed_messages << "Invalid dynamic section entry: expected #{ val } , got #{ dyn . un } "
164166 end
165167 end
166168
167169 valid_range = ( pt_load . vaddr ...( pt_load . vaddr + pt_load . memsz ) )
168170 unless rela_dyn . body . all? { |rel | valid_range . include? ( rel . offset ) }
169- raise Caotral :: Binary :: ELF :: Error , "Relocation entries in .rela.dyn exceed LOAD segment range"
171+ failed_messages << "Relocation entries in .rela.dyn exceed LOAD segment range"
170172 end
171173
174+ if rela_plt
175+ dynamic . body . find { |dt | dt . jmp_rel? } &.un == rela_plt . header . addr || failed_messages << "Dynamic section entry DT_JMPREL does not match .rela.plt address"
176+ dynamic . body . find { |dt | dt . plt_rel_size? } &.un == rela_plt . header . size || failed_messages << "Dynamic section entry DT_PLTRELSZ does not match .rela.plt size"
177+ dynamic . body . find { |dt | dt . plt_rel? } &.un == 7 || failed_messages << "Dynamic section entry DT_PLTREL does not indicate RELA type"
178+ rela_plt . body . each do |rel |
179+ valid_range . include? ( rel . offset ) || failed_messages << "Relocation entries in .rela.plt exceed LOAD segment range"
180+ rela_type_name ( rel . type ) == :AMD64_JUMP_SLOT || failed_messages << "Unexpected relocation type in .rela.plt: #{ rel . type_name } "
181+ end
182+ end
183+ raise Caotral ::Binary ::ELF ::Error , failed_messages . join ( "\n " ) unless failed_messages . empty?
172184 true
173185 end
174186
@@ -182,7 +194,8 @@ def decision(input)
182194 end
183195 end
184196
185- def type ( num ) = Caotral ::Binary ::ELF ::SectionHeader ::SHT_BY_VALUE . fetch ( num , :unknown )
197+ def section_type_name ( num ) = Caotral ::Binary ::ELF ::SectionHeader ::SHT_BY_VALUE . fetch ( num , :unknown )
198+ def rela_type_name ( num ) = Caotral ::Binary ::ELF ::Section ::Rel ::TYPES_BY_V . fetch ( num , :unknown )
186199 end
187200 end
188201 end
0 commit comments