tlemons has asked for the wisdom of the Perl Monks concerning the following question:
Hi
I have a Perl application that consists of a Perl program (foo.pl) and a Perl module (bar.pm). There are some secrets in bar.pm that I don't want to share with the application's user. So, I'm planning to use Perl2Exe on bar.pm to create bar.exe. (I can't use Perl2Exe on foo.pl, because foo.pl uses IPC::Run, which Perl2Exe does not currently support)
I need to call the 12 functions in bar.exe from foo.pl. Currenly, in my foo.pl<>bar.pm world, foo.pl does a 'use bar', and executes the subroutines in bar.pm. The subroutine calls pass multiple parameters into bar.pm's subroutines, and receive multiple return values in return. This all works fine.
But, when I turn bar.pm into bar.exe, how then can I call bar's subroutines (passing multiple input values and receiving multiple return values)?
Thanks!
tl
Re: Using Perl subroutines in a Perl2Exe exe file
by Xaositect (Friar) on Jun 29, 2005 at 19:32 UTC
|
I haven't used Perl2Exe, but I suspect this won't be possible. bar.pm as you describe it is intended to be a resource, whereas bar.exe would be a program.
The only way to accomplish this that I could think of would be to write another script that uses Bar.pm, and provides a command-line interface so you could perl2exe the new script, and make system calls with command-line arguments in foo.pl.
Frankly, I'd suspect that perl2exe won't provide much code protection anyway. Many of these 'create an exe out of a scripting language' programs just give you back an executable perl interpreter that's designed to look inside it's own file for the perl code to execute. (which means that anyone with an editor can open the exe, page through the binary garbage, and find your code at the end) If your desire is simply to protect your source, you'll be better off finding a tool specifically for that.
Xaositect - Whitepages.com
| [reply] |
|
Wow, thanks very much for this reply! Much to chew on.
First, I ran Perl2Exe on my code, and then fired up Wordpad to look at the file. Happily, I didn't see anything that looked like Perl source code. And, when I searched for the one text string that I want to protect, I didn't find it. So, while this is probably not encrypted in the classic sense, it seems sufficiently obscured that it meets my need.
I like your idea of writing a 'glue' script that would provide a CLI interface. I can see how to pass paramters into this (just by putting them on the command line following the name of the glue script .exe file). But how can I receive multiple return values back (or can I)?
Thanks
tl
| [reply] |
|
Aww shucks, that adds at least 30 seconds to the time it takes to look at your plaintext perl script... Look here
| [reply] |
|
my $returncode = system('bar.exe some params');
I think there are some rather harsh range limitations on the return code as well.
That's probably not going to be good enough, so you're probably going to have to develop a common interface of some kind. The easiest would be to simply print to stdout, but it could be anything, like creating a file, or inserting into a database, or whatever.
my $stdout = qx("bar.exe some arguments");
Watch out for the fact that command-line arguments are processed differently depending on how many arguments you pass to the system or qx call.
Xaositect - Whitepages.com
| [reply] [d/l] [select] |
Re: Using Perl subroutines in a Perl2Exe exe file
by hydo (Monk) on Jun 30, 2005 at 05:41 UTC
|
You might consider using PAR to build your executable. It would solve the problem with including IPC::Run as it does a very good job of scanning dependencies and including them in the exe. You would still have to figure out a way to obfuscate bar.pm though.
Still, it's one problem potentially solved.
Later...
But, when I turn bar.pm into bar.exe, how then can I call bar's subroutines (passing multiple input values and receiving multiple return values)?
Using PAR will let you build the exe off of foo.pl. PAR will recursively scan your script and all of the dependent modules, including your bar.pm file, and bundle them up.
Unless I'm completely missing something funky that you are trying to do, if it works when run from the script, ie "perl ./foo.pl" it will work in PAR with a simple "pp -o foo.exe foo.pl"
| [reply] |
|
| [reply] |
|
Great stuff! Thanks VERY much! I used PAR's pp program to build an .exe, and this .exe (unlike the ones produced by Perl2Exe and PerlApp) worked great on my development system!
But then, I copied this .exe to another system (one without Perl) and ran it. It died, with:
E:\>foo.exe
: Win32::Process::Create() at IPC/Run.pm line 2097
: Win32::Process::Create() at IPC/Run.pm line 2216
: Win32::Process::Create() at IPC/Run.pm line 2216
A Perl guru in another place had told me that this indicates IPC::Run-spawned processes could not locate Perl at run time; he directed me to add:
# BEGIN { $^X = 'C:\Perl\bin\perl.exe' }
to my program. This worked, as long as there was a perl.exe file at that location. Since my 'other' system does not have any Perl installed, that file didn't exist.
I guess I had ASSumed that PAR/pp provided Perl. Not so? If not, can I just bundle perl.exe into my .exe file, and have it work?
Thanks!
tl
| [reply] |
|
I don't have a PC to test it on at the moment, so I can't tell you exactly where it is, but I do know two things:
1. There *is* a copy of the interpreter bundled by default in PAR exe files.
2. You can create your PAR exe, then unzip it with whatever you use for .zip files, and look at the directory structure. As I understand it, and hopefully someone will correct me if I'm wrong, the cwd when the .exe file is running will the the top level of that directory structure. You should then be able to modify that BEGIN line with the relative path of the interpreter and make it work. Well, that and taking out the "#" that's making it a comment. :)
Again, I can't test this but I think it should work or at least put you on the path to.... errmm.... workitude?
| [reply] |
|
|