Class: Pwnlib::ELF::ELF
- Inherits:
-
Object
- Object
- Pwnlib::ELF::ELF
- Includes:
- Logger
- Defined in:
- lib/pwnlib/elf/elf.rb
Overview
Main class for using Pwnlib::ELF module.
Instance Attribute Summary collapse
-
#address ⇒ Integer
Base address.
-
#got ⇒ OpenStruct
readonly
GOT symbols.
-
#plt ⇒ OpenStruct
readonly
PLT symbols.
-
#symbols ⇒ OpenStruct
readonly
All symbols.
Instance Method Summary collapse
-
#canary? ⇒ Boolean
Is this ELF file has canary?.
-
#checksec ⇒ String
Return the protection information, wrapper with color codes.
-
#initialize(path, checksec: true) ⇒ ELF
constructor
Instantiate an ELF object.
-
#inspect ⇒ String
There’s too many objects inside, let pry not so verbose.
-
#nx? ⇒ Boolean
Is stack executable?.
-
#one_gadgets ⇒ Array<Integer>
Returns one-gadgets of glibc.
-
#pie? ⇒ Boolean
Is this ELF file a position-independent executable?.
-
#relro ⇒ :full, ...
The method used in relro.
-
#search(needle) ⇒ Enumerator<Integer>
(also: #find)
Yields the ELF’s virtual address space for the specified string or regexp.
Constructor Details
#initialize(path, checksec: true) ⇒ ELF
Instantiate an Pwnlib::ELF::ELF object.
Will show checksec information to stdout.
45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/pwnlib/elf/elf.rb', line 45 def initialize(path, checksec: true) @path = File.realpath(path) @elf_file = ELFTools::ELFFile.new(File.open(path, 'rb')) load_got load_plt load_symbols @address = base_address @load_addr = @address @one_gadgets = nil show_info(@path) if checksec end |
Instance Attribute Details
#address ⇒ Integer
Returns Base address.
26 27 28 |
# File 'lib/pwnlib/elf/elf.rb', line 26 def address @address end |
#got ⇒ OpenStruct (readonly)
Returns GOT symbols.
17 18 19 |
# File 'lib/pwnlib/elf/elf.rb', line 17 def got @got end |
#plt ⇒ OpenStruct (readonly)
Returns PLT symbols.
20 21 22 |
# File 'lib/pwnlib/elf/elf.rb', line 20 def plt @plt end |
#symbols ⇒ OpenStruct (readonly)
Returns All symbols.
23 24 25 |
# File 'lib/pwnlib/elf/elf.rb', line 23 def symbols @symbols end |
Instance Method Details
#canary? ⇒ Boolean
Is this ELF file has canary?
Actually judged by if __stack_chk_fail
in got symbols.
126 127 128 |
# File 'lib/pwnlib/elf/elf.rb', line 126 def canary? @got.respond_to?('__stack_chk_fail') || @symbols.respond_to?('__stack_chk_fail') end |
#checksec ⇒ String
Return the protection information, wrapper with color codes.
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/pwnlib/elf/elf.rb', line 83 def checksec [ 'RELRO:'.ljust(10) + { full: Rainbow('Full RELRO').green, partial: Rainbow('Partial RELRO').yellow, none: Rainbow('No RELRO').red }[relro], 'Stack:'.ljust(10) + { true => Rainbow('Canary found').green, false => Rainbow('No canary found').red }[canary?], 'NX:'.ljust(10) + { true => Rainbow('NX enabled').green, false => Rainbow('NX disabled').red }[nx?], 'PIE:'.ljust(10) + { true => Rainbow('PIE enabled').green, false => Rainbow(format('No PIE (0x%x)', address)).red }[pie?] ].join("\n") end |
#inspect ⇒ String
There’s too many objects inside, let pry not so verbose.
146 147 148 |
# File 'lib/pwnlib/elf/elf.rb', line 146 def inspect "#<Pwnlib::ELF::ELF:#{::Pwnlib::Util::Fiddling.hex(__id__)}>" end |
#nx? ⇒ Boolean
Is stack executable?
133 134 135 |
# File 'lib/pwnlib/elf/elf.rb', line 133 def nx? !@elf_file.segment_by_type(:gnu_stack).executable? end |
#one_gadgets ⇒ Array<Integer>
Returns one-gadgets of glibc.
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/pwnlib/elf/elf.rb', line 221 def one_gadgets return @one_gadgets if @one_gadgets gadgets = OneGadget.gadgets(file: @path, details: true, level: 1) @one_gadgets = gadgets.map { |g| g.offset + address } @one_gadgets.instance_variable_set(:@gadgets, gadgets) class << @one_gadgets def [](idx) super.tap { log.debug(@gadgets[idx].inspect) } end def first self[0] end def last self[-1] end include ::Pwnlib::Logger end @one_gadgets end |
#pie? ⇒ Boolean
Is this ELF file a position-independent executable?
140 141 142 |
# File 'lib/pwnlib/elf/elf.rb', line 140 def pie? @elf_file.elf_type == 'DYN' end |
#relro ⇒ :full, ...
The method used in relro.
108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/pwnlib/elf/elf.rb', line 108 def relro return :none unless @elf_file.segment_by_type(:gnu_relro) return :full if dynamic_tag(:bind_now) flags = dynamic_tag(:flags) return :full if flags && (flags.value & ::ELFTools::Constants::DF_BIND_NOW) != 0 flags1 = dynamic_tag(:flags_1) return :full if flags1 && (flags1.value & ::ELFTools::Constants::DF_1_NOW) != 0 :partial end |
#search(needle) ⇒ Enumerator<Integer> Also known as: find
Yields the ELF’s virtual address space for the specified string or regexp. Returns an Enumerator if no block given.
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/pwnlib/elf/elf.rb', line 169 def search(needle) return enum_for(:search, needle) unless block_given? load_address_fixup = @address - @load_addr stream = @elf_file.stream @elf_file.each_segments do |seg| addr = seg.header.p_vaddr memsz = seg.header.p_memsz offset = seg.header.p_offset stream.pos = offset data = stream.read(memsz).ljust(seg.header.p_filesz, "\x00") offset = 0 loop do offset = data.index(needle, offset) break if offset.nil? yield (addr + offset + load_address_fixup) offset += 1 end end true end |