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

I've been playing with the B:: modules this morning. I had an idea that it would be nice to be able to take a random script, poke around in it and do some kind of security audit. I know this is a bit optimistic but I thought it would give me a good chance to prod in the murky depths that is perl's guts.

Basically this code attempts to find out the eval statements and print out where they are. I'd also like it to print out the code that is trying to be eval'd. This is causing me grief as perl seems to be doing wacky stuff with constants and I'm ending up with objects of class 'SPECIAL' I can't work out what to do with.

entereval seems to be a UNOP and calling $op->first->sv seems to give me a SV I can't work out how to get the value of it. The printvars is an attempt to print out all the variables and I can see the string that I eval but I can't work out how to get it from the UNOP SV.

Has anyone got any ideas? I accept the fact that I'm doing something bady :)

Call this with perl -MFindEval yourscript.pl

use strict; use warnings; package FindEval; use B qw(minus_c main_root OPf_KIDS class comppadlist); my $eval = 0; sub walk { my $op = shift; if ($op->name eq 'entereval') { $eval++; printf "OP type for EVAL is %s\n", class($op); } elsif ($eval && $op->name eq 'nextstate') { printf "EVAL found on line %d\n", $op->line; $eval = 0; } if ($op->flags & OPf_KIDS) { for (my $kid = $op->first; $$kid; $kid = $kid->sibling) { walk($kid); } } } sub printvars { my ($name_av, $val_av) = comppadlist->ARRAY; foreach my $sv ($val_av->ARRAY) { print class($sv), "\t", eval { $sv->PVX }, "\n"; } } sub import { minus_c; eval 'CHECK { printvars(); walk(main_root); }'; print $@ if $@; } 1;

Thanks...

gav^