Home > rallhook

rallhook

Rallhook is a project mainly written in C and RUBY, based on the GPL-3.0 license.

Allow hooking of all method invocations transparently to control and / or monitor the behavior of a ruby program

= rallhook - An ruby absolute method hooker

This package contains rallhook, a ruby C extension to intercept ruby methods calls at interpreter level in a transparent way from ruby itself.

== Installation

=== Prerequisites

  • ruby-cymbol >= 0.1.0 (found at http://github.com/tario/ruby-cymbol)
  • ruby debug info ( apt-get install libruby1.8-dbg or libruby1.9-dbg on debian based systems)
  • ruby development package ( apt-get install ruby1.8-dev or ruby1.9-dev on debian based systems)
  • objdump

=== Installation

  • run in your system

sudo gem install rallhook

OR

  • Download the last version of the gem from http://github.com/tario/ruby-cpp/downloads
  • Install the gem with the following;

sudo gem install rallhook-X.X.X.gem

== Usage

=== Basic Example

test.rb:

require "rubygems"
require "rallhook"

include RallHook

class MethodHandler < HookHandler

    def handle_method (klass,self_,m, method_id)

        # print to the standar output details about the method called
        print "method call #{m}:#{method_id} over #{self_}:#{self_.class} 
"
        nil # do nothing
    end
end

MethodHandler.hook do
# all ruby calls in this block are intercepted by hook_recv::call

    [1,2,3].each do |x|
    print x,"
"
    end

end

standard output:

method call each:4001 over 123:Array
method call print:7697 over main:Object
method call write:7649 over #<IO:0x7fb15e54fad0>:IO
method call to_s:3137 over 1:Fixnum
1method call write:7649 over #<IO:0x7fb15e54fad0>:IO

method call print:7697 over main:Object
method call write:7649 over #<IO:0x7fb15e54fad0>:IO
method call to_s:3137 over 2:Fixnum
2method call write:7649 over #<IO:0x7fb15e54fad0>:IO

method call print:7697 over main:Object
method call write:7649 over #<IO:0x7fb15e54fad0>:IO
method call to_s:3137 over 3:Fixnum
3method call write:7649 over #<IO:0x7fb15e54fad0>:IO

=== Redirecting calls

require "rubygems"
require "rallhook"

include RallHook

class MethodHandler < HookHandler
    include RallHook::Helper

    def handle_method (klass,recv,m,method_id)

        if m == :foo
            # redirects the calls of method foo to method bar on the same object
            return redirect_call(klass,recv, :bar)
        end

        if m == :bar
            # redirects the calls of method bar to method bar on the method_handler
            return redirect_call(self.class,self, :bar)
        end

        nil # do nothing
    end

    def bar
        print "bar in MethodHandler
"
    end
end

class X
    def foo
        print "foo in X
"
    end
    def bar
        print "bar in X
"
    end
end

print "WITHOUT HOOK:
"

x = X.new
x.foo
x.bar

print "WITH HOOK:
"

MethodHandler.hook do
    # all ruby calls in this block are intercepted by hook_recv::call
    x = X.new
    x.foo # redirected to X#bar
    x.bar # redirected to MethodHandler#bar

end

=== Wrap Calls require "rubygems" require "rallhook"

include RallHook

class MethodHandler < HookHandler
    include RallHook::Helper

    class FooMethodWrapper < MethodWrapper
        def call(*x)
            # call with reyield if block_given
            if block_given?
                original_call(*x) do |*a|
                    yield(*a)
                end
                # add "�bar?"
                yield("bar?")
            else
                original_call(*x)
            end
        end
    end

    def handle_method (klass,recv,m,method_id)
        if m == :each
            return FooMethodWrapper.redirect_handler(klass,recv,m,method_id)
        end
        nil # do nothing
    end
end

print "calling Array#each without hook
"
[1,2,3,4].each do |x|
    print x.inspect, " "
end
print "
"

print "calling Array#each WITH hook
"
MethodHandler.hook do

    # 1 2 3 4 "bar?"
    [1,2,3,4].each do |x|
        print x.inspect," "
    end
    print "
"

end

=== Method Instrospection new features example

source1.rb

class X
    def foo
    end
end

source2.rb

class Y < X
    def foo
    end
end

main.rb

require "rallhook"
require "source1.rb"
require "source2.rb"

x = X.new
y = Y.new

print x.method(:foo).body.file,"
" # source1.rb
print y.method(:foo).body.file,"
" # source2.rb

print y.method(X,:foo).body.file,"
" # source1.rb
print y.method(Y,:foo).body.file,"
" # source2.rb

== Copying

Copyright (c) 2010 Dario Seminara, released under the GPL License (see LICENSE)

Previous:07-SK-K-L