diotalevi has asked for the wisdom of the Perl Monks concerning the following question:

I've always wanted to know what the Stunnix author meant in Re: Re: Re: Here is a commercial obfuscator by implying that I could somehow change ->request( ... ) into something still worked but was also obfuscated. Any ideas on how I could have futzed that up? All I can come up with is to replace the string literal "request" with a dereference like ->${\"request"} (obviously at that point request can be further mangled). Any other ideas?

Replies are listed 'Best First'.
Re: Obfuscating method calls
by broquaint (Abbot) on Jun 24, 2003 at 14:49 UTC
    Not sure if this fits the bill, but it might be of interest nonetheless
    package Filter::ObfuMethods; use Exporter::Tidy default => [ 'filter' ]; use Crypt::Rot13; use vars '%methods'; sub filter { my $code = pop; my(@calls) = $code =~ m{ \$? \w+ \s* -> \s* (\w+) }gx; @methods{map crypt_method($_), @calls} = @calls; $code =~ s{ ( \$? \w+ \s* -> \s* ) $methods{$_} } ($1\${\\\$Filter::ObfuMethods::methods{"$_"}})gx for keys %methods; return $code; } sub crypt_method { my $c = Crypt::Rot13->new; $c->charge(shift); return $c->rot13(6); } q[the end];
    And some code
    use Filter::ObfuMethods; my $code = <<'CODE'; sub foo { print "in foo\n" } sub bar { print "in bar\n" } main->foo; main -> bar(); my $o = bless []; $o->foo(); $o -> bar; CODE print filter($code); eval filter($code); warn "ack - $@" if $@; __output__ sub foo { print "in foo\n" } sub bar { print "in bar\n" } main->${\$Filter::ObfuMethods::methods{"luu"}}; main -> ${\$Filter::ObfuMethods::methods{"hgx"}}(); my $o = bless []; $o->${\$Filter::ObfuMethods::methods{"luu"}}(); $o -> ${\$Filter::ObfuMethods::methods{"hgx"}}; in foo in bar in foo in bar
    Ok, it's not terrifically obfuscated (rot13 not being the most secure of obfuscation methods) but it's something ;) It also needs to have more rigorous regex matching if it's going to be used on any old code and probably not delivered in it's current form and many other tweaks besides.
    HTH

    _________
    broquaint

Re: Obfuscating method calls
by abell (Chaplain) on Jun 24, 2003 at 14:40 UTC

    I guess he meant one could change the method name (and every invocation of said method) to something hard to read and without reference to what the method actually does. For instance, change

    sub average { ... } ... print average( ... )
    to
    sub xyyxwx { ... } ... print xyyxwx( ... )

    Of course this would be only one of several tricks (and not a particularly successful one) in a code obfuscator.

    Cheers

    Antonio

    The stupider the astronaut, the easier it is to win the trip to Vega - A. Tucket

      I must not have been clear. The reason ->request was not originally altered was because it belongs to the LWP package which is obviously not up for changing by the host module.

Re: Obfuscating method calls
by BrowserUk (Patriarch) on Jun 24, 2003 at 14:46 UTC

    I guess you could build an array of code references to all the methods called in the code and then call the methods as

    $coderefs[n]->( $obj, other parms );

    Reverse engineering a name from an array index would make life awkward for the deobfuscator.

    Whether it is possible to reliably track down the package from which the method will be invoked in order to get the address, given inheritance etc. is another question.

    Devious thoughts about overiding AUTOLOAD float through my brain too, but I'll leave them unpursued.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


Re: Obfuscating method calls
by adrianh (Chancellor) on Jun 25, 2003 at 00:14 UTC

    One method that springs to mind would be to add the obfu method names to the UNIVERSAL package and have them redirect to the actual methods.

    This would allow you to obfuscate core/standard module calls without having to munge their source.

    Another evil thing to do is to create constant subroutines to return the class names, and swap them around so the Foo subroutine returns the Bar package name. Can be most confusing.

    For example:

    #! /usr/bin/perl; use strict; use warnings; package Foo; sub new { bless {}, shift }; sub foo { my $self = shift; @_ ? $self->{foo} = shift : $self->{foo}; }; sub show { print "foo is ", shift->foo, "\n" }; package Bar; sub new { bless {}, shift }; sub bar { my $self = shift; @_ ? $self->{bar} = shift : $self->{bar}; }; sub show { print "bar is ", shift->bar, "\n" }; package main; use constant Bar => 'Foo'; use constant Foo => 'Bar'; { package UNIVERSAL; no warnings; *kwenve = sub { my $self = shift; $self->new(@_) }; *kwjehd = sub { my $self = shift; $self->foo(@_) }; *kjwehd = sub { my $self = shift; $self->bar(@_) }; *kfdlfe = sub { my $self = shift; $self->new(@_) }; *kedfgf = sub { my $self = shift; $self->show(@_) }; }; my ($kivbe, $kfovg) = (Bar->kwenve, Foo->kfdlfe); # my ($foo, $bar) = (Foo->new, Bar->new); $kivbe->kwjehd(12); # $foo->foo(12); $kfovg->kjwehd(42); # $bar->bar(42); $kivbe->kedfgf; # $foo->show; $kfovg->kedfgf; # $bar->show;
Re: Obfuscating method calls
by diotalevi (Canon) on Jun 24, 2003 at 14:25 UTC

    BTW - I'll be perfectly happy if this question never gets approved and definately not front-paged. There's no reason to help the unsocial buggers too much.