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 +4 -4
- data/README.md +28 -15
- data/lib/heapinfo.rb +9 -7
- data/lib/heapinfo/chunk.rb +6 -6
- data/lib/heapinfo/dumper.rb +4 -4
- data/lib/heapinfo/glibc/free.rb +5 -7
- data/lib/heapinfo/helper.rb +10 -10
- data/lib/heapinfo/nil.rb +1 -1
- data/lib/heapinfo/process.rb +32 -13
- data/lib/heapinfo/process_info.rb +29 -5
- data/lib/heapinfo/segment.rb +2 -2
- data/lib/heapinfo/version.rb +1 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 961ba248f261232617b7ed7ee649fd3fc21b72b9
|
4
|
+
data.tar.gz: 7bffd6cf6c33d2a6868ec59ba9d8b3509ab1512f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
-
|
66
|
+
#=> "0x7f892a63a000"
|
61
67
|
h.libc.name
|
62
|
-
|
68
|
+
#=> "/lib/x86_64-linux-gnu/libc-2.19.so"
|
63
69
|
"%#x" % h.elf.base
|
64
|
-
|
70
|
+
#=> "0x400000"
|
65
71
|
"%#x" % h.heap.base
|
66
|
-
|
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
|
-
|
96
|
+
#=> "\x7FELF\x02\x01\x01\x00"
|
91
97
|
p h.dump(:heap, 16)
|
92
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
104
|
+
#=> "\x7FELF\x02\x01\x01\x00"
|
99
105
|
p h.dump(0x400000, 8) # or simply give address
|
100
|
-
|
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
|
-
|
154
|
+
#=> 6299664 # 0x602010
|
143
155
|
h.find(/E.F/, 0x400000, 4)
|
144
|
-
|
156
|
+
#=> 4194305 # 0x400001
|
145
157
|
h.find(/E.F/, 0x400000, 3)
|
146
|
-
|
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
|
data/lib/heapinfo.rb
CHANGED
@@ -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
|
-
# @
|
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
|
-
#
|
35
|
+
# #=> "/lib/x86_64-linux-gnu/libc-2.19.so"
|
36
36
|
# p h.ld.name
|
37
|
-
#
|
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'
|
42
|
+
# h = heapinfo(27605, libc: 'libc.so.6')
|
41
43
|
# # pid 27605 is run by custom loader
|
42
44
|
# p h.libc.name
|
43
|
-
#
|
45
|
+
# #=> "/home/heapinfo/libc.so.6"
|
44
46
|
# p h.ld.name
|
45
|
-
#
|
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
|
data/lib/heapinfo/chunk.rb
CHANGED
@@ -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
|
-
#
|
95
|
+
# #=> [80, 8]
|
96
96
|
# c.bintype
|
97
|
-
#
|
97
|
+
# #=> :fast
|
98
98
|
# @example
|
99
99
|
# [c.size, c.size_t]
|
100
|
-
#
|
100
|
+
# #=> [80, 4]
|
101
101
|
# c.bintype
|
102
|
-
#
|
102
|
+
# #=> :small
|
103
103
|
# @example
|
104
104
|
# c.size
|
105
|
-
#
|
105
|
+
# #=> 135168
|
106
106
|
# c.bintype
|
107
|
-
#
|
107
|
+
# #=> :mmap
|
108
108
|
def bintype
|
109
109
|
sz = size
|
110
110
|
return :unknown if sz < @size_t * 4
|
data/lib/heapinfo/dumper.rb
CHANGED
@@ -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
|
-
#
|
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
|
-
#
|
81
|
+
# #=> 4194305
|
82
82
|
# find(0x4141414141414141, 'heap+0x10', 0x1000)
|
83
|
-
#
|
83
|
+
# #=> 6291472
|
84
84
|
# find('/bin/sh', :libc)
|
85
|
-
#
|
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
|
data/lib/heapinfo/glibc/free.rb
CHANGED
@@ -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
|
7
|
-
#
|
8
|
-
#
|
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
|
data/lib/heapinfo/helper.rb
CHANGED
@@ -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[
|
69
|
-
integer: "\e[
|
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",
|
73
|
-
sym: "\e[
|
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)
|
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
|
-
#
|
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
|
-
#
|
135
|
+
# #=> true
|
136
136
|
# Helper.integer? '0x1234'
|
137
|
-
#
|
137
|
+
# #=> true
|
138
138
|
# Helper.integer? '0xheapoverflow'
|
139
|
-
#
|
139
|
+
# #=> false
|
140
140
|
def integer?(str)
|
141
141
|
true if Integer(str)
|
142
142
|
rescue ArgumentError, TypeError
|
data/lib/heapinfo/nil.rb
CHANGED
@@ -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
|
-
#
|
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
|
data/lib/heapinfo/process.rb
CHANGED
@@ -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
|
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]
|
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
|
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
|
-
#
|
159
|
+
# #=> 6299664 # 0x602010
|
161
160
|
# h.find(/E.F/, 0x400000, 4)
|
162
|
-
#
|
161
|
+
# #=> 4194305 # 0x400001
|
163
162
|
# h.find(/E.F/, 0x400000, 3)
|
164
|
-
#
|
163
|
+
# #=> nil
|
165
164
|
# sh_offset = h.find('/bin/sh', :libc) - h.libc.base
|
166
|
-
#
|
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
|
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
|
-
#
|
4
|
-
#
|
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
|
-
@
|
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
|
data/lib/heapinfo/segment.rb
CHANGED
@@ -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
|
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,
|
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) }
|
data/lib/heapinfo/version.rb
CHANGED
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.
|
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-
|
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:
|
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: []
|