module HeapInfo::Helper::ClassMethods

Define class methods here.

Constants

COLOR_CODE

Color codes for pretty print.

Public Instance Methods

class_name(obj) click to toggle source

Retrieve pure class name(without module) of an object. @param [Object] obj Any instance. @return [String] Class name of obj. @example

# suppose obj is an instance of HeapInfo::Chunk
Helper.class_name(obj)
#=> 'Chunk'
# File lib/heapinfo/helper.rb, line 128
def class_name(obj)
  obj.class.name.split('::').last || obj.class.name
end
color(s, sev: nil) click to toggle source

Wrapper color codes for pretty inspect. @param [String] s Contents for wrapper. @param [Symbol?] sev

Specific which kind of color want to use, valid symbols are defined in +#COLOR_CODE+.
If this argument is not present, will detect according to the content of +s+.

@return [String] wrapper with color codes.

# File lib/heapinfo/helper.rb, line 83
def color(s, sev: nil)
  s = s.to_s
  return s if @disable_color
  cc = COLOR_CODE
  color = if cc.key?(sev) then cc[sev]
          elsif integer?(s) then cc[:integer] # integers
          else cc[:normal_s] # normal string
          end
  "#{color}#{s.sub(cc[:esc_m], color)}#{cc[:esc_m]}"
end
evaluate(formula, store: {}) click to toggle source

Safe-eval using dentaku. @param [String] formula Formula to be eval. @param [Hash{Symbol => Integer}] store Predefined values. @return [Integer] Evaluate result.

# File lib/heapinfo/helper.rb, line 152
def evaluate(formula, store: {})
  calc = Dentaku::Calculator.new
  formula = formula.delete(':')
  calc.store(store).evaluate(formula)
end
hex(num) click to toggle source

Convert number in hex format.

@param [Integer] num Non-negative integer. @return [String] number in hex format. @example

HeapInfo::Helper.hex(1000) #=> '0x3e8'
# File lib/heapinfo/helper.rb, line 116
def hex(num)
  return format('0x%x', num) if num >= 0
  format('-0x%x', -num)
end
integer?(str) click to toggle source

For checking a string is actually an integer. @param [String] str String to be checked. @return [Boolean] If str can be converted into integer. @example

Helper.integer? '1234'
#=> true
Helper.integer? '0x1234'
#=> true
Helper.integer? '0xheapoverflow'
#=> false
# File lib/heapinfo/helper.rb, line 142
def integer?(str)
  true if Integer(str)
rescue ArgumentError, TypeError
  false
end
parse_maps(content) click to toggle source

Parse the contents of /proc/[pid]/maps.

@param [String] content The file content of /proc/[pid]/maps. @return [Array] In form of [[start, end, permission, name], ...]. See examples. @example

HeapInfo::Helper.parse_maps(<<EOS
  00400000-0040b000 r-xp 00000000 ca:01 271708                             /bin/cat
  00bc4000-00be5000 rw-p 00000000 00:00 0                                  [heap]
  7f2788315000-7f2788316000 r--p 00022000 ca:01 402319                     /lib/x86_64-linux-gnu/ld-2.19.so
  EOS
)
# [[0x400000, 0x40b000, 'r-xp', '/bin/cat'],
# [0xbc4000, 0xbe5000, 'rw-p', '[heap]'],
# [0x7f2788315000, 0x7f2788316000, 'r--p', '/lib/x86_64-linux-gnu/ld-2.19.so']]
# File lib/heapinfo/helper.rb, line 50
def parse_maps(content)
  lines = content.split("\n")
  lines.map do |line|
    s = line.scan(%r{^([0-9a-f]+)-([0-9a-f]+)\s([rwxp-]{4})[^/|\[]*([/|\[].+)$})[0]
    next nil if s.nil?
    s[0], s[1] = s[0, 2].map { |h| h.to_i(16) }
    s
  end.compact
end
pidof(prog) click to toggle source

Get the process id from program name.

When multiple processes exist, the one with lastest start time would be returned. @param [String] prog The request process name. @return [Integer] Process id.

# File lib/heapinfo/helper.rb, line 27
def pidof(prog)
  info = %x(ps -o pid=,lstart= --pid `pidof #{Shellwords.escape(prog)}` 2>/dev/null).lines.map do |l|
    pid, time = l.split(' ', 2)
    [Time.parse(time), pid.to_i]
  end
  return nil if info.empty? # process not exists yet
  info.max_by(&:first).last
end
tempfile(name) click to toggle source

Get temp filename. @param [String] name Filename. @return [String] Temp filename.

# File lib/heapinfo/helper.rb, line 161
def tempfile(name)
  Dir::Tmpname.create(name, HeapInfo::TMP_DIR) {}
end
toggle_color(on: false) click to toggle source

enable / disable the color function. @param [Boolean] on Enable or not. @return [void]

# File lib/heapinfo/helper.rb, line 63
def toggle_color(on: false)
  @disable_color = !on
end
unpack(size_t, data) click to toggle source

Unpack strings to integer.

Like the p32 and p64 in pwntools.

@param [Integer] size_t Either 4 or 8. @param [String] data String to be unpack. @return [Integer] Unpacked result. @example

HeapInfo::Helper.unpack(4, "\x12\x34\x56\x78")
# 0x78563412
HeapInfo::Helper.unpack(8, "\x12\x34\x56\x78\xfe\xeb\x90\x90")
# 0x9090ebfe78563412
# File lib/heapinfo/helper.rb, line 106
def unpack(size_t, data)
  data.unpack(size_t == 4 ? 'L*' : 'Q*')[0]
end