ragweed 0.1.7.3 → 0.2.0.pre1

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.
@@ -1,55 +1,72 @@
1
- require 'dl'
1
+ require 'ffi'
2
2
 
3
3
  module Ragweed; end
4
4
  module Ragweed::Wraposx
5
-
6
- # These hashes are the magic glue of the ragweed system calls.
7
- # This one holds the library references from Ruby/DL.
8
- LIBS = Hash.new do |h, str|
9
- if not str =~ /^[\.\/].*/
10
- str = "/usr/lib/" + str
11
- end
12
- if not str =~ /.*\.dylib$/
13
- str = str + ".dylib"
14
- end
15
- h[str] = DL.dlopen(str)
16
- end
17
-
18
- # This hash holds the function references from Ruby/DL.
19
- # It also auto populates LIBS.
20
- # CALLS["<library>!<function>:<argument types>=<return type>"]
21
- # Hash.new is a beautiful thing.
22
- CALLS = Hash.new do |h, str|
23
- lib = proc = args = ret = nil
24
- lib, rest = str.split "!"
25
- proc, rest = rest.split ":"
26
- args, ret = rest.split("=") if rest
27
- ret ||= "0"
28
- raise "need proc" if not proc
29
- h[str] = LIBS[lib][proc, ret + args]
30
- end
31
5
 
32
- NULL = DL::PtrData.new(0)
6
+ module Libc
7
+ extend FFI::Library
8
+ ffi_lib FFI::Library::LIBC
9
+ typedef :int, :kern_return_t
33
10
 
34
- SIZEOFINT = DL.sizeof('I')
35
- SIZEOFLONG = DL.sizeof('L')
11
+ typedef :ulong_long, :memory_object_offset_t
12
+ typedef :uint, :vm_inherit_t
13
+ typedef :uint, :natural_t
14
+ typedef :natural_t, :mach_msg_type_number_t
15
+ typedef :natural_t, :mach_port_name_t
16
+ typedef :mach_port_name_t, :mach_port_t
17
+ typedef :mach_port_t, :vm_map_t
18
+ typedef :mach_port_t, :task_t
19
+ typedef :mach_port_t, :thread_act_t
20
+ typedef :int, :vm_region_flavor_t
21
+ typedef :int, :vm_prot_t
22
+ typedef :int, :vm_behavior_t
23
+ typedef :int, :policy_t
24
+ typedef :int, :boolean_t
25
+ typedef :int, :thread_state_flavor_t
26
+ case FFI::Platform::LONG_SIZE
27
+ when 64
28
+ # ifdef __LP64__
29
+ typedef :uintptr_t, :vm_size_t
30
+ typedef :uintptr_t, :vm_offset_t
31
+ when 32
32
+ # else /* __LP64__ */
33
+ typedef :natural_t, :vm_size_t
34
+ typedef :natural_t, :vm_offset_t
35
+ else
36
+ raise "Unsupported Platform"
37
+ end
38
+
39
+ typedef :vm_offset_t, :vm_address_t
40
+
41
+ attach_function :getpid, [], :pid_t
42
+ attach_function :ptrace, [:int, :pid_t, :ulong, :int], :int
43
+ attach_function :wait, [:pointer], :pid_t
44
+ attach_function :waitpid, [:pid_t, :pointer, :int], :pid_t
45
+ attach_function :mach_task_self, [], :mach_port_t
46
+ attach_function :task_for_pid, [:mach_port_name_t, :int, :pointer], :kern_return_t
47
+ attach_function :task_threads, [:task_t, :pointer, :pointer], :kern_return_t
48
+ attach_function :kill, [:pid_t, :int], :int
49
+ attach_function :vm_read_overwrite, [:vm_map_t, :vm_address_t, :vm_size_t, :vm_address_t, :pointer], :kern_return_t
50
+ attach_function :vm_write, [:vm_map_t, :vm_address_t, :vm_offset_t, :mach_msg_type_number_t], :kern_return_t
51
+ attach_function :vm_protect, [:vm_map_t, :vm_address_t, :vm_size_t, :boolean_t, :vm_prot_t], :kern_return_t
52
+ attach_function :vm_allocate, [:vm_map_t, :pointer, :vm_size_t, :int], :kern_return_t
53
+ attach_function :vm_deallocate, [:vm_map_t, :vm_address_t, :vm_size_t], :kern_return_t
54
+ attach_function :thread_resume, [:thread_act_t], :kern_return_t
55
+ attach_function :thread_suspend, [:thread_act_t], :kern_return_t
56
+ attach_function :task_suspend, [:int], :kern_return_t
57
+ attach_function :task_resume, [:int], :kern_return_t
58
+ attach_function :sysctl, [:pointer, :int, :pointer, :pointer, :pointer, :int], :int
59
+ attach_function :execv, [:string, :pointer], :int
60
+ end
36
61
 
37
62
  class << self
38
63
 
39
- # time_t
40
- # time(time_t *tloc);
41
- #
42
- # see also time(3)
43
- def time
44
- CALLS["libc!time:=I"].call.first
45
- end
46
-
47
64
  # pid_t
48
65
  # getpid(void);
49
66
  #
50
67
  # see also getpid(2)
51
68
  def getpid
52
- CALLS["libc!getpid:=I"].call.first
69
+ Libc.getpid
53
70
  end
54
71
 
55
72
  # Apple's ptrace is fairly gimped. The memory read and write functionality has been
@@ -62,13 +79,48 @@ module Ragweed::Wraposx
62
79
  #
63
80
  # see also ptrace(2)
64
81
  def ptrace(request, pid, addr, data)
65
- DL.last_error = 0
66
- r = CALLS["libc!ptrace:IIII=I"].call(request, pid, addr, data).first
67
- raise SystemCallError.new("ptrace", DL.last_error) if r == -1 and DL.last_error != 0
68
- return r
82
+ FFI.errno = 0
83
+ r = Libc.ptrace(request, pid, addr, data)
84
+ raise SystemCallError.new("ptrace", FFI.errno) if r == -1 and FFI.errno != 0
85
+ [r, data]
86
+ end
87
+
88
+ # ptrace(PT_TRACE_ME, ...)
89
+ def pt_trace_me pid
90
+ ptrace(Ragweed::Wraposx::Ptrace::TRACE_ME, pid, nil, nil).first
91
+ end
92
+
93
+ # ptrace(PT_DENY_ATTACH, ... )
94
+ def pt_deny_attach pid
95
+ ptrace(Ragweed::Wraposx::Ptrace::DENY_ATTACH, pid, nil, nil).first
69
96
  end
70
97
 
71
- # Oringially coded for use in debuggerosx but I've switched to waitpid for
98
+ # ptrace(PT_CONTINUE, pid, addr, signal)
99
+ def pt_continue pid, addr = 1, sig = 0
100
+ ptrace(Ragweed::Wraposx::Ptrace::CONTINUE, pid, addr, sig).first
101
+ end
102
+
103
+ # ptrace(PT_STEP, pid, addr, signal)
104
+ def pt_step pid, addr = 1, sig = 0
105
+ ptrace(Ragweed::Wraposx::Ptrace::STEP, pid, addr, sig).first
106
+ end
107
+
108
+ # ptrace(PT_KILL, ... )
109
+ def pt_kill pid
110
+ ptrace(Ragweed::Wraposx::Ptrace::KILL, pid, nil, nil).first
111
+ end
112
+
113
+ # ptrace(PT_ATTACH, ... )
114
+ def pt_attach pid
115
+ ptrace(Ragweed::Wraposx::Ptrace::ATTACH, pid, nil, nil).first
116
+ end
117
+
118
+ # ptrace(PT_DETACH, ... )
119
+ def pt_detach pid
120
+ ptrace(Ragweed::Wraposx::Ptrace::DETACH, pid, nil, nil).first
121
+ end
122
+
123
+ # Originally coded for use in debuggerosx but I've switched to waitpid for
72
124
  # usability and debugging purposes.
73
125
  #
74
126
  # Returns status of child when child recieves a signal.
@@ -78,10 +130,11 @@ module Ragweed::Wraposx
78
130
  #
79
131
  # see also wait(2)
80
132
  def wait
81
- status = ("\x00"*SIZEOFINT).to_ptr
82
- r = CALLS["libc!wait:=I"].call(status).first
83
- raise SystemCallError.new("wait", DL.last_error) if r== -1
84
- return status.to_s(SIZEOFINT).unpack('i_').first
133
+ stat = FFI::MemoryPointer.new :int, 1
134
+ FFI.errno = 0
135
+ pid = Libc.wait stat
136
+ raise SystemCallError.new "wait", FFI.errno if pid == -1
137
+ [pid, stat.read_int]
85
138
  end
86
139
 
87
140
  # The wait used in debuggerosx.
@@ -95,13 +148,12 @@ module Ragweed::Wraposx
95
148
  # waitpid(pid_t pid, int *stat_loc, int options);
96
149
  #
97
150
  # see also wait(2)
98
- def waitpid(pid, opt=1)
99
- pstatus = ("\x00"*SIZEOFINT).to_ptr
100
- r = CALLS["libc!waitpid:IPI=I"].call(pid, pstatus, opt).first
101
- raise SystemCallError.new("waitpid", DL.last_error) if r== -1
102
-
103
- # maybe I should return a Hash?
104
- return [r, pstatus.to_s(SIZEOFINT).unpack('i_').first]
151
+ def waitpid pid, opts = 0
152
+ stat = FFI::MemoryPointer.new :int, 1
153
+ FFI.errno = 0
154
+ r = Libc.waitpid(pid, stat, opts)
155
+ raise SystemCallError.new "waitpid", FFI.errno if r == -1
156
+ [r, stat.read_int]
105
157
  end
106
158
 
107
159
  # From docs at http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/mach_task_self.html
@@ -112,9 +164,9 @@ module Ragweed::Wraposx
112
164
  #
113
165
  # There is no man page for this call.
114
166
  def mach_task_self
115
- CALLS["libc!mach_task_self:=I"].call().first
167
+ Libc.mach_task_self
116
168
  end
117
-
169
+
118
170
  # Requires sudo to use as of 10.5 or 10.4.11(ish)
119
171
  # Returns the task id for a process.
120
172
  #
@@ -125,12 +177,12 @@ module Ragweed::Wraposx
125
177
  #
126
178
  # There is no man page for this call.
127
179
  def task_for_pid(pid, target=nil)
128
- target ||= mach_task_self
129
- port = ("\x00"*SIZEOFINT).to_ptr
130
- r = CALLS["libc!task_for_pid:IIP=I"].call(target, pid, port).first
180
+ target ||= mach_task_self
181
+ port = FFI::MemoryPointer.new :int, 1
182
+ r = Libc.task_for_pid(target, pid, port)
131
183
  raise KernelCallError.new(:task_for_pid, r) if r != 0
132
- return port.to_s(SIZEOFINT).unpack('i_').first
133
- end
184
+ port.read_int
185
+ end
134
186
 
135
187
  # Returns an Array of thread IDs for the given task
136
188
  #
@@ -139,30 +191,29 @@ module Ragweed::Wraposx
139
191
  # thread_act_port_array_t thread_list,
140
192
  # mach_msg_type_number_t* thread_count);
141
193
  #
142
- #There is no man page for this funtion.
194
+ #There is no man page for this funtion.
143
195
  def task_threads(port)
144
- threads = ("\x00"*SIZEOFINT).to_ptr
145
- #threads = 0
146
- count = ("\x00"*SIZEOFINT).to_ptr
147
- r = CALLS["libc!task_threads:IPP=I"].call(port, threads, count).first
148
- t = DL::PtrData.new(threads.to_s(SIZEOFINT).unpack('i_').first)
196
+ threads = FFI::MemoryPointer.new :int, 1
197
+ count = FFI::MemoryPointer.new :int, 1
198
+ r = Libc.task_threads(port, threads, count)
149
199
  raise KernelCallError.new(:task_threads, r) if r != 0
150
- return t.to_a("I", count.to_s(SIZEOFINT).unpack('I_').first)
200
+ threads.read_array_of_int(count.read_int)
151
201
  end
152
202
 
153
203
  # Decrement the target tasks suspend count
154
204
  # kern_return_t task_resume
155
205
  # (task_t task);
156
206
  def task_resume(task)
157
- r = CALLC["libc!task_resume:I=I"].call(task).first
207
+ r = Libc.task_resume(task)
158
208
  raise KernelCallError.new(r) if r != 0
209
+ r
159
210
  end
160
211
 
161
212
  # Increment the target tasks suspend count
162
213
  # kern_return_t task_suspend
163
214
  # (task_t task);
164
215
  def task_suspend(task)
165
- r = CALLC["libc!task_suspend:I=I"].call(task).first
216
+ r = Libc.task_suspend(task)
166
217
  raise KernelCallError.new(r) if r != 0
167
218
  end
168
219
 
@@ -173,28 +224,9 @@ module Ragweed::Wraposx
173
224
  #
174
225
  # See kill(2)
175
226
  def kill(pid, sig)
176
- DL.last_error = 0
177
- r = CALLS["libc!kill:II=I"].call(pid,sig).first
178
- raise SystemCallError.new("kill",DL.last_error) if r != 0
179
- end
180
-
181
- # function to marshal 32bit integers into DL::PtrData objects
182
- # necessary due to Ruby/DL not properly dealing with 31 and 32 bit integers
183
- def dl_bignum_to_ulong(x)
184
- if x.class == Fixnum
185
- return DL::PtrData.new(x)
186
- else
187
- # shut up
188
- c = x / 4
189
- e = x - (c * 4)
190
- v = DL::PtrData.new 0
191
- v += c
192
- v += c
193
- v += c
194
- v += c
195
- v += e
196
- return v
197
- end
227
+ FFI::errno = 0
228
+ r = Libc.kill(pid, sig)
229
+ raise SystemCallError.new "kill", FFI::errno if r != 0
198
230
  end
199
231
 
200
232
  # Reads sz bytes from task's address space starting at addr.
@@ -208,10 +240,9 @@ module Ragweed::Wraposx
208
240
  #
209
241
  # There is no man page for this function.
210
242
  def vm_read(task, addr, sz=256)
211
- addr = dl_bignum_to_ulong(addr)
212
- buf = ("\x00" * sz).to_ptr
213
- len = (sz.to_l32).to_ptr
214
- r = CALLS["libc!vm_read_overwrite:IPIPP=I"].call(task, addr, sz, buf, len).first
243
+ buf = FFI::MemoryPointer.new(sz)
244
+ len = FFI::MemoryPointer(sz.to_l32)
245
+ r = Libc.vm_read_overwrite(task, addr, sz, buf, len)
215
246
  raise KernelCallError.new(:vm_read, r) if r != 0
216
247
  return buf.to_str(len.to_str(4).to_l32)
217
248
  end
@@ -227,9 +258,8 @@ module Ragweed::Wraposx
227
258
  #
228
259
  # There is no man page for this function.
229
260
  def vm_write(task, addr, val)
230
- addr = dl_bignum_to_ulong(addr)
231
- val = val.to_ptr
232
- r = CALLS["libc!vm_write:IPPI=I"].call(task, addr, val, val.size).first
261
+ val = FFI::MemoryPointer.new
262
+ r = Libc.vm_write(task, addr, val, val.size)
233
263
  raise KernelCallError.new(:vm_write, r) if r != 0
234
264
  return nil
235
265
  end
@@ -246,14 +276,12 @@ module Ragweed::Wraposx
246
276
  #
247
277
  # There is no man page for this function.
248
278
  def vm_protect(task, addr, size, setmax, prot)
249
- addr = dl_bignum_to_ulong(addr)
250
279
  setmax = setmax ? 1 : 0
251
- r = CALLS["libc!vm_protect:IPIII=I"].call(task,addr,size,setmax,prot).first
280
+ r = Libc.vm_protect(task, addr, size, setmax, prot)
252
281
  raise KernelCallError.new(:vm_protect, r) if r != 0
253
282
  return nil
254
283
  end
255
284
 
256
-
257
285
  # Allocates a page in the memory space of the target task.
258
286
  #
259
287
  # kern_return_t vm_allocate
@@ -263,13 +291,14 @@ module Ragweed::Wraposx
263
291
  # boolean_t anywhere);
264
292
  #
265
293
  def vm_allocate(task, address, size, anywhere)
266
- addr = int_to_intptr(address)
294
+ addr = FFI::MemoryPointer.new :int, 1
295
+ addr.write_int(address)
267
296
  anywhere = anywhere ? 1 : 0
268
- r = CALLS["libc!vm_allocate:IPII=I"].call(task,addr,size,anywhere).first
297
+ r = Libc.vm_allocate(task, addr, size, anywhere)
269
298
  raise KernelCallError.new(r) if r != 0
270
- addr.ptr
299
+ addr.address
271
300
  end
272
-
301
+
273
302
  # deallocates a page in the memoryspace of target task.
274
303
  #
275
304
  # kern_return_t vm_deallocate
@@ -277,12 +306,13 @@ module Ragweed::Wraposx
277
306
  # vm_address_t address,
278
307
  # vm_size_t size);
279
308
  #
280
- def vm_deallocate(task,address,size)
281
- addr = int_to_intptr(address)
282
- r = CALLS["libc!vm_deallocate:IPI=I"].call(task, addr, size).first
309
+ def vm_deallocate(task, address, size)
310
+ addr = FFI::MemoryPointer.new :int, 1
311
+ addr.write_int(address)
312
+ r = Libc.vm_deallocate(task, addr, size)
283
313
  raise KernelCallError.new(r) if r != 0
284
314
  end
285
-
315
+
286
316
  # Resumes a suspended thread by id.
287
317
  #
288
318
  # kern_return_t thread_resume
@@ -290,7 +320,7 @@ module Ragweed::Wraposx
290
320
  #
291
321
  # There is no man page for this function.
292
322
  def thread_resume(thread)
293
- r = CALLS["libc!thread_resume:I=I"].call(thread).first
323
+ r = Libc.thread_resume(thread)
294
324
  raise KernelCallError.new(:thread_resume, r) if r != 0
295
325
  end
296
326
 
@@ -301,133 +331,26 @@ module Ragweed::Wraposx
301
331
  #
302
332
  # There is no man page for this function.
303
333
  def thread_suspend(thread)
304
- r = CALLS["libc!thread_suspend:I=I"].call(thread).first
334
+ r = Libc.thread_suspend(thread)
305
335
  raise KernelCallError.new(:thread_suspend, r) if r != 0
306
336
  end
307
337
 
308
- # Suspends a task by id.
309
- #
310
- # kern_return_t task_suspend
311
- # (task_t task);
312
- #
313
- # There is no man page for this function.
314
- def task_suspend(task)
315
- r = CALLS["libc!task_suspend:I=I"].call(task).first
316
- raise KernelCallError.new(:task_suspend, r) if r != 0
317
- end
318
-
319
- # Resumes a suspended task by id.
320
- #
321
- # kern_return_t task_resume
322
- # (task_t task);
323
- #
324
- # There is no man page for this function.
325
- def task_resume(task)
326
- r = CALLS["libc!task_resume:I=I"].call(task).first
327
- raise KernelCallError.new(:task_resume, r) if r != 0
328
- end
329
-
330
- # Used to query kernel state.
331
- # Returns output buffer on successful call or required buffer size on ENOMEM.
332
- #
333
- # mib: and array of integers decribing the MIB
334
- # newb: the buffer to replace the old information (only used on some commands so it defaults to empty)
335
- # oldlenp: output buffer size
336
- #
337
- # int
338
- # sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
339
- #
340
- # this function doesn't really match the Ruby Way(tm)
341
- #
342
- # see sysctl(8)
343
- def sysctl(mib,oldlen=0,newb="")
344
- DL.last_error = 0
345
- mibp = mib.pack("I_"*mib.size).to_ptr
346
- oldlenp = [oldlen].pack("I_").to_ptr
347
- namelen = mib.size
348
- oldp = (oldlen > 0 ? "\x00"*oldlen : NULL)
349
- newp = (newb.empty? ? NULL : newb.to_ptr)
350
- newlen = newb.size
351
- r = CALLS["libc!sysctl:PIPPPI=I"].call(mibp, namelen, oldp, oldlenp, newp, newlen).first
352
- return oldlenp.to_str(SIZEOFINT).unpack("I_").first if (r == -1 and DL.last_error == Errno::ENOMEM::Errno)
353
- raise SystemCallError.new("sysctl", DL.last_error) if r != 0
354
- return oldp.to_str(oldlenp.to_str(SIZEOFINT).unpack("I_").first)
355
- end
356
-
357
- # Used to query kernel state.
358
- # Returns output buffer on successful call and required buffer size as an Array.
359
- #
360
- # mib: and array of integers decribing the MIB
361
- # newb: the buffer to replace the old information (only used on some commands so it defaults to empty)
362
- # oldlenp: output buffer size
363
- #
364
- # int
365
- # sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
366
- #
367
- # this function doesn't really match the Ruby Way(tm)
368
- #
369
- # see sysctl(8)
370
- def sysctl_raw(mib,oldlen=0,newb="")
371
- DL.last_error = 0
372
- mibp = mib.pack('I_'*mib.size).to_ptr
373
- oldlenp = [oldlen].pack("I_").to_ptr
374
- namelen = mib.size
375
- oldp = (oldlen > 0 ? ("\x00"*oldlen).to_ptr : NULL)
376
- newp = (newb.empty? ? NULL : newb.to_ptr)
377
- newlen = newb.size
378
- r = CALLS["libc!sysctl:PIPPPI=I"].call(mibp, namelen, oldp, oldlenp, newp, newlen).first
379
- ret = (DL.last_error == Errno::ENOMEM::Errno ? NULL : oldp)
380
- raise SystemCallError.new("sysctl", DL.last_error) if (r != 0 and DL.last_error != Errno::ENOMEM::Errno)
381
- return [ret,oldlenp.to_str(SIZEOFINT).unpack("I_").first]
382
- end
383
-
384
338
  # Changes execution to file in path with *args as though called from command line.
385
339
  #
386
340
  # int
387
341
  # execv(const char *path, char *const argv[]);
388
- def execv(path,*args)
389
- DL.last_error = 0
390
- argv = ""
391
- args.flatten.each { |arg| argv = "#{ argv }#{arg.to_ptr.ref.to_s(SIZEOFINT)}" }
392
- argv += ("\x00"*SIZEOFINT)
393
- r = CALLS["libc!execv:SP"].call(path,argv.to_ptr).first
394
- raise SystemCallError.new("execv", DL.last_error) if r == -1
395
- return r
396
- end
397
-
398
- def int_to_intptr(i)
399
- case i
400
- when Integer
401
- return [i].pack("I").to_ptr
402
- when DL::PtrData
403
- return i
404
- else
405
- raise ArgumentError, "Not an Integer"
342
+ def execv(path, *args)
343
+ FFI.errno = 0
344
+ args.flatten!
345
+ argv = FFI::MemoryPointer.new(:pointer, args.size + 1)
346
+ args.each_with_index do |arg, i|
347
+ argv[i].put_pointer(0, FFI::MemoryPointer.from_string(arg.to_s))
406
348
  end
349
+ argv[args.size].put_pointer(0, nil)
350
+
351
+ r = Libc.execv(path, argv)
352
+ # if this ever returns, there's been an error
353
+ raise SystemCallError(:execv, FFI.errno)
407
354
  end
408
355
  end
409
356
  end
410
-
411
- # if __FILE__ == $0
412
- # include Ragweed
413
- # require 'pp'
414
- # require 'constants'
415
- # addr = data = 0
416
- # pid = 1319
417
- # int = "\x00" * 4
418
- # port = 0
419
- # Wraposx::ptrace(Wraposx::Ptrace::ATTACH,pid,0,0)
420
- # # status = Wraposx::waitpid(pid,0)
421
- # # Wraposx::ptrace(Wraposx::Ptrace::CONTINUE,pid,1,0)
422
- # mts = Wraposx::mach_task_self
423
- # port = Wraposx::task_for_pid(mts,pid)
424
- # port2 = Wraposx::task_for_pid(mts,pid)
425
- # threads = Wraposx::task_threads(port)
426
- # state = Wraposx::thread_get_state(threads.first)
427
- # pp port
428
- # pp port2
429
- # pp threads
430
- # pp state
431
- # # Wraposx::thread_set_state(threads.first,state)
432
- # Wraposx::ptrace(Wraposx::Ptrace::DETACH,pid,0,0)
433
- # end
@@ -5,7 +5,7 @@ module Ragweed; end
5
5
  module Ragweed::Wraposx
6
6
 
7
7
  # :stopdoc:
8
- VERSION = '0.1.7.3'
8
+ VERSION = File.read(File.join(File.dirname(__FILE__),"..","..","VERSION")).strip
9
9
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
10
10
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
11
11
  # :startdoc:
@@ -54,6 +54,7 @@ module Ragweed::Wraposx
54
54
  end
55
55
  end # module Ragweed::Wraposx
56
56
 
57
+ require 'ragweed/wraposx/wraposx'
57
58
  Ragweed::Wraposx.require_all_libs_relative_to(__FILE__)
58
59
 
59
60
  # EOF
@@ -3,27 +3,51 @@ module Ragweed; end
3
3
  module Ragweed::Wraptux;end
4
4
 
5
5
  module Ragweed::Wraptux::Ptrace
6
- TRACE_ME = 0
7
- PEEK_TEXT = 1
8
- PEEK_DATA = 2
9
- PEEK_USER = 3
10
- POKE_TEXT = 4
11
- POKE_DATA = 5
12
- POKE_USER = 6
13
- CONTINUE = 7
14
- KILL = 8
15
- STEP = 9
16
- GETREGS = 12
17
- SETREGS = 13
18
- ATTACH = 16
19
- DETACH = 17
20
- SYSCALL = 24
6
+ TRACE_ME = 0
7
+ PEEK_TEXT = 1
8
+ PEEK_DATA = 2
9
+ PEEK_USER = 3
10
+ POKE_TEXT = 4
11
+ POKE_DATA = 5
12
+ POKE_USER = 6
13
+ CONTINUE = 7
14
+ KILL = 8
15
+ STEP = 9
16
+ GETREGS = 12
17
+ SETREGS = 13
18
+ ATTACH = 16
19
+ DETACH = 17
20
+ SYSCALL = 24
21
+ SETOPTIONS = 0x4200
22
+ GETEVENTMSG = 0x4201
23
+ GETSIGINFO = 0x4202
24
+ SETSIGINFO = 0x4203
25
+ end
26
+
27
+ module Ragweed::Wraptux::Ptrace::SetOptions
28
+ TRACESYSGOOD = 0x00000001
29
+ TRACEFORK = 0x00000002
30
+ TRACEVFORK = 0x00000004
31
+ TRACECLONE = 0x00000008
32
+ TRACEEXEC = 0x00000010
33
+ TRACEVFORKDONE = 0x00000020
34
+ TRACEEXIT = 0x00000040
35
+ MASK = 0x0000007f
36
+ end
37
+
38
+ module Ragweed::Wraptux::Ptrace::EventCodes
39
+ FORK = 1
40
+ VFORK = 2
41
+ CLONE = 3
42
+ EXEC = 4
43
+ VFORK_DONE = 5
44
+ EXIT = 6
21
45
  end
22
46
 
23
47
  module Ragweed::Wraptux::Signal
24
48
  SIGHUP = 1
25
49
  SIGINT = 2
26
- SIGQUIT = 3
50
+ SIGQUIT = 3
27
51
  SIGILL = 4
28
52
  SIGTRAP = 5
29
53
  SIGABRT = 6
@@ -59,10 +83,10 @@ module Ragweed::Wraptux::Signal
59
83
  end
60
84
 
61
85
  module Ragweed::Wraptux::Wait
62
- NOHANG = 1
63
- UNTRACED = 2
64
- EXITED = 4
65
- STOPPED = 8
66
- CONTINUED = 10
67
- NOWWAIT = 20
86
+ NOHANG = 1
87
+ UNTRACED = 2
88
+ EXITED = 4
89
+ STOPPED = 8
90
+ CONTINUED = 10
91
+ NOWWAIT = 20
68
92
  end
@@ -0,0 +1,25 @@
1
+ module Ragweed::FFIStructInclude
2
+ if RUBY_VERSION < "1.9"
3
+ def methods regular=true
4
+ super + self.offsets.map{|x| x.first.to_s}
5
+ end
6
+ else
7
+ def methods regular=true
8
+ super + self.offsets.map{|x| x.first}
9
+ end
10
+ end
11
+
12
+ def method_missing meth, *args
13
+ super unless self.respond_to? meth
14
+ if meth.to_s =~ /=$/
15
+ self.__send__(:[]=, meth.to_s.gsub(/=$/,'').intern, *args)
16
+ else
17
+ self.__send__(:[], meth, *args)
18
+ end
19
+ end
20
+
21
+ def respond_to? meth, include_priv=false
22
+ mth = meth.to_s.gsub(/=$/,'')
23
+ self.offsets.map{|x| x.first.to_s}.include? mth || super
24
+ end
25
+ end
File without changes