ragweed 0.2.0.pre3-java → 0.2.1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/lib/ragweed/debugger32.rb +1 -1
- data/lib/ragweed/debuggerosx.rb +29 -0
- data/lib/ragweed/debuggertux.rb +91 -69
- data/lib/ragweed/wrap32/debugging.rb +35 -0
- data/lib/ragweed/wrap32/wrap32.rb +2 -2
- data/lib/ragweed/wraptux/constants.rb +3 -0
- data/ragweed.gemspec +8 -8
- metadata +8 -18
- data/lib/.DS_Store +0 -0
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.2.
|
|
1
|
+
0.2.1
|
data/lib/ragweed/debugger32.rb
CHANGED
|
@@ -312,7 +312,7 @@ class Ragweed::Debugger32
|
|
|
312
312
|
def wait
|
|
313
313
|
self.attach() if not @attached
|
|
314
314
|
|
|
315
|
-
event = ev = Ragweed::Wrap32::wait_for_debug_event
|
|
315
|
+
@event = ev = Ragweed::Wrap32::wait_for_debug_event
|
|
316
316
|
return if not ev
|
|
317
317
|
case ev.code
|
|
318
318
|
when Ragweed::Wrap32::DebugCodes::CREATE_PROCESS
|
data/lib/ragweed/debuggerosx.rb
CHANGED
|
@@ -415,6 +415,35 @@ class Ragweed::Debuggerosx
|
|
|
415
415
|
end
|
|
416
416
|
end
|
|
417
417
|
|
|
418
|
+
# XXX watch this space for an object to hold this information
|
|
419
|
+
# Return a range via mapping name
|
|
420
|
+
def get_mapping_by_name name, exact = true
|
|
421
|
+
ret = []
|
|
422
|
+
IO.popen("vmmap -interleaved #{@pid}") do |pipe|
|
|
423
|
+
pipe.each_line do |line|
|
|
424
|
+
next if pipe.lineno < 5
|
|
425
|
+
break if line == "==== Legend\n"
|
|
426
|
+
rtype, saddr, eaddr, sz, perms, sm, purpose =
|
|
427
|
+
line.scan(/^([[:graph:]]+(?:\s[[:graph:]]+)?)\s+([[:xdigit:]]+)-([[:xdigit:]]+)\s+\[\s+([[:digit:]]+[A-Z])\s*\]\s+([-rwx\/]+)\s+SM=(COW|PRV|NUL|ALI|SHM|ZER|S\/A)\s+(.*)$/).
|
|
428
|
+
first
|
|
429
|
+
if exact && (rtype == name || purpose == name)
|
|
430
|
+
ret << [saddr, eaddr].map{|x| x.to_i(16)}
|
|
431
|
+
elsif rtype.match(name) || purpose.match(name)
|
|
432
|
+
ret << [saddr, eaddr].map{|x| x.to_i(16)}
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
ret
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
def get_stack_ranges
|
|
440
|
+
get_mapping_by_name "Stack", false
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
def get_heap_ranges
|
|
444
|
+
get_mapping_by_name "MALLOC", false
|
|
445
|
+
end
|
|
446
|
+
|
|
418
447
|
private
|
|
419
448
|
|
|
420
449
|
# sets instance automagic options to sane(ish) defaults when not given
|
data/lib/ragweed/debuggertux.rb
CHANGED
|
@@ -83,18 +83,15 @@ class Ragweed::Debuggertux
|
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
def self.find_by_regex(rx)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
f = File.read("/proc/#{x}/cmdline")
|
|
93
|
-
if f =~ rx and x.to_i != Process.pid.to_i
|
|
94
|
-
return x
|
|
86
|
+
Dir.glob("/proc/*/cmdline").each do |x|
|
|
87
|
+
x.gsub(/^\/proc\/(\d+)\/cmdline$/) do |ln|
|
|
88
|
+
f = File.read(ln)
|
|
89
|
+
if f =~ rx and $1.to_i != ::Process.pid.to_i
|
|
90
|
+
return f
|
|
91
|
+
end
|
|
95
92
|
end
|
|
96
93
|
end
|
|
97
|
-
|
|
94
|
+
nil
|
|
98
95
|
end
|
|
99
96
|
|
|
100
97
|
def install_bps
|
|
@@ -134,78 +131,101 @@ class Ragweed::Debuggertux
|
|
|
134
131
|
## key = Start address of region
|
|
135
132
|
## value = Size of the region
|
|
136
133
|
def mapped
|
|
137
|
-
|
|
134
|
+
@mapped_regions.clear if @mapped_regions
|
|
138
135
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
e =
|
|
142
|
-
|
|
143
|
-
|
|
136
|
+
File.open("/proc/#{pid}/maps") do |f|
|
|
137
|
+
f.each_line do |l|
|
|
138
|
+
e = l.split(' ',2).first
|
|
139
|
+
s,e = e.split('-').map{|x| x.to_i(16)}
|
|
140
|
+
sz = e - s
|
|
141
|
+
@mapped_regions.store(s, sz)
|
|
144
142
|
end
|
|
143
|
+
end
|
|
144
|
+
@mapped_regions
|
|
145
145
|
end
|
|
146
146
|
|
|
147
|
-
|
|
147
|
+
# Return a name for a range if possible. greedy match
|
|
148
|
+
# returns the first found
|
|
148
149
|
def get_mapping_name(val)
|
|
149
|
-
File.
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
150
|
+
File.open("/proc/#{pid}/maps") do |f|
|
|
151
|
+
f.each_line do |l|
|
|
152
|
+
range, perms, offset, dev, inode, pathname = l.chomp.split(" ")
|
|
153
|
+
base, max = range.split('-').map{|x| x.to_i(16)}
|
|
154
|
+
if base <= val && val <= max
|
|
155
|
+
return pathname
|
|
154
156
|
end
|
|
157
|
+
end
|
|
155
158
|
end
|
|
156
159
|
nil
|
|
157
160
|
end
|
|
161
|
+
alias mapping_name get_mapping_name
|
|
158
162
|
|
|
159
163
|
## Return a range via mapping name
|
|
160
|
-
def get_mapping_by_name(name)
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
164
|
+
def get_mapping_by_name(name, exact = true)
|
|
165
|
+
ret = []
|
|
166
|
+
File.open("/proc/#{pid}/maps") do |f|
|
|
167
|
+
f.each_line do |l|
|
|
168
|
+
range, perms, offset, dev, inode, pathname = l.chomp.split(" ",6)
|
|
169
|
+
base, max = range.split('-').map{|x| x.to_i(16)}
|
|
170
|
+
if pathname
|
|
171
|
+
if exact && pathname == name
|
|
172
|
+
ret << range.split('-').map{|x| x.to_i(16)}
|
|
173
|
+
elsif pathname.match(name)
|
|
174
|
+
ret << range.split('-').map{|x| x.to_i(16)}
|
|
175
|
+
end
|
|
167
176
|
end
|
|
177
|
+
end
|
|
168
178
|
end
|
|
169
|
-
|
|
179
|
+
ret
|
|
170
180
|
end
|
|
181
|
+
alias mapping_by_name get_mapping_by_name
|
|
171
182
|
|
|
172
183
|
## Helper method for retrieving stack range
|
|
173
184
|
def get_stack_range
|
|
174
|
-
|
|
185
|
+
get_mapping_by_name('[stack]')
|
|
175
186
|
end
|
|
187
|
+
alias stack_range get_stack_range
|
|
176
188
|
|
|
177
189
|
## Helper method for retrieving heap range
|
|
178
190
|
def get_heap_range
|
|
179
|
-
|
|
191
|
+
get_mapping_by_name('[heap]')
|
|
180
192
|
end
|
|
193
|
+
alias heap_range get_heap_range
|
|
181
194
|
|
|
182
195
|
## Parse procfs and create a hash containing
|
|
183
196
|
## a listing of each mapped shared object
|
|
184
197
|
def self.shared_libraries(p)
|
|
198
|
+
raise "pid is 0" if p.to_i == 0
|
|
185
199
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
@shared_objects = Hash.new
|
|
192
|
-
end
|
|
200
|
+
if @shared_objects
|
|
201
|
+
@shared_objects.clear
|
|
202
|
+
else
|
|
203
|
+
@shared_objects = Hash.new
|
|
204
|
+
end
|
|
193
205
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
206
|
+
File.open("/proc/#{p}/maps") do |f|
|
|
207
|
+
f.each_line do |l|
|
|
208
|
+
if l =~ /[a-zA-Z0-9].so/ && l =~ /xp /
|
|
209
|
+
lib = l.split(' ', 6)
|
|
210
|
+
sa = l.split('-', 0)
|
|
198
211
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
212
|
+
if lib[5] =~ /vdso/
|
|
213
|
+
next
|
|
214
|
+
end
|
|
202
215
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
end
|
|
216
|
+
lib = lib[5].strip
|
|
217
|
+
lib.gsub!(/[\s\n]+/, "")
|
|
218
|
+
@shared_objects.store(sa[0], lib)
|
|
207
219
|
end
|
|
208
|
-
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
@shared_objects
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# instance method for above
|
|
226
|
+
# returns a hash of the mapped shared libraries
|
|
227
|
+
def shared_libraries
|
|
228
|
+
self.class.shared_libraries(@pid)
|
|
209
229
|
end
|
|
210
230
|
|
|
211
231
|
## Search a specific page for a value
|
|
@@ -227,15 +247,17 @@ class Ragweed::Debuggertux
|
|
|
227
247
|
## Search the heap for a value
|
|
228
248
|
def search_heap(val)
|
|
229
249
|
loc = Array.new
|
|
230
|
-
File.
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
250
|
+
File.open("/proc/#{pid}/maps") do |f|
|
|
251
|
+
f.each_line do |l|
|
|
252
|
+
if l =~ /\[heap\]/
|
|
253
|
+
s,e = l.split('-')
|
|
254
|
+
e = e.split(' ').first
|
|
255
|
+
s = s.to_i(16)
|
|
256
|
+
e = e.to_i(16)
|
|
257
|
+
sz = e - s
|
|
258
|
+
max = s + sz
|
|
259
|
+
loc = search_page(s, max, val)
|
|
260
|
+
end
|
|
239
261
|
end
|
|
240
262
|
end
|
|
241
263
|
loc
|
|
@@ -266,7 +288,7 @@ class Ragweed::Debuggertux
|
|
|
266
288
|
end
|
|
267
289
|
|
|
268
290
|
def single_step
|
|
269
|
-
|
|
291
|
+
on_single_step
|
|
270
292
|
ret = Ragweed::Wraptux::ptrace(Ragweed::Wraptux::Ptrace::STEP, @pid, 1, 0)
|
|
271
293
|
end
|
|
272
294
|
|
|
@@ -392,14 +414,14 @@ class Ragweed::Debuggertux
|
|
|
392
414
|
end
|
|
393
415
|
|
|
394
416
|
def self.threads(pid)
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
a
|
|
417
|
+
a = []
|
|
418
|
+
begin
|
|
419
|
+
a = Dir.entries("/proc/#{pid}/task/")
|
|
420
|
+
a.delete_if {|x| x == '.' || x == '..'}
|
|
421
|
+
rescue
|
|
422
|
+
puts "No such PID: #{pid}"
|
|
423
|
+
end
|
|
424
|
+
a
|
|
403
425
|
end
|
|
404
426
|
|
|
405
427
|
def get_registers
|
|
@@ -14,7 +14,14 @@ module Ragweed::Wrap32
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
module PagePermissions
|
|
17
|
+
PAGE_NOACCESS = 0x1
|
|
18
|
+
PAGE_READONLY = 0x2
|
|
19
|
+
PAGE_READWRITE = 0x4
|
|
20
|
+
PAGE_WRITECOPY = 0x8
|
|
21
|
+
PAGE_EXECUTE = 0x10
|
|
22
|
+
PAGE_EXECUTE_READ = 0x20
|
|
17
23
|
PAGE_EXECUTE_READWRITE = 0x40
|
|
24
|
+
PAGE_EXECUTE_WRITECOPY = 0x80
|
|
18
25
|
end
|
|
19
26
|
|
|
20
27
|
module ExceptionCodes
|
|
@@ -51,6 +58,34 @@ module Ragweed::Wrap32
|
|
|
51
58
|
end
|
|
52
59
|
end
|
|
53
60
|
|
|
61
|
+
class Ragweed::Wrap32::StartupInfo < FFI::Struct
|
|
62
|
+
layout :cb, :ulong,
|
|
63
|
+
:reserved, :pointer,
|
|
64
|
+
:desktop, :pointer,
|
|
65
|
+
:title, :pointer,
|
|
66
|
+
:x, :ulong,
|
|
67
|
+
:y, :ulong,
|
|
68
|
+
:xsize, :ulong,
|
|
69
|
+
:ysize, :ulong,
|
|
70
|
+
:xcountchars, :ulong,
|
|
71
|
+
:ycountchars, :ulong,
|
|
72
|
+
:fillattr, :ulong,
|
|
73
|
+
:flags, :ulong,
|
|
74
|
+
:show_window, :short,
|
|
75
|
+
:breserved, :uint16,
|
|
76
|
+
:preserved, :uint8,
|
|
77
|
+
:std_input, :ulong,
|
|
78
|
+
:std_output, :ulong,
|
|
79
|
+
:std_error, :ulong
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
class Ragweed::Wrap32::ProcessInfo < FFI::Struct
|
|
83
|
+
layout :process_handle, :pointer,
|
|
84
|
+
:thread_handle, :pointer,
|
|
85
|
+
:pid, :ulong,
|
|
86
|
+
:thread_id, :ulong
|
|
87
|
+
end
|
|
88
|
+
|
|
54
89
|
class Ragweed::Wrap32::RipInfo < FFI::Struct
|
|
55
90
|
include Ragweed::FFIStructInclude
|
|
56
91
|
layout :error, :ulong,
|
|
@@ -117,8 +117,8 @@ module Ragweed::Wrap32
|
|
|
117
117
|
attach_function 'DeviceIoControl', [ :long, :long, :pointer, :long, :pointer, :long, :pointer, :pointer ], :long
|
|
118
118
|
attach_function 'GetOverlappedResult', [ :long, :pointer, :pointer, :long ], :long
|
|
119
119
|
attach_function 'WaitForMultipleObjects', [ :long, :pointer, :long, :long ], :long
|
|
120
|
-
attach_function 'CreateProcessA', [ :pointer, :pointer, :pointer, :pointer, :
|
|
121
|
-
attach_function 'CreateProcessW', [ :pointer, :pointer, :pointer, :pointer, :
|
|
120
|
+
attach_function 'CreateProcessA', [ :pointer, :pointer, :pointer, :pointer, :bool, :long, :pointer, :pointer, :pointer, :pointer ], :long
|
|
121
|
+
attach_function 'CreateProcessW', [ :pointer, :pointer, :pointer, :pointer, :bool, :long, :pointer, :pointer, :pointer, :pointer ], :long
|
|
122
122
|
|
|
123
123
|
ffi_lib 'ntdll'
|
|
124
124
|
ffi_convention :stdcall
|
data/ragweed.gemspec
CHANGED
|
@@ -5,12 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = %q{ragweed}
|
|
8
|
-
s.version = "0.2.
|
|
9
|
-
s.platform = %q{java}
|
|
8
|
+
s.version = "0.2.1"
|
|
10
9
|
|
|
11
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
12
11
|
s.authors = ["tduehr", "struct", "tqbf"]
|
|
13
|
-
s.date = %q{2011-
|
|
12
|
+
s.date = %q{2011-04-13}
|
|
14
13
|
s.description = %q{General debugging tool written in Ruby for OSX/Win32/Linux}
|
|
15
14
|
s.email = %q{td@matasano.com}
|
|
16
15
|
s.extra_rdoc_files = [
|
|
@@ -28,7 +27,6 @@ Gem::Specification.new do |s|
|
|
|
28
27
|
"examples/hook_notepad.rb",
|
|
29
28
|
"examples/snicker.rb",
|
|
30
29
|
"examples/tux-example.rb",
|
|
31
|
-
"lib/.DS_Store",
|
|
32
30
|
"lib/ragweed.rb",
|
|
33
31
|
"lib/ragweed/arena.rb",
|
|
34
32
|
"lib/ragweed/blocks.rb",
|
|
@@ -76,7 +74,7 @@ Gem::Specification.new do |s|
|
|
|
76
74
|
s.homepage = %q{http://github.com/tduehr/ragweed}
|
|
77
75
|
s.rdoc_options = ["--inline-source", "--line-numbers", "--main", "README.rdoc"]
|
|
78
76
|
s.require_paths = ["lib"]
|
|
79
|
-
s.rubygems_version = %q{1.
|
|
77
|
+
s.rubygems_version = %q{1.5.2}
|
|
80
78
|
s.summary = %q{Scriptable debugger}
|
|
81
79
|
s.test_files = [
|
|
82
80
|
"examples/hittracertux.rb",
|
|
@@ -90,13 +88,15 @@ Gem::Specification.new do |s|
|
|
|
90
88
|
]
|
|
91
89
|
|
|
92
90
|
if s.respond_to? :specification_version then
|
|
93
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
94
91
|
s.specification_version = 3
|
|
95
92
|
|
|
96
|
-
if Gem::Version.new(Gem::
|
|
93
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
94
|
+
s.add_runtime_dependency(%q<ffi>, ["~> 1.0"])
|
|
97
95
|
else
|
|
96
|
+
s.add_dependency(%q<ffi>, ["~> 1.0"])
|
|
98
97
|
end
|
|
99
98
|
else
|
|
99
|
+
s.add_dependency(%q<ffi>, ["~> 1.0"])
|
|
100
100
|
end
|
|
101
101
|
end
|
|
102
102
|
|
metadata
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ragweed
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
prerelease:
|
|
5
|
-
|
|
6
|
-
- 0
|
|
7
|
-
- 2
|
|
8
|
-
- 0
|
|
9
|
-
- pre3
|
|
10
|
-
version: 0.2.0.pre3
|
|
4
|
+
prerelease:
|
|
5
|
+
version: 0.2.1
|
|
11
6
|
platform: java
|
|
12
7
|
authors:
|
|
13
8
|
- tduehr
|
|
@@ -17,7 +12,7 @@ autorequire:
|
|
|
17
12
|
bindir: bin
|
|
18
13
|
cert_chain: []
|
|
19
14
|
|
|
20
|
-
date: 2011-
|
|
15
|
+
date: 2011-04-13 00:00:00 -05:00
|
|
21
16
|
default_executable:
|
|
22
17
|
dependencies: []
|
|
23
18
|
|
|
@@ -41,7 +36,6 @@ files:
|
|
|
41
36
|
- examples/hook_notepad.rb
|
|
42
37
|
- examples/snicker.rb
|
|
43
38
|
- examples/tux-example.rb
|
|
44
|
-
- lib/.DS_Store
|
|
45
39
|
- lib/ragweed.rb
|
|
46
40
|
- lib/ragweed/arena.rb
|
|
47
41
|
- lib/ragweed/blocks.rb
|
|
@@ -98,25 +92,21 @@ rdoc_options:
|
|
|
98
92
|
require_paths:
|
|
99
93
|
- lib
|
|
100
94
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
95
|
+
none: false
|
|
101
96
|
requirements:
|
|
102
97
|
- - ">="
|
|
103
98
|
- !ruby/object:Gem::Version
|
|
104
|
-
segments:
|
|
105
|
-
- 0
|
|
106
99
|
version: "0"
|
|
107
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
|
+
none: false
|
|
108
102
|
requirements:
|
|
109
|
-
- - "
|
|
103
|
+
- - ">="
|
|
110
104
|
- !ruby/object:Gem::Version
|
|
111
|
-
|
|
112
|
-
- 1
|
|
113
|
-
- 3
|
|
114
|
-
- 1
|
|
115
|
-
version: 1.3.1
|
|
105
|
+
version: "0"
|
|
116
106
|
requirements: []
|
|
117
107
|
|
|
118
108
|
rubyforge_project:
|
|
119
|
-
rubygems_version: 1.
|
|
109
|
+
rubygems_version: 1.5.1
|
|
120
110
|
signing_key:
|
|
121
111
|
specification_version: 3
|
|
122
112
|
summary: Scriptable debugger
|
data/lib/.DS_Store
DELETED
|
Binary file
|