Class: Pwnlib::DynELF
Overview
DynELF class, resolve symbols in loaded, dynamically-linked ELF binaries. Given a function which can leak data at an arbitrary address, any symbol in any loaded library can be resolved.
Instance Attribute Summary collapse
-
#libbase ⇒ Integer
readonly
Base of lib.
Instance Method Summary collapse
-
#build_id ⇒ String?
Leak the BuildID of the remote libc.so.
-
#initialize(addr) {|leak_addr| ... } ⇒ DynELF
constructor
Instantiate a DynELF object.
-
#lookup(symbol) ⇒ Integer?
Lookup a symbol from the ELF.
Constructor Details
#initialize(addr) {|leak_addr| ... } ⇒ DynELF
Instantiate a Pwnlib::DynELF object.
26 27 28 29 30 31 32 33 |
# File 'lib/pwnlib/dynelf.rb', line 26 def initialize(addr, &block) @leak = ::Pwnlib::MemLeak.new(&block) @libbase = find_base(addr) @elfclass = { 0x1 => 32, 0x2 => 64 }[@leak.b(@libbase + 4)] @elfword = @elfclass / 8 @dynamic = find_dynamic @hshtab = @strtab = @symtab = nil end |
Instance Attribute Details
#libbase ⇒ Integer (readonly)
Returns Base of lib.
14 15 16 |
# File 'lib/pwnlib/dynelf.rb', line 14 def libbase @libbase end |
Instance Method Details
#build_id ⇒ String?
Leak the BuildID of the remote libc.so.
81 82 83 84 85 86 87 88 |
# File 'lib/pwnlib/dynelf.rb', line 81 def build_id build_id_offsets.each do |offset| next unless @leak.n(@libbase + offset + 12, 4) == "GNU\x00" return @leak.n(@libbase + offset + 16, 20).unpack1('H*') end nil end |
#lookup(symbol) ⇒ Integer?
Lookup a symbol from the ELF.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/pwnlib/dynelf.rb', line 42 def lookup(symbol) symbol = symbol.to_s sym_size = { 32 => 16, 64 => 24 }[@elfclass] # Leak GNU_HASH section header. nbuckets = @leak.d(hshtab) symndx = @leak.d(hshtab + 4) maskwords = @leak.d(hshtab + 8) l_gnu_buckets = hshtab + 16 + (@elfword * maskwords) l_gnu_chain_zero = l_gnu_buckets + (4 * nbuckets) - (4 * symndx) hsh = gnu_hash(symbol) bucket = hsh % nbuckets i = @leak.d(l_gnu_buckets + bucket * 4) return nil if i.zero? hsh2 = 0 while (hsh2 & 1).zero? hsh2 = @leak.d(l_gnu_chain_zero + i * 4) if ((hsh ^ hsh2) >> 1).zero? sym = symtab + sym_size * i st_name = @leak.d(sym) name = @leak.n(strtab + st_name, symbol.length + 1) if name == ("#{symbol}\x00") offset = { 32 => 4, 64 => 8 }[@elfclass] st_value = unpack(@leak.n(sym + offset, @elfword)) return @libbase + st_value end end i += 1 end nil end |