Dynamic code generation in Perl

Post on 02-Jul-2015

221 views 3 download

description

Dynamically change the code that your application is using.

Transcript of Dynamic code generation in Perl

Dynamic Code Generation

Marian HackMan Marinov

22.Nov.2014

Marian HackMan Marinov Dynamic Code Generation

Why would you need that?

Marian HackMan Marinov Dynamic Code Generation

Why would you need that?

Faster Development time

Marian HackMan Marinov Dynamic Code Generation

Why would you need that?

Faster Development time

Easier interfaces

Marian HackMan Marinov Dynamic Code Generation

Why would you need that?

Faster Development time

Easier interfaces

Abstraction

Marian HackMan Marinov Dynamic Code Generation

Why would you need that?

Faster Development time

Easier interfaces

Abstraction

Obfuscation

Marian HackMan Marinov Dynamic Code Generation

Why would you need that?

Faster Development time

Easier interfaces

Abstraction

Obfuscation/crypto

Performance

Marian HackMan Marinov Dynamic Code Generation

I will focus mainly on PERFORMANCE

Marian HackMan Marinov Dynamic Code Generation

Let’s start with a basic script

#!/usr/bin/perl

use warnings;

use strict;

sub DEBUG { 0; };

use constant ADEBUG => 0;

Marian HackMan Marinov Dynamic Code Generation

The following would be optimised out

if (DEBUG) {

print "Debuging\n";

}

if (ADEBUG) {

print "Debuging A\n";

}

Marian HackMan Marinov Dynamic Code Generation

What if we need to have something like this

if (defined($ARGV[0]) && $ARGV[0] eq ’ok’) {

sub DEBUG { 1; };

}

Marian HackMan Marinov Dynamic Code Generation

What if we need to have something like this

if (defined($ARGV[0]) && $ARGV[0] eq ’ok’) {

sub DEBUG { 1; };

}

$ perl f.pl ok

Subroutine DEBUG redefined at f.pl line 9.

$

Marian HackMan Marinov Dynamic Code Generation

Or something like this

if (defined($ARGV[0]) && $ARGV[0] eq ’ok’) {

ADEBUG => 1;

}

Marian HackMan Marinov Dynamic Code Generation

Or something like this

if (defined($ARGV[0]) && $ARGV[0] eq ’ok’) {

ADEBUG => 1;

}

$ perl f.pl ok

Useless use of a constant ("ADEBUG") in void context at f.pl line 9.

Marian HackMan Marinov Dynamic Code Generation

What if we start playing dirty :)

if (defined($ARGV[0]) && $ARGV[0] eq ’ok’) {

undef &ADEBUG;

use constant ADEBUG => 1;

}

$ perl f.pl ok

Constant subroutine main::ADEBUG redefined at /usr/share/perl5/constant.pm line 140.

Constant subroutine (anonymous) undefined at f.pl line 9.

Debuging

$

Marian HackMan Marinov Dynamic Code Generation

Let’s declare this as futile

Figure : Resistance is futile

Marian HackMan Marinov Dynamic Code Generation

So why did I tried to redifine a constant ?

What if we have a script which does:

while (my $line = <$fd>) {

if ($line =~ /RE/) { };

if ($line =~ /RE/) { };

....

....

if ($line =~ /RE/) { };

}

Marian HackMan Marinov Dynamic Code Generation

So why did I tried to redifine a constant ?

We can update it to:

while (my $line = <$fd>) {

if ($config{’type1’} && $line =~ /RE/) { };

if ($config{’type2’} && $line =~ /RE/) { };

....

....

if ($config{’typeN’} && $line =~ /RE/) { };

}

Marian HackMan Marinov Dynamic Code Generation

Hook::Filter

First looked at this

use Hook::Filter::RulePool qw(get_rule_pool);

get_rule_pool->add_rule("subname eq ’mydebug’ &&

from =~ /^My::Filthy::Attempt/");

->add_rule("from =~ /^My::Filthy::Attempt::func$/");

->add_rule("args(1) =~ /bob/");

Marian HackMan Marinov Dynamic Code Generation

Welcome to perlfilter

Preprocessor like directives for Perl

Marian HackMan Marinov Dynamic Code Generation

perlfilter

Filter::Util::Call - the main filter module

Marian HackMan Marinov Dynamic Code Generation

perlfilter

Filter::Util::Call - the main filter module

Filter::Simple - simplified version of the Util::Call

Marian HackMan Marinov Dynamic Code Generation

perlfilter

Filter::Util::Call - the main filter module

Filter::Simple - simplified version of the Util::Call

Filter::sh - filter the source trough cmd with shell

Marian HackMan Marinov Dynamic Code Generation

perlfilter

Filter::Util::Call - the main filter module

Filter::Simple - simplified version of the Util::Call

Filter::sh - filter the source trough cmd with shell

Filter::exec - filter the source trough cmd

Marian HackMan Marinov Dynamic Code Generation

perlfilter

Filter::Util::Call - the main filter module

Filter::Simple - simplified version of the Util::Call

Filter::sh - filter the source trough cmd with shell

Filter::exec - filter the source trough cmd

Filter::tee - copies all text from the line after the use

Marian HackMan Marinov Dynamic Code Generation

perlfilter

Filter::Util::Call - the main filter module

Filter::Simple - simplified version of the Util::Call

Filter::sh - filter the source trough cmd with shell

Filter::exec - filter the source trough cmd

Filter::tee - copies all text from the line after the use

Filter::cpp - pipes all souce trough the cpp pre-processor

Marian HackMan Marinov Dynamic Code Generation

Crypto filters

Filter::decrypt - example documentation for enc/decrypting

Marian HackMan Marinov Dynamic Code Generation

Crypto filters

Filter::decrypt - example documentation for enc/decrypting

Filter::Rijndael - decrypting source filter based on Rijndaelencryption

Marian HackMan Marinov Dynamic Code Generation

Crypto filters

Filter::decrypt - example documentation for enc/decrypting

Filter::Rijndael - decrypting source filter based on Rijndaelencryption

Filter::CBC - Source filter for Cipher Block Chaining

Marian HackMan Marinov Dynamic Code Generation

Crypto filters

Filter::decrypt - example documentation for enc/decrypting

Filter::Rijndael - decrypting source filter based on Rijndaelencryption

Filter::CBC - Source filter for Cipher Block Chaining

Filter::Crypto::CryptFile & Filter::Crypto::Decrypt

Marian HackMan Marinov Dynamic Code Generation

Filter::Util::Call part I

package Debug;

use strict;

use warnings;

use Filter::Util::Call;

use constant TRUE => 1;

use constant FALSE => 0;

sub import {

my ($type) = @_;

my (%context) = (

Enabled => defined $ENV{DEBUG},

InTraceBlock => FALSE,

Filename => (caller)[1],

LineNo => 0,

LastBegin => 0,

);

filter_add(bless \%context);

}Marian HackMan Marinov Dynamic Code Generation

Filter::Util::Call part II

sub filter {

my ($self) = @_;

my ($status);

$status = filter_read();

++ $self->{LineNo};

if ($self->{InTraceBlock}) {

if (/^\s*##\s*DEBUG_END/) {

$self->{InTraceBlock} = FALSE;

}

s/^/#/ if ! $self->{Enabled};

} elsif ( /^\s*##\s*DEBUG_BEGIN/ ) {

$self->{InTraceBlock} = TRUE;

$self->{LastBegin} = $self->{LineNo};

}

return $status;

}

1;Marian HackMan Marinov Dynamic Code Generation

Filter::Simple

package BANG;

use Filter::Simple;

FILTER {

s/BANG\s+BANG/die ’BANG’ if \$BANG/g;

};

1;

Marian HackMan Marinov Dynamic Code Generation

Filter::cpp

use Filter::cpp;

#define FRED 1

$a = 2 + FRED;

print "a = $a\n";

#ifdef FRED

print "Hello FRED\n";

#else

print "Where is FRED\n";

#endif

Marian HackMan Marinov Dynamic Code Generation

Thank you

Questions ?

Additional readinghttp://www.bytelabs.org/pub/papers/hburg07.pdf

Contact me:

Marian HackMan Marinov

mm [maybe at] 1h.com

icq: 7556201

irc: irc.freenode.net HackMan

jabber: hackman@jabber.org

Marian HackMan Marinov Dynamic Code Generation