Class: HeapInfo::Process
- Inherits:
-
Object
- Object
- HeapInfo::Process
- Defined in:
- lib/heapinfo/process.rb
Overview
Main class of heapinfo.
Constant Summary collapse
- DEFAULT_LIB =
The default options of libraries, use for matching glibc segments in
/proc/[pid]/maps. { libc: /bc[^a-z]*\.so/ }.freeze
Instance Attribute Summary collapse
-
#pid ⇒ Integer?
readonly
The pid of process,
nilif no such process found.
Instance Method Summary collapse
-
#canary ⇒ Integer
Get the value of stack guard.
-
#debug ⇒ Object
Use this method to wrapper all HeapInfo methods.
-
#dump(*args) ⇒ String, HeapInfo::Nil
Dump the content of specific memory address.
-
#dump_chunks(*args) ⇒ HeapInfo::Chunks, HeapInfo::Nil
Return the dump result as chunks.
-
#find(pattern, from, length = :unlimited, rel: false) ⇒ Integer?
(also: #search)
GDB-style command.
-
#find_all(pattern, from = 0, to = 1 << 64) ⇒ void
(also: #findall)
Find pattern in all segments with pretty output.
-
#initialize(prog, options = {}) ⇒ Process
constructor
Instantiate a Process object.
-
#inspect ⇒ String
Make pry not so verbose.
-
#layouts(*args) ⇒ void
Pretty dump of bins' layouts.
-
#offset(addr, sym = nil) ⇒ void
(also: #off)
Show the offset in pretty way between the segment.
-
#reload! ⇒ HeapInfo::Process
(also: #reload)
Reload a new process with same program name.
-
#s(address) ⇒ String
GDB-style command.
-
#to_s ⇒ String
Show simple information of target process.
-
#x(count, address) ⇒ void
GDB-style command.
Constructor Details
#initialize(prog, options = {}) ⇒ Process
Instantiate a HeapInfo::Process object.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/heapinfo/process.rb', line 24 def initialize(prog, = {}) @prog = prog @options = DEFAULT_LIB.merge @pid = nil # Transparent info's methods ProcessInfo::EXPORT.each do |m| define_singleton_method(m) do return Nil.instance if @pid.nil? @info.__send__(m) end end load! end |
Instance Attribute Details
#pid ⇒ Integer? (readonly)
Returns The pid of process, nil if no such process found.
18 19 20 |
# File 'lib/heapinfo/process.rb', line 18 def pid @pid end |
Instance Method Details
#canary ⇒ Integer
Get the value of stack guard.
323 324 325 326 327 328 |
# File 'lib/heapinfo/process.rb', line 323 def canary return Nil.instance unless load? addr = @info.auxv[:random] Helper.unpack(bits / 8, @dumper.dump(addr, bits / 8)) & 0xffffffffffffff00 end |
#debug ⇒ Object
66 67 68 69 70 |
# File 'lib/heapinfo/process.rb', line 66 def debug return unless load! yield if block_given? end |
#dump(*args) ⇒ String, HeapInfo::Nil
Dump the content of specific memory address.
Note: This method require you have permission of attaching another process. If not, a warning message will present.
94 95 96 97 98 |
# File 'lib/heapinfo/process.rb', line 94 def dump(*args) return Nil.instance unless load? dumper.dump(*args) end |
#dump_chunks(*args) ⇒ HeapInfo::Chunks, HeapInfo::Nil
Return the dump result as chunks. see Dumper#dump_chunks for more information.
105 106 107 108 109 |
# File 'lib/heapinfo/process.rb', line 105 def dump_chunks(*args) return Nil.instance unless load? dumper.dump_chunks(*args) end |
#find(pattern, from, length = :unlimited, rel: false) ⇒ Integer? Also known as: search
GDB-style command.
Search a specific value/string/regexp in memory.
209 210 211 212 213 |
# File 'lib/heapinfo/process.rb', line 209 def find(pattern, from, length = :unlimited, rel: false) return Nil.instance unless load? dumper.find(pattern, from, length, rel) end |
#find_all(pattern, from = 0, to = 1 << 64) ⇒ void Also known as: findall
This method returns an undefined value.
Find pattern in all segments with pretty output.
The search result will be output to $stdout.
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/heapinfo/process.rb', line 255 def find_all(pattern, from = 0, to = 1 << 64) return Nil.instance unless load? from = dumper.base_of(from) to = dumper.base_of(to) result = [] HeapInfo::Helper.parsed_maps(pid).each do |st, ed, perm, name| next if st >= to || ed < from || !perm.include?('r') start = [st, from].max len = [ed, to].min - start matches = dumper.scan(pattern, start, len).map { |v| v + start } result << [st, ed, perm, name, matches] if matches.any? end target = pattern.is_a?(Integer) ? Helper.hex(pattern) : pattern.inspect str = ["Searching #{Helper.color(target)}:"] str.concat(format_findall_result(result)) $stdout.puts(str) end |
#inspect ⇒ String
Make pry not so verbose.
333 334 335 |
# File 'lib/heapinfo/process.rb', line 333 def inspect format('#<HeapInfo::Process:0x%016x>', __id__) end |
#layouts(*args) ⇒ void
This method returns an undefined value.
Pretty dump of bins' layouts.
The request layouts will output to stdout.
288 289 290 291 292 293 294 295 296 |
# File 'lib/heapinfo/process.rb', line 288 def layouts(*args) return unless load? args << :all if args.empty? str = +'' str << libc.tcache.layouts if libc.tcache? && (%w[all tcache] & args.map(&:to_s)).any? str << libc.main_arena.layouts(*args) $stdout.puts(str) end |
#offset(addr, sym = nil) ⇒ void Also known as: off
This method returns an undefined value.
Show the offset in pretty way between the segment. Very useful in pwn when leak some address, see examples for more details.
129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/heapinfo/process.rb', line 129 def offset(addr, sym = nil) return unless load? segment = @info.to_segment(sym) if segment.nil? sym, segment = @info.segments .select { |_, seg| seg.base <= addr } .min_by { |_, seg| addr - seg } end return $stdout.puts("Invalid address #{Helper.color_hex(addr)}") if segment.nil? $stdout.puts(Helper.color_hex(addr - segment) + ' after ' + Helper.color(sym, sev: :sym)) end |
#reload! ⇒ HeapInfo::Process Also known as: reload
Reload a new process with same program name.
44 45 46 47 48 |
# File 'lib/heapinfo/process.rb', line 44 def reload! @pid = nil load! self end |
#s(address) ⇒ String
GDB-style command
Dump a string until reach the null-byte.
178 179 180 181 182 |
# File 'lib/heapinfo/process.rb', line 178 def s(address) return Nil.instance unless load? dumper.cstring(address) end |
#to_s ⇒ String
Show simple information of target process.
Contains program names, pid, and segments' info.
305 306 307 308 309 310 311 312 313 314 315 |
# File 'lib/heapinfo/process.rb', line 305 def to_s return 'Process not found' unless load? "Program: #{Helper.color(program.name)} PID: #{Helper.color(pid)}\n" + program.to_s + heap.to_s + stack.to_s + libc.to_s + ld.to_s + format("%-28s\tvalue: #{Helper.color(format('%#x', canary), sev: :sym)}", Helper.color('canary', sev: :sym)) end |
#x(count, address) ⇒ void
This method returns an undefined value.
GDB-style command
Show dump results like gdb's command x.
While will auto detect the current elf class to decide using gx or wx.
The dump results wrapper with color codes and nice typesetting will output to stdout.
164 165 166 167 168 |
# File 'lib/heapinfo/process.rb', line 164 def x(count, address) return unless load? dumper.x(count, address) end |