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-like command.
-
#find_all(pattern, segment = :all) ⇒ 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-like command.
-
#to_s ⇒ String
Show simple information of target process.
-
#x(count, address) ⇒ void
Gdb-like command.
Constructor Details
#initialize(prog, options = {}) ⇒ Process
Instantiate a HeapInfo::Process object.
23 24 25 26 27 |
# File 'lib/heapinfo/process.rb', line 23 def initialize(prog, = {}) @prog = prog @options = DEFAULT_LIB.merge load! end |
Instance Attribute Details
#pid ⇒ Integer? (readonly)
Returns The pid of process, nil if no such process found.
17 18 19 |
# File 'lib/heapinfo/process.rb', line 17 def pid @pid end |
Instance Method Details
#canary ⇒ Integer
Get the value of stack guard.
263 264 265 266 267 |
# File 'lib/heapinfo/process.rb', line 263 def canary return Nil.new unless load? addr = @info.auxv[:random] Helper.unpack(bits / 8, @dumper.dump(addr, bits / 8)) & 0xffffffffffffff00 end |
#debug ⇒ Object
56 57 58 59 |
# File 'lib/heapinfo/process.rb', line 56 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.
83 84 85 86 |
# File 'lib/heapinfo/process.rb', line 83 def dump(*args) return Nil.new 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.
93 94 95 96 |
# File 'lib/heapinfo/process.rb', line 93 def dump_chunks(*args) return Nil.new unless load? dumper.dump_chunks(*args) end |
#find(pattern, from, length = :unlimited, rel: false) ⇒ Integer? Also known as: search
Gdb-like command.
Search a specific value/string/regexp in memory.
192 193 194 195 |
# File 'lib/heapinfo/process.rb', line 192 def find(pattern, from, length = :unlimited, rel: false) return Nil.new unless load? dumper.find(pattern, from, length, rel) end |
#find_all(pattern, segment = :all) ⇒ void Also known as: findall
This method returns an undefined value.
Find pattern in all segments with pretty output.
206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/heapinfo/process.rb', line 206 def find_all(pattern, segment = :all) return Nil.new unless load? segments = segment == :all ? %i[elf heap libc ld stack] : Array(segment) result = findall_raw(pattern, segments).reject { |(_, _, ary)| ary.empty? } target = pattern.is_a?(Integer) ? Helper.hex(pattern) : pattern.inspect str = ["Searching #{Helper.color(target)}:\n"] str.concat(result.map do |(sym, base, ary)| "In #{Helper.color(sym, sev: :bin)} (#{Helper.color(Helper.hex(base))}):\n" + ary.map { |v| " #{Helper.color(sym, sev: :bin)}+#{Helper.color(Helper.hex(v))}\n" }.join end) $stdout.puts str end |
#inspect ⇒ String
Make pry not so verbose.
272 273 274 |
# File 'lib/heapinfo/process.rb', line 272 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.
231 232 233 234 235 236 237 |
# File 'lib/heapinfo/process.rb', line 231 def layouts(*args) return unless load? 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.
116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/heapinfo/process.rb', line 116 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.hex(addr)}" if segment.nil? $stdout.puts Helper.color(Helper.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.
34 35 36 37 38 |
# File 'lib/heapinfo/process.rb', line 34 def reload! @pid = nil load! self end |
#s(address) ⇒ String
Gdb-like command
Dump a string until reach the null-byte.
162 163 164 165 |
# File 'lib/heapinfo/process.rb', line 162 def s(address) return Nil.new unless load? dumper.cstring(address) end |
#to_s ⇒ String
Show simple information of target process.
Contains program names, pid, and segments’ info.
246 247 248 249 250 251 252 253 254 255 |
# File 'lib/heapinfo/process.rb', line 246 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-like 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.
149 150 151 152 |
# File 'lib/heapinfo/process.rb', line 149 def x(count, address) return unless load? dumper.x(count, address) end |