rallhook 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/AUTHORS +3 -0
  2. data/CHANGELOG +82 -0
  3. data/README +207 -0
  4. data/Rakefile +49 -0
  5. data/TODO +8 -0
  6. data/examples/hook/example1.rb +19 -0
  7. data/examples/hook/example2.rb +30 -0
  8. data/examples/hook/example3.rb +24 -0
  9. data/examples/hook/example4.rb +18 -0
  10. data/examples/hook/intercept.rb +41 -0
  11. data/examples/hook/intercept2.rb +49 -0
  12. data/examples/hook/redirect.rb +55 -0
  13. data/examples/hook/redirect_inherited.rb +28 -0
  14. data/examples/hook/shadow.rb +44 -0
  15. data/examples/instrospection/main.rb +13 -0
  16. data/examples/instrospection/source1.rb +4 -0
  17. data/examples/instrospection/source2.rb +4 -0
  18. data/ext/rallhook_base/distorm.h +401 -0
  19. data/ext/rallhook_base/extconf.rb +21 -0
  20. data/ext/rallhook_base/hook.c +165 -0
  21. data/ext/rallhook_base/hook.h +30 -0
  22. data/ext/rallhook_base/hook_rb_call.c +88 -0
  23. data/ext/rallhook_base/hook_rb_call.h +33 -0
  24. data/ext/rallhook_base/method_node.c +212 -0
  25. data/ext/rallhook_base/method_node.h +27 -0
  26. data/ext/rallhook_base/node_defs.h +294 -0
  27. data/ext/rallhook_base/rallhook.c +396 -0
  28. data/ext/rallhook_base/rb_call_fake.c +398 -0
  29. data/ext/rallhook_base/rb_call_fake.h +138 -0
  30. data/ext/rallhook_base/restrict_def.c +176 -0
  31. data/ext/rallhook_base/restrict_def.h +37 -0
  32. data/ext/rallhook_base/ruby_redirect.c +122 -0
  33. data/ext/rallhook_base/ruby_redirect.h +33 -0
  34. data/ext/rallhook_base/ruby_symbols.c +43 -0
  35. data/ext/rallhook_base/ruby_symbols.h +28 -0
  36. data/ext/rallhook_base/ruby_version.h +21 -0
  37. data/lib/rallhook/thread_hook.rb +37 -0
  38. data/lib/rallhook.rb +384 -0
  39. data/test/basic_proc.rb +45 -0
  40. data/test/integrity/test_array.rb +42 -0
  41. data/test/integrity/test_binding.rb +26 -0
  42. data/test/integrity/test_block.rb +37 -0
  43. data/test/integrity/test_call.rb +1 -0
  44. data/test/integrity/test_class_methods.rb +1 -0
  45. data/test/integrity/test_exception.rb +1 -0
  46. data/test/integrity/test_super.rb +34 -0
  47. data/test/introspection/test_call.rb +29 -0
  48. data/test/introspection/test_class_method.rb +41 -0
  49. data/test/introspection/test_file.rb +15 -0
  50. metadata +113 -0
@@ -0,0 +1,37 @@
1
+ /*
2
+
3
+ This file is part of the rallhook project, http://github.com/tario
4
+
5
+ Copyright (c) 2009-2010 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ rallhook is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ rallhook is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with rallhook. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ */
21
+ #ifndef __RESTRICT_DEF_H
22
+ #define __RESTRICT_DEF_H
23
+
24
+ #include "ruby.h"
25
+
26
+ void init_restrict_def();
27
+
28
+ void disable_overwrite(VALUE current_thread);
29
+ void enable_overwrite(VALUE current_thread);
30
+
31
+ void shadow_redirect(VALUE* klass, VALUE* recv, ID* mid);
32
+
33
+ VALUE unshadow(VALUE klass) ;
34
+
35
+ VALUE shadow_or_create(VALUE klass);
36
+
37
+ #endif
@@ -0,0 +1,122 @@
1
+ /*
2
+
3
+ This file is part of the rallhook project, http://github.com/tario/rallhook
4
+
5
+ Copyright (c) 2009-2010 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ rallhook is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ rallhook is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with rallhook. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ */
21
+ #include "ruby_redirect.h"
22
+ #include "ruby_symbols.h"
23
+ #include "rb_call_fake.h"
24
+ #include "hook_rb_call.h"
25
+ #include "pthread.h"
26
+
27
+ int code_changed = 0;
28
+
29
+ REDIRECTHANDLER current_redirect_handler;
30
+
31
+ void init_redirect();
32
+
33
+ int put_redirect_handler_( REDIRECTHANDLER redirect_handler) {
34
+ current_redirect_handler = redirect_handler;
35
+
36
+ if (!code_changed) {
37
+ // insert inconditional jmp from rb_call to rb_call_copy
38
+
39
+ #ifdef __i386__
40
+ rb_call_copy = (RBCALL)hook_rb_call(rb_call_fake_regs);
41
+ #endif
42
+
43
+ #ifdef __x86_64__
44
+ rb_call_copy = (RBCALL)hook_rb_call(rb_call_fake);
45
+ #endif
46
+ // calibrate protocol of rb_call
47
+ #ifdef __i386__
48
+ is_calibrate = 1;
49
+
50
+ VALUE test_value = LONG2FIX(0);
51
+
52
+ calibrate_recv = test_value;
53
+ calibrate_klass = CLASS_OF(test_value);
54
+ calibrate_mid = rb_intern("to_s");
55
+
56
+ rb_funcall(test_value, calibrate_mid, 0);
57
+
58
+
59
+ #endif
60
+
61
+ if (!rb_call_copy) {
62
+ rb_raise( rb_eFatal, "libruby incompatible with rallhook");
63
+ }
64
+
65
+ #ifdef RUBY1_9
66
+ #ifdef __i386__
67
+
68
+ rb_eval_string("def Object.___calibrate_x(x); end");
69
+
70
+ calibrate_recv = rb_cObject;
71
+ calibrate_klass = CLASS_OF(rb_cObject);
72
+ calibrate_mid = rb_intern("___calibrate_x");
73
+
74
+ vm_call_method_copy = (VMCALLMETHOD)hook_vm_call_method(vm_call_method_fake_regs);
75
+ vm_is_calibrate = 1;
76
+
77
+ char code[256];
78
+ snprintf(code, sizeof(code), "Object.___calibrate_x(%i)", test_value);
79
+ rb_eval_string(code);
80
+
81
+ #endif
82
+ #ifdef __x86_64__
83
+ vm_call_method_copy = (VMCALLMETHOD)hook_vm_call_method(vm_call_method_fake);
84
+ #endif
85
+
86
+ if (!vm_call_method_copy) {
87
+ rb_raise( rb_eFatal, "libruby incompatible with rallhook");
88
+ }
89
+ #endif
90
+
91
+ code_changed = 1;
92
+ }
93
+
94
+ return 0;
95
+ }
96
+
97
+
98
+ pthread_mutex_t put_redirect_handler_mutex;
99
+
100
+ int put_redirect_handler( REDIRECTHANDLER redirect_handler) {
101
+
102
+ pthread_mutex_lock(&put_redirect_handler_mutex);
103
+ put_redirect_handler_(redirect_handler);
104
+ pthread_mutex_unlock(&put_redirect_handler_mutex);
105
+ }
106
+
107
+
108
+ void init_redirect() {
109
+
110
+ pthread_mutexattr_t attr;
111
+
112
+ pthread_mutexattr_init(&attr);
113
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
114
+
115
+ pthread_mutex_init( &put_redirect_handler_mutex, &attr);
116
+
117
+ init_hook_rb_call();
118
+ rb_call_fake_init();
119
+ }
120
+
121
+
122
+
@@ -0,0 +1,33 @@
1
+ /*
2
+
3
+ This file is part of the rallhook project, http://github.com/tario/rallhook
4
+
5
+ Copyright (c) 2009-2010 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ rallhook is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ rallhook is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with rallhook. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ */
21
+ #ifndef __RUBY_REDIRECT_H
22
+ #define __RUBY_REDIRECT_H
23
+
24
+ // Acts as facade of the division between the ruby interpreter modification
25
+
26
+ #include <ruby.h>
27
+
28
+ typedef void (*REDIRECTHANDLER) ( VALUE* klass, VALUE* recv, ID* mid );
29
+ int put_redirect_handler( REDIRECTHANDLER redirect_handler);
30
+
31
+ void init_redirect();
32
+
33
+ #endif
@@ -0,0 +1,43 @@
1
+ /*
2
+
3
+ This file is part of the rallhook project, http://github.com/tario/rallhook
4
+
5
+ Copyright (c) 2009-2010 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ rallhook is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ rallhook is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with rallhook. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ */
21
+
22
+ #include "ruby_symbols.h"
23
+ #include "ruby.h"
24
+
25
+ void* ruby_resolv(unsigned char* p_base, const char* symbol_name) {
26
+ VALUE rb_mCymbol = rb_eval_string("Cymbol");
27
+ VALUE rb_str_symbol_name = rb_str_new2(symbol_name);
28
+
29
+ VALUE rb_offset = rb_funcall(rb_mCymbol,rb_intern("resolv"), 1, rb_str_symbol_name);
30
+
31
+ unsigned long long offset = FIX2LONG(rb_offset);
32
+
33
+ return (p_base + offset);
34
+ }
35
+
36
+
37
+ const char* current_libruby() {
38
+ VALUE rb_mCymbol = rb_eval_string("Cymbol");
39
+ VALUE rb_strSharedName = rb_funcall(rb_mCymbol,rb_intern("ruby_shared_name"), 0);
40
+
41
+ return rb_string_value_ptr(&rb_strSharedName);
42
+ }
43
+
@@ -0,0 +1,28 @@
1
+ /*
2
+
3
+ This file is part of the rallhook project, http://github.com/tario/rallhook
4
+
5
+ Copyright (c) 2009-2010 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ rallhook is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ rallhook is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with rallhook. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ */
21
+
22
+ #ifndef __RUBY_SYMBOLS_H
23
+ #define __RUBY_SYMBOLS_H
24
+
25
+ void* ruby_resolv(unsigned char* p_base, const char* symbol_name);
26
+ const char* current_libruby();
27
+
28
+ #endif
@@ -0,0 +1,21 @@
1
+ /*
2
+
3
+ This file is part of the rallhook project, http://github.com/tario/rallhook
4
+
5
+ Copyright (c) 2009-2010 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ rallhook is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ rallhook is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with rallhook. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ */
21
+
@@ -0,0 +1,37 @@
1
+ =begin
2
+
3
+ This file is part of the rallhook project, http://github.com/tario/
4
+
5
+ Copyright (c) 2009-2010 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ rallhook is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ rallhook is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with rallhook. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ class Thread
22
+
23
+ class << self
24
+ alias :original_new :new
25
+
26
+ private :original_new
27
+
28
+ def new
29
+ parent = current
30
+ original_new do
31
+ parent.acquire_attributes do
32
+ yield
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
data/lib/rallhook.rb ADDED
@@ -0,0 +1,384 @@
1
+ =begin
2
+
3
+ This file is part of the rallhook project, http://github.com/tario/
4
+
5
+ Copyright (c) 2009-2010 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ rallhook is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ rallhook is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with rallhook. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ require "rubygems"
22
+ require "rallhook_base"
23
+ require "rallhook/thread_hook"
24
+
25
+ module RallHook
26
+ #
27
+ #Internal class used for return method redirection messages
28
+ #Example:
29
+ # ...
30
+ # class X
31
+ # def foo
32
+ # end
33
+ # end
34
+ # def handle_method
35
+ # return RallHook::Redirect.new(X, X.new, :foo)
36
+ # end
37
+ # ...
38
+ #
39
+ #Note: Use x.redirect(:foo) instead (see Object#redirect )
40
+ #
41
+ class Redirect
42
+ include MethodRedirect
43
+
44
+ attr_reader :recv
45
+
46
+ def initialize(klass, recv, m, unhook = nil)
47
+ @klass = klass
48
+ @recv = recv
49
+ @method = m
50
+ @unhook = unhook
51
+ end
52
+ end
53
+ #
54
+ #Internal class used by RallHook::Helper#return_value
55
+ #
56
+ class ReturnHolder
57
+ def initialize(v)
58
+ @value = v
59
+ end
60
+ def value(*x)
61
+ @value
62
+ end
63
+ end
64
+
65
+ #
66
+ #This module brings together classes and methods to facilitate the handling
67
+ #
68
+ module Helper
69
+
70
+ #Equivalent to:
71
+ # recv.redirect(m, klass)
72
+ def redirect_call(klass, recv, m)
73
+ ::RallHook::Redirect.new(klass,recv,m)
74
+ end
75
+
76
+ #Return a value as return value of the method being handled
77
+ #Example:
78
+ #
79
+ # include RallHook::Helper
80
+ # def handle_method
81
+ # return_value(4) # all methods called returns 4
82
+ # end
83
+ #
84
+ def return_value(v)
85
+ recv = ReturnHolder.new(v)
86
+ klass = recv.class
87
+ m = :value
88
+ redirect_call(klass, recv, m)
89
+ end
90
+
91
+ #
92
+ #This class acts as base to define classes that acts as receptors and wrappers of
93
+ #redirected methods. Allows interception of methods with its parameters and controlled recall
94
+ #in a hooking logic
95
+ #
96
+ #Example 1: basic modifications of arguments
97
+ #
98
+ # class MethodHandler
99
+ # include RallHook::Helper
100
+ #
101
+ # class FooMethodWrapper < RallHook::MethodWrapper
102
+ # def call(foo_argument)
103
+ # original_call(foo_argument + 5) # add 5 in all calls to foo
104
+ # end
105
+ # end
106
+ #
107
+ # def handle_method (klass,recv,m,method_id)
108
+ # if m == :foo
109
+ # FooMethodWrapper.redirect_handler(klass,recv,m,method_id)
110
+ # else
111
+ # nil
112
+ # end
113
+ # end
114
+ # end
115
+ #
116
+ # ... hooking using MethodHandler ( see Hook#hook, README and examples)
117
+ #
118
+ #
119
+ #Example 2: generic recall of methods
120
+ #
121
+ # class MethodHandler
122
+ # include RallHook::Helper
123
+ #
124
+ # class GenericMethodWrapper < RallHook::MethodWrapper
125
+ # def call(*x)
126
+ # # call with reyield if block_given
127
+ # if block_given?
128
+ # original_call(*x) do |*a|
129
+ # yield(*a)
130
+ # end
131
+ # else
132
+ # original_call(*x)
133
+ # end
134
+ # end
135
+ # end
136
+ #
137
+ # def handle_method (klass,recv,m,method_id)
138
+ # return GenericMethodWrapper.redirect_handler(klass,recv,m,method_id)
139
+ # end
140
+ # end
141
+ #
142
+ # ... hooking using MethodHandler ( see Hook#hook, README and examples)
143
+ #
144
+ #
145
+ class MethodWrapper
146
+
147
+ attr_accessor :klass, :recv, :method_name, :method_id
148
+
149
+ #Reactivate the hook status to intercept methods
150
+ #Allow to pass a block to enable the hook status only in that block
151
+ #
152
+ #Example:
153
+ # class MethodHandler
154
+ # include RallHook::Helper
155
+ #
156
+ # class FooMethodWrapper < RallHook::MethodWrapper
157
+ # def call(foo_argument)
158
+ # original_call(foo_argument + 5) # add 5 in all calls to foo
159
+ # rehook do # the print "hello world hooked" are intercepted too
160
+ # print "hello world hooked\n"
161
+ # end
162
+ # end
163
+ # end
164
+ #
165
+ # ... definition of handle_method that use FooMethodWrapper as redirect, etc...
166
+ #
167
+ #Note: is not necesary to use rehook to hook the nested calls in original_call
168
+ #MethodWrapper#original_call does that internally
169
+ #
170
+ def rehook
171
+ if block_given?
172
+ ::RallHook::Hook.rehook do
173
+ yield
174
+ end
175
+ else
176
+ ::RallHook::Hook.rehook
177
+ end
178
+ end
179
+
180
+ #
181
+ #Same as Hook#from
182
+ #
183
+ def from(a)
184
+ ::RallHook::Hook.from(a)
185
+ self
186
+ end
187
+
188
+ #
189
+ #Recall the original method(specified in initialization parameters)
190
+ #
191
+ def original_call(*args)
192
+ mname = self.method_name
193
+ mklass = self.klass
194
+ mid = self.method_id
195
+ recv_ = self.recv
196
+
197
+ # original calls over the shadow of the class, not the original one
198
+ m = recv_.specific_method(mklass.shadow,mname)
199
+
200
+ if block_given?
201
+ from(3).rehook do
202
+ m.call(*args) do |*blockargs|
203
+ yield(*blockargs)
204
+ end
205
+ end
206
+ else
207
+ from(3).rehook do
208
+ m.call(*args)
209
+ end
210
+ end
211
+ end
212
+
213
+ #
214
+ #Target of redirection, should be implemented to intercept the call
215
+ #
216
+ def call(*args)
217
+ end
218
+
219
+ def call_with_rehook(*args)
220
+ if block_given?
221
+ call(*args) do |*x|
222
+ yield(*x)
223
+ end
224
+ else
225
+ call(*args)
226
+ end
227
+ ensure
228
+ rehook
229
+ end
230
+
231
+ #
232
+ #Makes a redirect_handler to wrap a method call with this MethodWrapper. Example:
233
+ #
234
+ # FooMethodWrapper.redirect_handler(klass,recv,m,method_id)
235
+ #
236
+ def self.redirect_handler(klass,recv,method_name, method_id)
237
+ if method_name
238
+
239
+ mw = self.new
240
+ mw.klass = klass
241
+ mw.recv = recv
242
+ mw.method_name = method_name
243
+ mw.method_id = method_id
244
+ if block_given?
245
+ yield(mw)
246
+ end
247
+ mw.redirect_with_unhook(:call_with_rehook)
248
+ else
249
+ nil
250
+ end
251
+ end
252
+
253
+ end
254
+ end
255
+
256
+
257
+
258
+ class HookHandler
259
+
260
+ #default method_handler of a Hook does nothing with any method call
261
+ def handle_method
262
+ nil
263
+ end
264
+
265
+ #enable the hook. Example
266
+ #
267
+ # class MethodHandler < Hook
268
+ # def handle_method
269
+ # nil # do nothing
270
+ # end
271
+ # end
272
+ #
273
+ # MethodHandler.hook do
274
+ # print "hello world\n"
275
+ # end
276
+ #
277
+
278
+ def hook
279
+ if block_given?
280
+ ::RallHook::Hook.hook self do
281
+ yield
282
+ end
283
+ else
284
+ ::RallHook::Hook.hook self
285
+ end
286
+ end
287
+
288
+ #Instance handler and activate the hook
289
+ #Example:
290
+ #
291
+ # class MethodHandler < Hook
292
+ # def handle_method
293
+ # nil # do nothing
294
+ # end
295
+ # end
296
+ #
297
+ # MethodHandler.hook do
298
+ # print "hello world\n"
299
+ # end
300
+
301
+ def self.hook
302
+ if block_given?
303
+ self.new.hook do
304
+ yield
305
+ end
306
+ else
307
+ self.new.hook
308
+ end
309
+ end
310
+ end
311
+
312
+
313
+
314
+ end
315
+
316
+ # To facilitate the use of hooking/redirection features,
317
+ # rallhook defines some methods in the Object class
318
+ #
319
+
320
+ class Object
321
+
322
+
323
+ # Same as redirect, but disable the hook/interception of methods (dont call handle_redirect) before
324
+ # make the call, the hook status may be restored with Hook#rehook
325
+ # Anyway, it is desirable to use MethodWrapper instead to "wrap" method calls
326
+ #
327
+ # see RallHook::Helper::MethodWrapper
328
+ #
329
+ def redirect_with_unhook(method_name, klass = nil)
330
+ if klass
331
+ ::RallHook::Redirect.new(klass,self,method_name,true)
332
+ else
333
+ ::RallHook::Redirect.new(self.class,self,method_name,true)
334
+ end
335
+
336
+ end
337
+
338
+ # Generates a redirect message to return it in handle_method to cause the redirection of
339
+ # the method that is beign processed with the object as receiver, the method_name the new target
340
+ # and the class as second parameter if specified
341
+ #
342
+ # Example:
343
+ # class X
344
+ # def foo(*args)
345
+ # end
346
+ # end
347
+ #
348
+ # class MethodHandler
349
+ # @@x = x.new
350
+ # def handle_method(klass, recv, m , method_id)
351
+ # if m == :bar then
352
+ # # redirect bar calls to foo in x
353
+ # return x.redirect(:foo)
354
+ # end
355
+ # nil # do nothing
356
+ # end
357
+ # end
358
+ #
359
+ # # hook using MethodHandler, etc... (see README and examples)
360
+ #
361
+ #
362
+ def redirect(method_name, klass = nil)
363
+ if klass
364
+ ::RallHook::Redirect.new(klass,self,method_name)
365
+ else
366
+ ::RallHook::Redirect.new(self.class,self,method_name)
367
+ end
368
+ end
369
+
370
+ def specific_method(arg1, arg2=nil)
371
+ if arg2
372
+ method_name = arg2
373
+ klass = arg1
374
+
375
+ if instance_of? Class
376
+ method(method_name)
377
+ else
378
+ klass.shadow.instance_method(method_name).unchecked_bind(self)
379
+ end
380
+ else
381
+ method(arg1)
382
+ end
383
+ end
384
+ end