ragweed 0.2.3-java → 0.2.4-java
Sign up to get free protection for your applications and to get access to all the features.
- 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
|