mirror of
https://github.com/david942j/one_gadget.git
synced 2026-10-11 22:09:54 +00:00
Ask a load segment where it is, rather than reading its header (#461)
Every one of these is a LOAD segment, and LoadSegment already answers for
what they were taking out of the header: mem_head, file_head, and mem_tail
for the p_vaddr + p_memsz the harness was adding up itself.
The gadget corpus is byte-identical at levels 0, 1 and 2, and the address
the harness steers writes to is unchanged for every fixture.
Left alone: helper.rb reads e_machine, for which there is no accessor --
ELFFile#machine answers with a display string ("Advanced Micro Devices
X86-64 processor"), which is no basis for choosing a fetcher.
This commit is contained in:
@@ -70,7 +70,7 @@ module Aletheia
|
|||||||
def spare_writable(target)
|
def spare_writable(target)
|
||||||
end_of_data = File.open(target) do |f|
|
end_of_data = File.open(target) do |f|
|
||||||
ELFTools::ELFFile.new(f).segments_by_type(:load).select(&:writable?)
|
ELFTools::ELFFile.new(f).segments_by_type(:load).select(&:writable?)
|
||||||
.map { |s| s.header.p_vaddr.to_i + s.header.p_memsz.to_i }.max
|
.map(&:mem_tail).max
|
||||||
end
|
end
|
||||||
return nil unless end_of_data
|
return nil unless end_of_data
|
||||||
|
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ module OneGadget
|
|||||||
record_instruction_sets(elf)
|
record_instruction_sets(elf)
|
||||||
@objdump.read_raw(machine: OneGadget::Helper.objdump_arch(OneGadget::Helper.architecture(file)),
|
@objdump.read_raw(machine: OneGadget::Helper.objdump_arch(OneGadget::Helper.architecture(file)),
|
||||||
endian: elf.endian,
|
endian: elf.endian,
|
||||||
vma: seg.header.p_vaddr.to_i - seg.header.p_offset.to_i)
|
vma: seg.mem_head - seg.file_head)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -187,7 +187,7 @@ module OneGadget
|
|||||||
seg = executable_segment(elf)
|
seg = executable_segment(elf)
|
||||||
return nil if seg.nil?
|
return nil if seg.nil?
|
||||||
|
|
||||||
scan_calls(seg.header.p_vaddr.to_i, seg.data, targets)
|
scan_calls(seg.mem_head, seg.data, targets)
|
||||||
end
|
end
|
||||||
rescue ELFTools::ELFError
|
rescue ELFTools::ELFError
|
||||||
nil # not something we can scan; disassemble everything
|
nil # not something we can scan; disassemble everything
|
||||||
@@ -197,7 +197,7 @@ module OneGadget
|
|||||||
# what raw disassembly is taken from. It holds a little besides the code, and
|
# what raw disassembly is taken from. It holds a little besides the code, and
|
||||||
# is used in place of a section because a stripped file has none.
|
# is used in place of a section because a stripped file has none.
|
||||||
# @param [ELFTools::ELFFile] elf
|
# @param [ELFTools::ELFFile] elf
|
||||||
# @return [ELFTools::Segments::Segment, nil]
|
# @return [ELFTools::Segments::LoadSegment, nil]
|
||||||
def executable_segment(elf)
|
def executable_segment(elf)
|
||||||
elf.segments_by_type(:load).find(&:executable?)
|
elf.segments_by_type(:load).find(&:executable?)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ module OneGadget
|
|||||||
@loaded_code = File.open(file) do |fd|
|
@loaded_code = File.open(file) do |fd|
|
||||||
elf = ELFTools::ELFFile.new(fd)
|
elf = ELFTools::ELFFile.new(fd)
|
||||||
segment = executable_segment(elf)
|
segment = executable_segment(elf)
|
||||||
segment && { base: segment.header.p_vaddr.to_i,
|
segment && { base: segment.mem_head,
|
||||||
words: segment.data.unpack(elf.endian == :big ? 'N*' : 'V*') }
|
words: segment.data.unpack(elf.endian == :big ? 'N*' : 'V*') }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user