Executing entire perl program from string in Perl
I have a program that is encrypted with Blowfish in a file and a second perl program that prompts for a passphrase tha开发者_运维百科t is used to decrypt it into a string, I would like to not have to write the decrypted source to the hard drive ever, although having it in memory isn't really a problem as those running the program already know the source. I thought I might use eval but the program I need to run has a lot of input/output using Curses and stuff so eval wont work as it only returns the last value... Does anyone have any idea how this could be accomplished?
You can use an @INC
hook to perform the decryption. Then you can simply require
or use
the encrypted program. For example,
# loader.pl
use Crypt::Rot13;
use File::Spec;
sub decrypt_line {
if ($_ ne '') {
my ($self, $state) = @_;
my ($crypt, $key) = @$state;
$crypt->charge($_);
($_) = $crypt->rot13($key);
return 1;
}
}
sub load_crypt {
my ($self, $filename) = @_;
print "Key?\n";
chomp(my $key = <STDIN>);
for my $prefix (@INC) {
open my $fh, '<', File::Spec->catfile($prefix, "$filename.r13") or next;
return ($fh, \&decrypt_line, [Crypt::Rot13->new(), $key]);
}
}
BEGIN {
unshift @INC, \&load_crypt;
}
require 'hello.pl';
# hello.pl.r13
cevag "Uryyb, jbeyq!\a";
$ perl loader.pl Key? 13 Hello, world!
There's no reason eval
won't work for what you describe. While it only returns a single value, that doesn't prevent the eval'd code from interacting with the terminal. It's not usually used that way, but your use-case is a legitimate reason for using string eval
. (Note that you could still end up with the source code written to your swap file.)
Just start a separate perl instance and pass the program to it using standard input, like this:
echo 'print 2+2 . "\n";' | perl -
With perl code:
open(P,"|perl -") || die "Failed: $!\n";
print P 'print 2+2 . "\n"'
精彩评论