ragweed 0.2.3-java → 0.2.4-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/README.rdoc +9 -9
- data/VERSION +1 -1
- data/examples/hittracerx.rb +36 -15
- data/lib/ragweed/debugger32.rb +71 -53
- data/lib/ragweed/debuggerosx.rb +48 -25
- data/lib/ragweed/debuggertux.rb +71 -57
- data/lib/ragweed/rasm/isa.rb +1 -1
- data/lib/ragweed/rasm.rb +0 -5
- data/lib/ragweed/utils.rb +7 -3
- data/lib/ragweed/wrap32/hooks.rb +9 -9
- data/lib/ragweed/wrap32/process.rb +24 -28
- data/lib/ragweed/wrap32/wrap32.rb +7 -3
- data/lib/ragweed/wrap32.rb +0 -3
- data/lib/ragweed/wraposx/constants.rb +11 -5
- data/lib/ragweed/wraposx/kernelerrorx.rb +2 -3
- data/lib/ragweed/wraposx/region_info.rb +4 -4
- data/lib/ragweed/wraposx/thread_context.rb +8 -0
- data/lib/ragweed/wraposx/thread_info.rb +11 -3
- data/lib/ragweed/wraposx/wraposx.rb +3 -2
- data/lib/ragweed/wraptux/constants.rb +81 -80
- data/lib/ragweed/wraptux/process.rb +4 -4
- data/lib/ragweed/wraptux/threads.rb +3 -2
- data/lib/ragweed/wraptux.rb +0 -4
- data/ragweed.gemspec +2 -2
- metadata +2 -2
data/lib/ragweed/debuggertux.rb
CHANGED
@@ -2,20 +2,20 @@ require ::File.join(::File.dirname(__FILE__),'wraptux')
|
|
2
2
|
|
3
3
|
module Ragweed; end
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
5
|
+
# Debugger class for Linux
|
6
|
+
# You can use this class in 2 ways:
|
7
|
+
#
|
8
|
+
# (1) You can create instances of Debuggertux and use them to set and handle
|
9
|
+
# breakpoints.
|
10
|
+
#
|
11
|
+
# (2) If you want to do more advanced event handling, you can subclass from
|
12
|
+
# debugger and define your own on_whatever events. If you handle an event
|
13
|
+
# that Debuggertux already handles, call "super", too.
|
14
14
|
class Ragweed::Debuggertux
|
15
15
|
attr_reader :pid, :status, :exited, :signal
|
16
16
|
attr_accessor :breakpoints, :mapped_regions, :process, :use_ptrace_for_search
|
17
17
|
|
18
|
-
|
18
|
+
# Class to handle installing/uninstalling breakpoints
|
19
19
|
class Breakpoint
|
20
20
|
|
21
21
|
INT3 = 0xCC
|
@@ -23,10 +23,10 @@ class Ragweed::Debuggertux
|
|
23
23
|
attr_accessor :orig, :bppid, :function, :installed
|
24
24
|
attr_reader :addr
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
# ip: insertion point
|
27
|
+
# callable: lambda to be called when breakpoint is hit
|
28
|
+
# p: process ID
|
29
|
+
# name: name of breakpoint
|
30
30
|
def initialize(ip, callable, p, name = "")
|
31
31
|
@bppid = p
|
32
32
|
@function = name
|
@@ -59,9 +59,9 @@ class Ragweed::Debuggertux
|
|
59
59
|
def call(*args); @callable.call(*args) if @callable != nil; end
|
60
60
|
end
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
# init object
|
63
|
+
# p: pid of process to be debugged
|
64
|
+
# opts: default options for automatically doing things (attach and install)
|
65
65
|
def initialize(pid, opts) ## Debuggertux Class
|
66
66
|
if p.to_i.kind_of? Fixnum
|
67
67
|
@pid = pid.to_i
|
@@ -109,13 +109,13 @@ class Ragweed::Debuggertux
|
|
109
109
|
@installed = false
|
110
110
|
end
|
111
111
|
|
112
|
-
|
112
|
+
# This has not been fully tested yet
|
113
113
|
def set_options(option)
|
114
114
|
r = Ragweed::Wraptux::ptrace(Ragweed::Wraptux::Ptrace::SETOPTIONS, @pid, 0, option)
|
115
115
|
end
|
116
116
|
|
117
|
-
|
118
|
-
|
117
|
+
# Attach calls install_bps so dont forget to call breakpoint_set
|
118
|
+
# BEFORE attach or explicitly call install_bps
|
119
119
|
def attach(opts=@opts)
|
120
120
|
r = Ragweed::Wraptux::ptrace(Ragweed::Wraptux::Ptrace::ATTACH, @pid, 0, 0)
|
121
121
|
if r != -1
|
@@ -127,10 +127,10 @@ class Ragweed::Debuggertux
|
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
130
|
+
# This method returns a hash of mapped regions
|
131
|
+
# The hash is also stored as @mapped_regions
|
132
|
+
# key = Start address of region
|
133
|
+
# value = Size of the region
|
134
134
|
def mapped
|
135
135
|
@mapped_regions.clear if @mapped_regions
|
136
136
|
File.open("/proc/#{pid}/maps") do |f|
|
@@ -160,7 +160,7 @@ class Ragweed::Debuggertux
|
|
160
160
|
end
|
161
161
|
alias mapping_name get_mapping_name
|
162
162
|
|
163
|
-
|
163
|
+
# Return a range via mapping name
|
164
164
|
def get_mapping_by_name(name, exact = true)
|
165
165
|
ret = []
|
166
166
|
File.open("/proc/#{pid}/maps") do |f|
|
@@ -180,20 +180,20 @@ class Ragweed::Debuggertux
|
|
180
180
|
end
|
181
181
|
alias mapping_by_name get_mapping_by_name
|
182
182
|
|
183
|
-
|
183
|
+
# Helper method for retrieving stack range
|
184
184
|
def get_stack_range
|
185
185
|
get_mapping_by_name('[stack]')
|
186
186
|
end
|
187
187
|
alias stack_range get_stack_range
|
188
188
|
|
189
|
-
|
189
|
+
# Helper method for retrieving heap range
|
190
190
|
def get_heap_range
|
191
191
|
get_mapping_by_name('[heap]')
|
192
192
|
end
|
193
193
|
alias heap_range get_heap_range
|
194
194
|
|
195
|
-
|
196
|
-
|
195
|
+
# Parse procfs and create a hash containing
|
196
|
+
# a listing of each mapped shared object
|
197
197
|
def self.shared_libraries(p)
|
198
198
|
raise "pid is 0" if p.to_i == 0
|
199
199
|
|
@@ -226,8 +226,8 @@ class Ragweed::Debuggertux
|
|
226
226
|
self.class.shared_libraries(@pid)
|
227
227
|
end
|
228
228
|
|
229
|
-
|
230
|
-
|
229
|
+
# Search a specific page for a value
|
230
|
+
# Should be used by most search methods
|
231
231
|
def search_page(base, max, val, &block)
|
232
232
|
loc = []
|
233
233
|
if self.use_ptrace_for_search == true
|
@@ -292,17 +292,17 @@ class Ragweed::Debuggertux
|
|
292
292
|
loc
|
293
293
|
end
|
294
294
|
|
295
|
-
|
295
|
+
# Search the heap for a value, returns an array of matches
|
296
296
|
def search_heap(val, &block)
|
297
297
|
search_mem_by_name('heap', &block)
|
298
298
|
end
|
299
299
|
|
300
|
-
|
300
|
+
# Search the stack for a value, returns an array of matches
|
301
301
|
def search_stack(val, &block)
|
302
302
|
search_mem_by_name('stack', &block)
|
303
303
|
end
|
304
304
|
|
305
|
-
|
305
|
+
# Search all mapped regions for a value
|
306
306
|
def search_process(val, &block)
|
307
307
|
loc = []
|
308
308
|
self.mapped
|
@@ -329,10 +329,10 @@ class Ragweed::Debuggertux
|
|
329
329
|
ret = Ragweed::Wraptux::ptrace(Ragweed::Wraptux::Ptrace::STEP, @pid, 1, 0)
|
330
330
|
end
|
331
331
|
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
332
|
+
# Adds a breakpoint to be installed
|
333
|
+
# ip: Insertion point
|
334
|
+
# name: name of breakpoint
|
335
|
+
# callable: object to .call at breakpoint
|
336
336
|
def breakpoint_set(ip, name="", callable=nil, &block)
|
337
337
|
if not callable and block_given?
|
338
338
|
callable = block
|
@@ -342,15 +342,15 @@ class Ragweed::Debuggertux
|
|
342
342
|
@breakpoints[ip] = bp
|
343
343
|
end
|
344
344
|
|
345
|
-
|
345
|
+
# Remove a breakpoint by ip
|
346
346
|
def breakpoint_clear(ip)
|
347
347
|
bp = @breakpoints[ip]
|
348
348
|
return nil if bp.nil?
|
349
349
|
bp.uninstall
|
350
350
|
end
|
351
351
|
|
352
|
-
|
353
|
-
|
352
|
+
# loop for wait()
|
353
|
+
# times: the number of wait calls to make
|
354
354
|
def loop(times=nil)
|
355
355
|
if times.kind_of? Numeric
|
356
356
|
times.times do
|
@@ -369,11 +369,11 @@ class Ragweed::Debuggertux
|
|
369
369
|
((status) & 0x7f)
|
370
370
|
end
|
371
371
|
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
372
|
+
# This wait must be smart, it has to wait for a signal
|
373
|
+
# when SIGTRAP is received we need to see if one of our
|
374
|
+
# breakpoints has fired. If it has then execute the block
|
375
|
+
# originally stored with it. If its a different signal,
|
376
|
+
# then process it accordingly and move on
|
377
377
|
def wait(opts = 0)
|
378
378
|
r, status = Ragweed::Wraptux::waitpid(@pid, opts)
|
379
379
|
wstatus = wtermsig(status)
|
@@ -471,53 +471,67 @@ class Ragweed::Debuggertux
|
|
471
471
|
Ragweed::Wraptux::ptrace(Ragweed::Wraptux::Ptrace::SETREGS, @pid, 0, regs.to_ptr.address)
|
472
472
|
end
|
473
473
|
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
474
|
+
# Here we need to do something about the bp
|
475
|
+
# we just hit. We have a block to execute.
|
476
|
+
# Remember if you implement this on your own
|
477
|
+
# make sure to call super, and also realize
|
478
|
+
# EIP won't look correct until this runs
|
479
479
|
def on_breakpoint
|
480
480
|
r = get_registers
|
481
481
|
eip = r.eip
|
482
482
|
eip -= 1
|
483
483
|
|
484
|
-
|
484
|
+
# Call the block associated with the breakpoint
|
485
485
|
@breakpoints[eip].call(r, self)
|
486
486
|
|
487
|
-
|
487
|
+
# The block may have called breakpoint_clear
|
488
488
|
del = true if !@breakpoints[eip].installed?
|
489
489
|
|
490
|
-
|
490
|
+
# Uninstall and single step the bp
|
491
491
|
@breakpoints[eip].uninstall
|
492
492
|
r.eip = eip
|
493
493
|
set_registers(r)
|
494
494
|
single_step
|
495
495
|
|
496
|
-
|
497
|
-
|
496
|
+
# ptrace peektext returns -1 upon reinstallation of bp without calling
|
497
|
+
# waitpid() if that occurs the breakpoint cannot be reinstalled
|
498
498
|
Ragweed::Wraptux::waitpid(@pid, 0)
|
499
499
|
|
500
500
|
if del == true
|
501
|
-
|
501
|
+
# The breakpoint block may have called breakpoint_clear
|
502
502
|
@breakpoints.delete(eip)
|
503
503
|
else
|
504
504
|
@breakpoints[eip].install
|
505
505
|
end
|
506
506
|
end
|
507
507
|
|
508
|
+
# @abstract
|
508
509
|
def on_attach() end
|
510
|
+
# @abstract
|
509
511
|
def on_single_step() end
|
512
|
+
# @abstract
|
510
513
|
def on_continue() end
|
514
|
+
# @abstract
|
511
515
|
def on_exit() end
|
516
|
+
# @abstract
|
512
517
|
def on_signal() end
|
518
|
+
# @abstract
|
513
519
|
def on_sigint() end
|
520
|
+
# @abstract
|
514
521
|
def on_segv() end
|
522
|
+
# @abstract
|
515
523
|
def on_illegal_instruction() end
|
524
|
+
# @abstract
|
516
525
|
def on_sigtrap() end
|
526
|
+
# @abstract
|
517
527
|
def on_fork_child(pid) end
|
528
|
+
# @abstract
|
518
529
|
def on_sigchild() end
|
530
|
+
# @abstract
|
519
531
|
def on_sigterm() end
|
532
|
+
# @abstract
|
520
533
|
def on_sigstop() end
|
534
|
+
# @abstract
|
521
535
|
def on_iot_trap() end
|
522
536
|
|
523
537
|
def print_registers
|
data/lib/ragweed/rasm/isa.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
module Ragweed; end
|
1
2
|
## ------------------------------------------------------------------------
|
2
3
|
|
3
4
|
# Rasm: a half-assed X86 assembler.
|
@@ -9,7 +10,6 @@
|
|
9
10
|
# to inject trampoline functions and detours into remote processes. This
|
10
11
|
# is Ruby code; you'd never use it where performance matters. It's not
|
11
12
|
# enough to write a decent compiler, but it's enough to fuck up programs.
|
12
|
-
module Ragweed; end
|
13
13
|
module Ragweed::Rasm
|
14
14
|
class NotImp < RuntimeError; end
|
15
15
|
class Insuff < RuntimeError; end
|
data/lib/ragweed/rasm.rb
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
# Dir[File.expand_path("#{File.dirname(__FILE__)}/rasm/*.rb")].each do |file|
|
2
|
-
# require file
|
3
|
-
# end
|
4
1
|
module Ragweed; end
|
5
2
|
module Ragweed::Rasm
|
6
3
|
|
@@ -49,8 +46,6 @@ module Ragweed::Rasm
|
|
49
46
|
::File.join(::File.dirname(fname), dir, '**', '*.rb'))
|
50
47
|
|
51
48
|
Dir.glob(search_me).sort.each {|rb| require rb}
|
52
|
-
# require File.dirname(File.basename(__FILE__)) + "/#{x}"
|
53
|
-
|
54
49
|
end
|
55
50
|
end # module Ragweed::Rasm
|
56
51
|
|
data/lib/ragweed/utils.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'iconv'
|
2
2
|
|
3
|
-
#
|
3
|
+
# @deprecated - unused this will be removed at some point.
|
4
4
|
class Range
|
5
5
|
module RangeExtensions
|
6
6
|
def each_backwards
|
@@ -47,11 +47,11 @@ class Object
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
|
50
|
+
# This is from Topher Cyll's Stupd IRB tricks
|
51
51
|
def mymethods
|
52
52
|
(self.methods - self.class.superclass.methods).sort
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
def callable?; respond_to? :call; end
|
56
56
|
def number?; kind_of? Numeric; end
|
57
57
|
|
@@ -69,9 +69,13 @@ class Object
|
|
69
69
|
end
|
70
70
|
|
71
71
|
class String
|
72
|
+
# to little endian 32bit integer
|
72
73
|
def to_l32; unpack("L").first; end
|
74
|
+
# to big endian 32bit integer
|
73
75
|
def to_b32; unpack("N").first; end
|
76
|
+
# to little endian 16bit short
|
74
77
|
def to_l16; unpack("v").first; end
|
78
|
+
# to big endian 16bit short
|
75
79
|
def to_b16; unpack("n").first; end
|
76
80
|
def to_u8; self[0]; end
|
77
81
|
def shift_l32; shift(4).to_l32; end
|
data/lib/ragweed/wrap32/hooks.rb
CHANGED
@@ -6,7 +6,7 @@ class Ragweed::Debugger32
|
|
6
6
|
def hook(ip, nargs, callable=nil, &block)
|
7
7
|
|
8
8
|
callable ||= block || lambda do |ev,ctx,dir,args|
|
9
|
-
#puts args.map{|a| "%08x" % a}.join(',')
|
9
|
+
# puts args.map{|a| "%08x" % a}.join(',')
|
10
10
|
end
|
11
11
|
|
12
12
|
breakpoint_set(ip) do |ev,ctx|
|
@@ -17,13 +17,13 @@ class Ragweed::Debugger32
|
|
17
17
|
args = (1..nargs).map {|i| process.read32(ctx.esp + 4*i)}
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
# set exit bpoint
|
21
|
+
# We cant always set a leave bp due to
|
22
|
+
# calling conventions but we can avoid
|
23
|
+
# a crash by setting a breakpoint on
|
24
|
+
# the wrong address. So we attempt to
|
25
|
+
# get an idea of where the instruction
|
26
|
+
# is mapped.
|
27
27
|
eip = ctx.eip
|
28
28
|
if esp != 0 #and esp > (eip & 0xf0000000)
|
29
29
|
breakpoint_set(esp) do |ev,ctx|
|
@@ -32,7 +32,7 @@ class Ragweed::Debugger32
|
|
32
32
|
end.install
|
33
33
|
end
|
34
34
|
|
35
|
-
|
35
|
+
# Call the block sent to hook()
|
36
36
|
callable.call(ev, ctx, :enter, args)
|
37
37
|
end
|
38
38
|
end
|
@@ -35,25 +35,22 @@ class Ragweed::Process
|
|
35
35
|
def is_hex(s)
|
36
36
|
s = s.strip
|
37
37
|
|
38
|
-
|
38
|
+
# Strip leading 0s and 0x prefix
|
39
39
|
while s[0..1] == '0x' or s[0..1] == '00'
|
40
|
-
|
40
|
+
s = s[2..-1]
|
41
41
|
end
|
42
42
|
|
43
43
|
o = s
|
44
44
|
|
45
|
-
|
46
|
-
return true
|
47
|
-
end
|
48
|
-
return false
|
45
|
+
s.hex.to_s(16) == o
|
49
46
|
end
|
50
47
|
|
51
|
-
|
52
|
-
|
53
|
-
|
48
|
+
# This only gets called for breakpoints in modules
|
49
|
+
# that have just been loaded and detected by a LOAD_DLL
|
50
|
+
# event. It is called from on_load_dll() -> deferred_install()
|
54
51
|
def get_deferred_proc_remote(name, handle, base_of_dll)
|
55
52
|
if !name.kind_of?String
|
56
|
-
|
53
|
+
return name
|
57
54
|
end
|
58
55
|
|
59
56
|
mod, meth = name.split "!"
|
@@ -64,7 +61,7 @@ class Ragweed::Process
|
|
64
61
|
|
65
62
|
modh = handle
|
66
63
|
|
67
|
-
|
64
|
+
# Location is an offset
|
68
65
|
if is_hex(meth)
|
69
66
|
baseaddr = 0
|
70
67
|
modules.each do |m|
|
@@ -75,15 +72,15 @@ class Ragweed::Process
|
|
75
72
|
|
76
73
|
ret = base_of_dll + meth.hex
|
77
74
|
else
|
78
|
-
|
79
|
-
|
75
|
+
# Location is a symbolic name
|
76
|
+
# Win32 should have successfully loaded the DLL
|
80
77
|
ret = remote_call "kernel32!GetProcAddress", modh, meth
|
81
78
|
end
|
82
79
|
ret
|
83
80
|
end
|
84
81
|
|
85
|
-
|
86
|
-
|
82
|
+
# This only gets called for breakpoints
|
83
|
+
# in modules that are already loaded
|
87
84
|
def get_proc_remote(name)
|
88
85
|
if !name.kind_of?String
|
89
86
|
return name
|
@@ -95,11 +92,10 @@ class Ragweed::Process
|
|
95
92
|
raise "can not set this breakpoint: #{name}"
|
96
93
|
end
|
97
94
|
|
98
|
-
# modh = remote_call "kernel32!GetModuleHandleW", mod.to_utf16
|
99
95
|
modh = remote_call "kernel32!GetModuleHandleA", mod
|
100
96
|
raise "no such module #{ mod }" if not modh
|
101
97
|
|
102
|
-
|
98
|
+
# Location is an offset
|
103
99
|
if is_hex(meth)
|
104
100
|
baseaddr = 0
|
105
101
|
modules.each do |m|
|
@@ -109,26 +105,26 @@ class Ragweed::Process
|
|
109
105
|
end
|
110
106
|
end
|
111
107
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
108
|
+
# Somehow the module does not appear to be
|
109
|
+
# loaded. This should have been caught by
|
110
|
+
# Process::is_breakpoint_deferred either way
|
111
|
+
# Process::initialize should catch this return
|
116
112
|
if baseaddr == 0 or baseaddr == -1
|
117
113
|
return name
|
118
114
|
end
|
119
115
|
|
120
116
|
ret = baseaddr + meth.hex
|
121
117
|
else
|
122
|
-
|
118
|
+
# Location is a symbolic name
|
123
119
|
ret = remote_call "kernel32!GetProcAddress", modh, meth
|
124
120
|
end
|
125
121
|
ret
|
126
122
|
end
|
127
123
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
124
|
+
# Check if breakpoint location is deferred
|
125
|
+
# This method expects a string 'module!function'
|
126
|
+
# true is the module is not yet loaded
|
127
|
+
# false is the module is loaded
|
132
128
|
def is_breakpoint_deferred(ip)
|
133
129
|
if !ip.kind_of? String
|
134
130
|
return false
|
@@ -149,8 +145,8 @@ class Ragweed::Process
|
|
149
145
|
return true
|
150
146
|
end
|
151
147
|
|
152
|
-
|
153
|
-
|
148
|
+
# Look up a process by name or regex, returning an array of all
|
149
|
+
# matching processes, as objects.
|
154
150
|
def self.by_name(n)
|
155
151
|
n = Regexp.new(n) if not n.kind_of? Regexp
|
156
152
|
p = []
|
@@ -129,8 +129,8 @@ module Ragweed::Wrap32
|
|
129
129
|
attach_function 'malloc', [ :long ], :long
|
130
130
|
attach_function 'memcpy', [ :pointer, :pointer, :long ], :long
|
131
131
|
|
132
|
-
|
133
|
-
|
132
|
+
# XXX This shouldnt be in psapi in win7, need to clean this up
|
133
|
+
# XXX Also the unicode version should be supported, this is NOT complete
|
134
134
|
ffi_lib 'psapi'
|
135
135
|
ffi_convention :stdcall
|
136
136
|
attach_function 'GetMappedFileNameA', [ :long, :long, :pointer, :long ], :long
|
@@ -201,7 +201,7 @@ module Ragweed::Wrap32
|
|
201
201
|
|
202
202
|
# Read from a remote process given an address and length, returning a string.
|
203
203
|
def read_process_memory(h, ptr, len)
|
204
|
-
#
|
204
|
+
# val = FFI::MemoryPointer.from_string("\x00" * len)
|
205
205
|
val = "\x00" * len
|
206
206
|
r = Win.ReadProcessMemory(h, ptr.to_i, val, len, NULL)
|
207
207
|
raise WinX.new(:read_process_memory) if r == 0
|
@@ -215,6 +215,7 @@ module Ragweed::Wrap32
|
|
215
215
|
return val
|
216
216
|
end
|
217
217
|
|
218
|
+
# @deprecated - will be replaced with a proper object
|
218
219
|
def str2memory_basic_info(mbi)
|
219
220
|
s = OpenStruct.new
|
220
221
|
s.BaseAddress,
|
@@ -304,6 +305,7 @@ module Ragweed::Wrap32
|
|
304
305
|
raise WinX.new(:wait_for_single_object) if r == -1
|
305
306
|
end
|
306
307
|
|
308
|
+
# @deprecated - will be replaced with a proper object
|
307
309
|
def str2process_info(str)
|
308
310
|
ret = OpenStruct.new
|
309
311
|
ret.dwSize,
|
@@ -337,6 +339,7 @@ module Ragweed::Wrap32
|
|
337
339
|
end
|
338
340
|
end
|
339
341
|
|
342
|
+
# @deprecated - will be replaced with a proper object
|
340
343
|
def str2module_info(str)
|
341
344
|
ret = OpenStruct.new
|
342
345
|
ret.dwSize,
|
@@ -392,6 +395,7 @@ module Ragweed::Wrap32
|
|
392
395
|
nil
|
393
396
|
end
|
394
397
|
|
398
|
+
# @deprecated - will be replaced with a proper object
|
395
399
|
def str2thread_info(str)
|
396
400
|
ret = OpenStruct.new
|
397
401
|
ret.dwSize,
|
data/lib/ragweed/wrap32.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module Ragweed; end
|
2
2
|
module Ragweed::Wraposx;end
|
3
|
+
|
4
|
+
# PTRACE request constants
|
3
5
|
module Ragweed::Wraposx::Ptrace
|
4
6
|
TRACE_ME = 0 # child declares it's being traced
|
5
7
|
#(READ|WRITE)_[IDU] are not valid in OSX but defined in ptrace.h
|
@@ -22,10 +24,11 @@ module Ragweed::Wraposx::Ptrace
|
|
22
24
|
FIRSTMACH = 32 # for machine-specific requests
|
23
25
|
end
|
24
26
|
|
27
|
+
# the Ruby module Signal also has this information.
|
28
|
+
# in reality, that is a better source since it's based on the signals
|
29
|
+
# available at the time ruby was compiled.
|
30
|
+
# @deprecated - Just use ::Signal
|
25
31
|
module Ragweed::Wraposx::Signal
|
26
|
-
# the Ruby module Signal also has this information.
|
27
|
-
# in reality, that is a better source since it's based on the signals
|
28
|
-
# available at the time ruby was compiled.
|
29
32
|
SIGHUP = 1 # hangup
|
30
33
|
SIGINT = 2 # interrupt
|
31
34
|
SIGQUIT = 3 # quit
|
@@ -68,6 +71,7 @@ module Ragweed::Wraposx::Signal
|
|
68
71
|
SIGUSR2 = 31 # user defined signal 2
|
69
72
|
end
|
70
73
|
|
74
|
+
# options for wait()
|
71
75
|
module Ragweed::Wraposx::Wait
|
72
76
|
NOHANG = 0x01 # [XSI] no hang in wait/no child to reap
|
73
77
|
UNTRACED = 0x02 # [XSI] notify on stop, untraced child
|
@@ -78,8 +82,9 @@ module Ragweed::Wraposx::Wait
|
|
78
82
|
end
|
79
83
|
|
80
84
|
module Ragweed::Wraposx::Vm; end
|
85
|
+
|
86
|
+
# vm_protect permission flags for memory spaces
|
81
87
|
module Ragweed::Wraposx::Vm::Prot
|
82
|
-
# vm_protect permission flags for memory spaces
|
83
88
|
READ = 0x1 #read permission
|
84
89
|
WRITE = 0x2 #write permission
|
85
90
|
EXECUTE = 0x4 #execute permission
|
@@ -87,8 +92,8 @@ module Ragweed::Wraposx::Vm::Prot
|
|
87
92
|
ALL = 0x7 #all permissions
|
88
93
|
end
|
89
94
|
|
95
|
+
# share mode constants
|
90
96
|
module Ragweed::Wraposx::Vm::Sm
|
91
|
-
# share mode constants
|
92
97
|
COW = 1
|
93
98
|
PRIVATE = 2
|
94
99
|
EMPTY = 3
|
@@ -98,6 +103,7 @@ module Ragweed::Wraposx::Vm::Sm
|
|
98
103
|
SHARED_ALIASED = 7
|
99
104
|
end
|
100
105
|
|
106
|
+
# dyld constants
|
101
107
|
module Ragweed::Wraposx::Dl
|
102
108
|
RTLD_LAZY = 0x1
|
103
109
|
RTLD_NOW = 0x2
|
@@ -1,8 +1,7 @@
|
|
1
|
-
# Exception objects for kernel errors likely in Wraposx
|
2
|
-
# If this were a C extension I'd use #ifdef on each to only create the required ones.
|
3
|
-
|
4
1
|
module Ragweed; end
|
5
2
|
module Ragweed::Wraposx; end
|
3
|
+
|
4
|
+
# Exception objects for kernel errors likely in Wraposx
|
6
5
|
module Ragweed::Wraposx::KernelReturn
|
7
6
|
SUCCESS = { :value => 0, :message => 'Not an error'}
|
8
7
|
INVALID_ADDRESS = { :value => 1, :message => 'Specified address is not currently valid.'}
|
@@ -192,10 +192,10 @@ EOM
|
|
192
192
|
end
|
193
193
|
end
|
194
194
|
|
195
|
-
#define VM_REGION_BASIC_INFO_COUNT ((mach_msg_type_number_t) (sizeof(vm_region_basic_info_data_t)/sizeof(int)))
|
196
|
-
#define VM_REGION_BASIC_INFO_COUNT_64 ((mach_msg_type_number_t) (sizeof(vm_region_basic_info_data_64_t)/sizeof(int)))
|
197
|
-
#define VM_REGION_EXTENDED_INFO_COUNT ((mach_msg_type_number_t) (sizeof(vm_region_extended_info_data_t)/sizeof(int)))
|
198
|
-
#define VM_REGION_TOP_INFO_COUNT ((mach_msg_type_number_t) (sizeof(vm_region_top_info_data_t)/sizeof(int)))
|
195
|
+
# define VM_REGION_BASIC_INFO_COUNT ((mach_msg_type_number_t) (sizeof(vm_region_basic_info_data_t)/sizeof(int)))
|
196
|
+
# define VM_REGION_BASIC_INFO_COUNT_64 ((mach_msg_type_number_t) (sizeof(vm_region_basic_info_data_64_t)/sizeof(int)))
|
197
|
+
# define VM_REGION_EXTENDED_INFO_COUNT ((mach_msg_type_number_t) (sizeof(vm_region_extended_info_data_t)/sizeof(int)))
|
198
|
+
# define VM_REGION_TOP_INFO_COUNT ((mach_msg_type_number_t) (sizeof(vm_region_top_info_data_t)/sizeof(int)))
|
199
199
|
FLAVORS = { REGION_BASIC_INFO => {:size => 30, :count => 8, :class => RegionBasicInfo},
|
200
200
|
REGION_BASIC_INFO_64 => {:size => 30, :count => 9, :class => RegionBasicInfo64},
|
201
201
|
REGION_EXTENDED_INFO => {:size => 32, :count => 8, :class => RegionExtendedInfo},
|
@@ -355,6 +355,14 @@ EOM
|
|
355
355
|
self.methods.include? mth || super
|
356
356
|
end
|
357
357
|
|
358
|
+
def dump(&block)
|
359
|
+
case self[:tsh][:flavor]
|
360
|
+
when Ragweed::Wraposx::ThreadContext::X86_THREAD_STATE32
|
361
|
+
self[:uts][:ts32].dump(&block)
|
362
|
+
when Ragweed::Wraposx::ThreadContext::X86_THREAD_STATE64
|
363
|
+
self[:uts][:ts64].dump(&block)
|
364
|
+
end
|
365
|
+
end
|
358
366
|
end
|
359
367
|
|
360
368
|
# _STRUCT_X86_DEBUG_STATE32
|