heapinfo 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d934f5ad5614d320a103119b23a48312b5034598
4
- data.tar.gz: 188ca4fe298b9859cbd546397d1176836a92e967
3
+ metadata.gz: 961ba248f261232617b7ed7ee649fd3fc21b72b9
4
+ data.tar.gz: 7bffd6cf6c33d2a6868ec59ba9d8b3509ab1512f
5
5
  SHA512:
6
- metadata.gz: 3051a5f8568e6a57d48ea2604193710a635c1fbd0c880b7a3e971b3608869e4c3d34e34a4c69886f422c0fe96e941c6be2c8d1f8d7a113759d244a6c739d1266
7
- data.tar.gz: 8a441e5ed3acebf552a047123d897fcaafd7b31117b26e07a5d2499d4e298da1baabd271517b84a065225e3fd47a1547da26da6796fb85763a1a2417adcf5f71
6
+ metadata.gz: 13d13edbcaab506b3b9044894f51bf10f5b9a32eb2e10d81a397f913a2488b947877d1d3747e1cb8d02f3f8304aa7c59e44f20ee3009bce20c7cd8c7f47ca658
7
+ data.tar.gz: 6680a5c6ab2a2483acbd0317d2dc3bf3871800d66136cd2d4263a23cff4b5367b5c10901e0788e21b3b4dc8af675fab1b270f1ac57d7d8c9bc1bea0162fb5b4a
data/README.md CHANGED
@@ -9,6 +9,10 @@
9
9
  ## HeapInfo
10
10
  As pwn lovers, while playing CTF with heap exploitation, we always need a debugger (e.g. gdb) for tracking memory layout. But we don't really need gdb if we want to see whether the heap layout same as our imagine or not. Hope this small tool helps us exploit easier ;).
11
11
 
12
+ #### Why
13
+ **HeapInfo** is very helpful when binary has somehow anti-debugger limitations, e.g being ptraced.
14
+ **HeapInfo** still works because it doesn't use ptrace.
15
+
12
16
  Implement with ruby because I love ruby :P. But might also implement with Python (if no others did) in the future.
13
17
 
14
18
  If you prefer [pwntools](https://github.com/Gallopsled/pwntools) for exploiting, you can still use **HeapInfo** in irb/pry as a small debugger.
@@ -30,12 +34,13 @@ $ gem install heapinfo
30
34
  * `dump` - Dump arbitrarily address memory.
31
35
  * `layouts` - Show the current bin layouts, very useful for heap exploitation.
32
36
  * `offset` - Show the offset between given address and segment. Very useful for calculating relative offset.
37
+ * `canary` - Fetch the value of stack guard!
33
38
  * `x` - Provide gdb-like commands.
34
39
  * `find` - Provide gdb-like commands.
35
40
  * More features and details can be found in [RDoc](http://www.rubydoc.info/github/david942j/heapinfo/master/)
36
41
 
37
42
  ### Under developing
38
- * `free` - Show what will happend when `free` an address.
43
+ * `free` - Show what will happend when calling `glibc#free` an address.
39
44
 
40
45
  ## Usage
41
46
 
@@ -45,7 +50,7 @@ $ gem install heapinfo
45
50
  require 'heapinfo'
46
51
  # ./victim is running
47
52
  h = heapinfo('victim')
48
- # or use h = heapinfo(20568) to prevent multi processes exist
53
+ # or use h = heapinfo(20568) to specific pid
49
54
 
50
55
  # will present simple info when loading:
51
56
  # Program: /home/heapinfo/victim PID: 20568
@@ -54,16 +59,17 @@ h = heapinfo('victim')
54
59
  # [stack] base @ 0x7fff2b244000
55
60
  # libc-2.19.so base @ 0x7f892a63a000
56
61
  # ld-2.19.so base @ 0x7f892bee6000
62
+ # canary value: 0x84b742f03d94c100
57
63
 
58
64
  # query segments' info
59
65
  "%#x" % h.libc.base
60
- # => "0x7f892a63a000"
66
+ #=> "0x7f892a63a000"
61
67
  h.libc.name
62
- # => "/lib/x86_64-linux-gnu/libc-2.19.so"
68
+ #=> "/lib/x86_64-linux-gnu/libc-2.19.so"
63
69
  "%#x" % h.elf.base
64
- # => "0x400000"
70
+ #=> "0x400000"
65
71
  "%#x" % h.heap.base
66
- # => "0x11cc000"
72
+ #=> "0x11cc000"
67
73
  ```
68
74
 
69
75
  NOTICE: While the process is not found, most methods will return `nil`. One way to prevent some error happend is to wrapper methods within `debug`, the block will be ignored while doing remote exploitation.
@@ -87,17 +93,17 @@ i.e. `/proc/sys/kernel/yama/ptrace_scope` set to 0 or run as root.
87
93
  ```ruby
88
94
  h.debug do
89
95
  p h.dump(:libc, 8)
90
- # => "\x7FELF\x02\x01\x01\x00"
96
+ #=> "\x7FELF\x02\x01\x01\x00"
91
97
  p h.dump(:heap, 16)
92
- # => "\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x00\x00\x00\x00"
98
+ #=> "\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x00\x00\x00\x00"
93
99
  p h.dump('heap+0x30', 16) # support offset!
94
- # => "\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00\x00\x00\x00\x00\x00\x00"
100
+ #=> "\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00\x00\x00\x00\x00\x00\x00"
95
101
  p h.dump('heap+0x30 * 3 + 0x8', 16) # and even complex formula!
96
- # => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
102
+ #=> "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
97
103
  p h.dump(:program, 8)
98
- # => "\x7FELF\x02\x01\x01\x00"
104
+ #=> "\x7FELF\x02\x01\x01\x00"
99
105
  p h.dump(0x400000, 8) # or simply give address
100
- # => "\x7FELF\x02\x01\x01\x00"
106
+ #=> "\x7FELF\x02\x01\x01\x00"
101
107
  end
102
108
 
103
109
  # invalid example:
@@ -126,6 +132,12 @@ h.offset(0x1839cd0)
126
132
  ```
127
133
  ![offset](https://github.com/david942j/heapinfo/blob/master/examples/offset.png?raw=true)
128
134
 
135
+ #### canary
136
+ ```ruby
137
+ h.canary.to_s(16)
138
+ #=> '84b742f03d94c100'
139
+ ```
140
+
129
141
  #### x - gdb-like command
130
142
  ```ruby
131
143
  h.x 8, :heap
@@ -139,11 +151,11 @@ Support search integer, string, and even regular expression.
139
151
 
140
152
  ```ruby
141
153
  h.find(0xdeadbeef, 'heap+0x10', 0x1000)
142
- # => 6299664 # 0x602010
154
+ #=> 6299664 # 0x602010
143
155
  h.find(/E.F/, 0x400000, 4)
144
- # => 4194305 # 0x400001
156
+ #=> 4194305 # 0x400001
145
157
  h.find(/E.F/, 0x400000, 3)
146
- # => nil
158
+ #=> nil
147
159
  h.offset(h.find('/bin/sh', :libc))
148
160
  # 0x18c177 after libc
149
161
  ```
@@ -153,3 +165,4 @@ h.offset(h.find('/bin/sh', :libc))
153
165
  * libc-2.19
154
166
  * libc-2.23
155
167
  * libc-2.24
168
+ * libc-2.25
@@ -20,8 +20,7 @@ module HeapInfo
20
20
  # The program name of victim. If a number is given, seem as pid (useful when multi-processes exist).
21
21
  # @param [Hash] options Give library's file name.
22
22
  # @option options [String, Regexp] :libc file name of glibc, default is +/bc[^a-z]*\.so/+.
23
- # @option options [String, Regexp] :ld file name of dynamic linker/loader, default is +/\/ld-.+\.so/+.
24
- # @return [HeapInfo::Process] The object for further usage
23
+ # @return [HeapInfo::Process] The object for further usage.
25
24
  # @example
26
25
  # h = heapinfo './victim'
27
26
  # # outputs:
@@ -31,18 +30,21 @@ module HeapInfo
31
30
  # # [stack] base @ 0x7fff2b244000
32
31
  # # libc-2.19.so base @ 0x7f892a63a000
33
32
  # # ld-2.19.so base @ 0x7f892bee6000
33
+ # # canary value: 0x84b742f03d94c100
34
34
  # p h.libc.name
35
- # # => "/lib/x86_64-linux-gnu/libc-2.19.so"
35
+ # #=> "/lib/x86_64-linux-gnu/libc-2.19.so"
36
36
  # p h.ld.name
37
- # # => "/lib/x86_64-linux-gnu/ld-2.19.so"
37
+ # #=> "/lib/x86_64-linux-gnu/ld-2.19.so"
38
+ # p h.heap.base.to_s(16)
39
+ # #=> '11cc000'
38
40
  #
39
41
  # @example
40
- # h = heapinfo(27605, libc: 'libc.so.6', ld: 'ld-linux-x86-64.so.2')
42
+ # h = heapinfo(27605, libc: 'libc.so.6')
41
43
  # # pid 27605 is run by custom loader
42
44
  # p h.libc.name
43
- # # => "/home/heapinfo/libc.so.6"
45
+ # #=> "/home/heapinfo/libc.so.6"
44
46
  # p h.ld.name
45
- # # => "/home/heapinfo/ld-linux-x86-64.so.2"
47
+ # #=> "/home/heapinfo/ld-linux-x86-64.so.2"
46
48
  def self.heapinfo(prog, options = {})
47
49
  h = HeapInfo::Process.new(prog, options)
48
50
  puts h
@@ -92,19 +92,19 @@ module HeapInfo
92
92
  # @return [Symbol] Bin type is simply determined according to +#size+
93
93
  # @example
94
94
  # [c.size, c.size_t]
95
- # # => [80, 8]
95
+ # #=> [80, 8]
96
96
  # c.bintype
97
- # # => :fast
97
+ # #=> :fast
98
98
  # @example
99
99
  # [c.size, c.size_t]
100
- # # => [80, 4]
100
+ # #=> [80, 4]
101
101
  # c.bintype
102
- # # => :small
102
+ # #=> :small
103
103
  # @example
104
104
  # c.size
105
- # # => 135168
105
+ # #=> 135168
106
106
  # c.bintype
107
- # # => :mmap
107
+ # #=> :mmap
108
108
  def bintype
109
109
  sz = size
110
110
  return :unknown if sz < @size_t * 4
@@ -21,7 +21,7 @@ module HeapInfo
21
21
  # @return [String, nil] Dump results. If error happend, +nil+ is returned.
22
22
  # @example
23
23
  # p dump(:elf, 4)
24
- # # => "\x7fELF"
24
+ # #=> "\x7fELF"
25
25
  def dump(*args)
26
26
  return need_permission unless dumpable?
27
27
  base, len = base_len_of(*args)
@@ -78,11 +78,11 @@ module HeapInfo
78
78
  # @return [Integer, nil] The first matched address, +nil+ is returned when no such pattern found.
79
79
  # @example
80
80
  # find(/E.F/, :elf)
81
- # # => 4194305
81
+ # #=> 4194305
82
82
  # find(0x4141414141414141, 'heap+0x10', 0x1000)
83
- # # => 6291472
83
+ # #=> 6291472
84
84
  # find('/bin/sh', :libc)
85
- # # => 140662379588827
85
+ # #=> 140662379588827
86
86
  def find(pattern, from, length)
87
87
  from = base_of(from)
88
88
  length = 1 << 40 if length.is_a? Symbol
@@ -1,11 +1,11 @@
1
- # Implment glibc's free-related functions
2
- # [Reference](https://code.woboq.org/userspace/glibc/malloc/malloc.c.html)
3
1
  module HeapInfo
4
2
  # Implement free-related functions.
5
3
  module Glibc
6
- # Implmentation of <tt>void __libc_free(void *mem)</tt>.
7
- # [glibc-2.23](https://github.com/david942j/heapinfo/blob/master/examples/libcdb/libc-2.23/malloc.c#L2934) or
8
- # [Online Source](https://code.woboq.org/userspace/glibc/malloc/malloc.c.html#__libc_free)
4
+ # Implmentation of +void __libc_free(void *mem)+.
5
+ #
6
+ # Reference:
7
+ # {https://github.com/david942j/heapinfo/blob/master/examples/libcdb/libc-2.23/malloc.c#L2934 glibc-2.23}
8
+ # and {https://code.woboq.org/userspace/glibc/malloc/malloc.c.html#__libc_free Online Source}
9
9
  # @param [Integer] mem Memory address to be free.
10
10
  def libc_free(mem)
11
11
  # TODO: free_hook
@@ -21,8 +21,6 @@ module HeapInfo
21
21
  private
22
22
 
23
23
  # Implmentation of <tt>void _int_free (mstate av, mchunkptr p, [int have_lock])</tt>.
24
- # [glibc-2.23](https://github.com/david942j/heapinfo/blob/master/examples/libcdb/libc-2.23/malloc.c#L2934) or
25
- # [Online Source](https://code.woboq.org/userspace/glibc/malloc/malloc.c.html#__libc_free)
26
24
  #
27
25
  # The original method in C is too long, split to multiple methods to match ruby convention.
28
26
  # @param [HeapInfo::Arena] av
@@ -5,7 +5,7 @@ module HeapInfo
5
5
  # Some helper functions.
6
6
  module Helper
7
7
  # Create read +/proc/[pid]/*+ methods.
8
- %w(exe maps).each do |method|
8
+ %w(exe maps auxv).each do |method|
9
9
  define_singleton_method("#{method}_of".to_sym) do |pid|
10
10
  begin
11
11
  IO.binread("/proc/#{pid}/#{method}")
@@ -65,12 +65,12 @@ module HeapInfo
65
65
  # Color codes for pretty print.
66
66
  COLOR_CODE = {
67
67
  esc_m: "\e[0m",
68
- normal_s: "\e[31m", # red
69
- integer: "\e[1m\e[34m", # light blue
68
+ normal_s: "\e[38;5;209m", # red
69
+ integer: "\e[38;5;153m", # light blue
70
70
  fatal: "\e[38;5;197m", # dark red
71
71
  bin: "\e[38;5;120m", # light green
72
- klass: "\e[38;5;155m", # pry like
73
- sym: "\e[33m", # pry like
72
+ klass: "\e[38;5;155m",
73
+ sym: "\e[38;5;230m"
74
74
  }.freeze
75
75
  # Wrapper color codes for pretty inspect.
76
76
  # @param [String] s Contents for wrapper.
@@ -110,7 +110,7 @@ module HeapInfo
110
110
  # @param [Integer] num Non-negative integer.
111
111
  # @return [String] number in hex format.
112
112
  # @example
113
- # HeapInfo::Helper.hex(1000) # => '0x3e8'
113
+ # HeapInfo::Helper.hex(1000) #=> '0x3e8'
114
114
  def hex(num)
115
115
  return format('0x%x', num) if num >= 0
116
116
  format('-0x%x', -num)
@@ -122,7 +122,7 @@ module HeapInfo
122
122
  # @example
123
123
  # # suppose obj is an instance of HeapInfo::Chunk
124
124
  # Helper.class_name(obj)
125
- # # => 'Chunk'
125
+ # #=> 'Chunk'
126
126
  def class_name(obj)
127
127
  obj.class.name.split('::').last || obj.class.name
128
128
  end
@@ -132,11 +132,11 @@ module HeapInfo
132
132
  # @return [Boolean] If +str+ can be converted into integer.
133
133
  # @example
134
134
  # Helper.integer? '1234'
135
- # # => true
135
+ # #=> true
136
136
  # Helper.integer? '0x1234'
137
- # # => true
137
+ # #=> true
138
138
  # Helper.integer? '0xheapoverflow'
139
- # # => false
139
+ # #=> false
140
140
  def integer?(str)
141
141
  true if Integer(str)
142
142
  rescue ArgumentError, TypeError
@@ -13,7 +13,7 @@ module HeapInfo
13
13
  # @example
14
14
  # # h.dump would return Nil when process not found
15
15
  # p h.dump(:heap)[8, 8].unpack('Q*')
16
- # # => nil
16
+ # #=> nil
17
17
  def method_missing(method_sym, *args, &block)
18
18
  return nil.send(method_sym, *args, &block) if nil.respond_to?(method_sym)
19
19
  self || super
@@ -3,22 +3,21 @@ module HeapInfo
3
3
  # Main class of heapinfo.
4
4
  class Process
5
5
  # The default options of libraries,
6
- # use for matching glibc and ld segments in +/proc/[pid]/maps+.
6
+ # use for matching glibc segments in +/proc/[pid]/maps+.
7
7
  DEFAULT_LIB = {
8
- libc: /bc[^a-z]*\.so/,
9
- ld: %r{/ld-.+\.so}
8
+ libc: /bc[^a-z]*\.so/
10
9
  }.freeze
11
- # @return [Integer, nil] return the pid of process, +nil+ if no such process found
10
+ # @return [Integer, nil] The pid of process, +nil+ if no such process found.
12
11
  attr_reader :pid
13
12
 
14
13
  # Instantiate a {HeapInfo::Process} object.
15
- # @param [String, Integer] prog Process name or pid, see {HeapInfo::heapinfo} for more information
16
- # @param [Hash{Symbol => Regexp, String}] options libraries' filename, see {HeapInfo::heapinfo} for more information
14
+ # @param [String, Integer] prog Process name or pid, see {HeapInfo::heapinfo} for more information.
15
+ # @param [Hash{Symbol => Regexp, String}] options
16
+ # Libraries' filename, see {HeapInfo::heapinfo} for more information.
17
17
  def initialize(prog, options = {})
18
18
  @prog = prog
19
19
  @options = DEFAULT_LIB.merge options
20
20
  load!
21
- return unless load?
22
21
  end
23
22
 
24
23
  # Reload a new process with same program name
@@ -157,13 +156,13 @@ module HeapInfo
157
156
  # @return [Integer, nil] The first matched address, +nil+ is returned when no such pattern found.
158
157
  # @example
159
158
  # h.find(0xdeadbeef, 'heap+0x10', 0x1000)
160
- # # => 6299664 # 0x602010
159
+ # #=> 6299664 # 0x602010
161
160
  # h.find(/E.F/, 0x400000, 4)
162
- # # => 4194305 # 0x400001
161
+ # #=> 4194305 # 0x400001
163
162
  # h.find(/E.F/, 0x400000, 3)
164
- # # => nil
163
+ # #=> nil
165
164
  # sh_offset = h.find('/bin/sh', :libc) - h.libc.base
166
- # # => 1559771 # 0x17ccdb
165
+ # #=> 1559771 # 0x17ccdb
167
166
  def find(pattern, from, length = :unlimited)
168
167
  return Nil.new unless load?
169
168
  length = 1 << 40 if length.is_a? Symbol
@@ -193,12 +192,32 @@ module HeapInfo
193
192
  # puts h
194
193
  def to_s
195
194
  return 'Process not found' unless load?
196
- "Program: #{Helper.color program.name} PID: #{Helper.color pid}\n" +
195
+ "Program: #{Helper.color(program.name)} PID: #{Helper.color(pid)}\n" +
197
196
  program.to_s +
198
197
  heap.to_s +
199
198
  stack.to_s +
200
199
  libc.to_s +
201
- ld.to_s
200
+ ld.to_s +
201
+ format("%-28s\tvalue: #{Helper.color(format('%#x', canary), sev: :sym)}", Helper.color('canary', sev: :sym))
202
+ end
203
+
204
+ # Get the value of stack guard.
205
+ #
206
+ # @return [Integer]
207
+ # @example
208
+ # h.canary
209
+ # #=> 11342701118118205184 # 0x9d695e921adc9700
210
+ def canary
211
+ return Nil.new unless load?
212
+ addr = @info.auxv[:random]
213
+ Helper.unpack(bits / 8, @dumper.dump(addr, bits / 8)) & 0xffffffffffffff00
214
+ end
215
+
216
+ # Make pry not so verbose.
217
+ #
218
+ # @return [nil]
219
+ def inspect
220
+ nil
202
221
  end
203
222
 
204
223
  private
@@ -1,12 +1,13 @@
1
1
  # encoding: ascii-8bit
2
2
  module HeapInfo
3
- # for {Process} to record current info(s)
4
- # {Process} has a +process_info+ object iff the process found (pid not +nil+).
3
+ # For {Process} to record basic process information.
4
+ #
5
+ # {Process} has a +process_info+ object iff the process exists (pid not +nil+).
5
6
  # Mainly records segments' base.
6
7
  class ProcessInfo
7
8
  # Methods to be transparent to +process+.
8
9
  # e.g. +process.libc+ alias to +process.info.libc+.
9
- EXPORT = %i(libc ld heap program elf stack bits).freeze
10
+ EXPORT = %i(libc ld heap program elf stack bits auxv).freeze
10
11
 
11
12
  # @return [Integer] 32 or 64.
12
13
  attr_reader :bits
@@ -18,6 +19,11 @@ module HeapInfo
18
19
  attr_reader :libc
19
20
  # @return [HeapInfo::Segment]
20
21
  attr_reader :ld
22
+ # @return [Hash{Symbol => Integer}] The parsed auxv hash.
23
+ # @example
24
+ # auxv
25
+ # #=> {:ld_base => 4152033280, :random => 4294374299}
26
+ attr_reader :auxv
21
27
  alias elf program
22
28
 
23
29
  # Instantiate a {ProcessInfo} object.
@@ -29,10 +35,12 @@ module HeapInfo
29
35
  maps = load_maps
30
36
  @bits = bits_of(Helper.exe_of(@pid))
31
37
  @program = Segment.find(maps, File.readlink("/proc/#{@pid}/exe"))
32
- @stack = Segment.find(maps, '[stack]')
33
38
  # well.. stack is a strange case because it will grow in runtime..
34
39
  # should i detect stack base growing..?
35
- @ld = Segment.find(maps, match_maps(maps, options[:ld]))
40
+ @stack = Segment.find(maps, '[stack]')
41
+ @auxv = parse_auxv(Helper.auxv_of(@pid))
42
+ ld_seg = maps.find { |m| m[0] == @auxv[:ld_base] } # nil if static-linked elf
43
+ @ld = ld_seg.nil? ? Nil.new : Segment.new(@auxv[:ld_base], ld_seg.last)
36
44
  @libc = Libc.find(maps, match_maps(maps, options[:libc]), @bits, @ld.name, ->(*args) { process.dump(*args) })
37
45
  end
38
46
 
@@ -59,6 +67,22 @@ module HeapInfo
59
67
  Helper.parse_maps(Helper.maps_of(@pid))
60
68
  end
61
69
 
70
+ def parse_auxv(str)
71
+ auxv = {}
72
+ sio = StringIO.new(str)
73
+ fetch = ->() { Helper.unpack(@bits / 8, sio.read(@bits / 8)) }
74
+ loop do
75
+ type = fetch.call
76
+ val = fetch.call
77
+ case type
78
+ when 7 then auxv[:ld_base] = val # AT_BASE
79
+ when 25 then auxv[:random] = val # AT_RANDOM
80
+ end
81
+ break if type.zero?
82
+ end
83
+ auxv
84
+ end
85
+
62
86
  def bits_of(elf)
63
87
  elf[4] == "\x01" ? 32 : 64
64
88
  end
@@ -19,7 +19,7 @@ module HeapInfo
19
19
  format("%-28s\tbase @ #{Helper.color(format('%#x', base))}\n", Helper.color(name.split('/')[-1]))
20
20
  end
21
21
 
22
- # Helper for create a {HeapInfo::Segment}.
22
+ # Helper for creating a {HeapInfo::Segment}.
23
23
  #
24
24
  # Search the specific <tt>pattern</tt> in <tt>maps</tt> and return a {HeapInfo::Segment} object.
25
25
  #
@@ -27,7 +27,7 @@ module HeapInfo
27
27
  # @param [Regexp, String] pattern
28
28
  # The segment name want to match in maps. If +String+ is given, the pattern is matched as a substring.
29
29
  # @return [HeapInfo::Segment, nil]
30
- # The request {HeapInfo::Segment} object. If the pattern is not matched, <tt>nil</tt> will be returned.
30
+ # The request {HeapInfo::Segment} object. If the pattern is not matched, instance of {Nil} will be returned.
31
31
  def self.find(maps, pattern)
32
32
  return Nil.new if pattern.nil?
33
33
  needs = maps.select { |m| pattern.is_a?(Regexp) ? m[3] =~ pattern : m[3].include?(pattern) }
@@ -1,4 +1,4 @@
1
1
  module HeapInfo
2
2
  # Current gem version.
3
- VERSION = '1.0.1'.freeze
3
+ VERSION = '1.0.2'.freeze
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heapinfo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - david942j
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-28 00:00:00.000000000 Z
11
+ date: 2017-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dentaku
@@ -94,7 +94,11 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.6'
97
- description: create an interactive memory info interface while pwn / exploiting
97
+ description: |
98
+ Create an interactive memory info interface while pwn / exploiting.
99
+ Useful for rubiers writing exploit scripts.
100
+ HeapInfo can be used even when target is being ptraced,
101
+ this tool helps a lot when one needs to debug an ptraced process.
98
102
  email:
99
103
  - david942j@gmail.com
100
104
  executables: []