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

Monks-

I've been learning to use the PAR-Packager (pp) command to build a windows executable of a simple test perl script, and it seems to be working great!

Next, I've learned about how to use PAR::Filter::Bleach (to remove all those unsightly printable characters from the source), and it works great too!

Now, I'm trying to use PAR::Filter::Crypto (to encrypt all those pesky printable characters in the source), and it fails when I try to run the executable on a pristine windows machine.

Note that it seems to work fine on the windows PC that I created the executable on, but taking it to another windows machine, the stand-alone executable fails with the following message:

>hello

Can't load 'C:\Users\dolph\AppData\Local\Temp\par-646f6c7068\cache-7e6a9a64588de12bc2c819565104dbfdc74fb296\e20507bc.xs.dll' for module Filter::Crypto::Decrypt: load_file:The specified module could not be found at <embedded>/DynaLoader.pm line 193.

at <embedded>/PAR/Heavy.pm line 140.

BEGIN failed--compilation aborted at C:\Users\dolph\AppData\Local\Temp\par-646f6c7068\cache-7e6a9a64588de12bc2c819565104dbfdc74fb296\inc\lib/Filter/Crypto/Decrypt.pm line 39.

Compilation failed in require at C:\Users\dolph\AppData\Local\Temp\par-646f6c7068\cache-7e6a9a64588de12bc2c819565104dbfdc74fb296\inc\lib/Data/Dumper.pm line 1.

BEGIN failed--compilation aborted at C:\Users\dolph\AppData\Local\Temp\par-646f6c7068\cache-7e6a9a64588de12bc2c819565104dbfdc74fb296\inc\lib/Data/Dumper.pm line 1.

Compilation failed in require at script/hello.pl line 5.

BEGIN failed--compilation aborted at script/hello.pl line 5.

Please help me figure out what I'm doing wrong.

Thanks

-Craig

Here is the Perl test script I'm using:

#!/opt/homebrew/bin/perl use strict; use warnings; use Data::Dumper; print "Hello There...\n";
Here is the command that I use to generate the executable:
pp -v -F Crypto -M Filter::Crypto::Decrypt -o hello.exe hello.pl

Replies are listed 'Best First'.
Re: PAR::Filter::Crypto Fails
by swl (Prior) on Apr 26, 2023 at 02:49 UTC

    Your packed executable needs to include several of the dynamic libs. These can be passed using --link arguments but it can be a pain to find out which ones to add, which is where App::PP::Autolink is useful.

    It seems App::PP::Autolink does not process modules passed with the -M flag, but you an always add it to your script explicitly.

    use strict; use warnings; use Data::Dumper; use Filter::Crypto::Decrypt; print "Hello There...\n";

    This then produces the output below on my Windows machine using Strawberry perl 5.32, which indicates the zlib and libcrypto dynamic libs are needed.

    pp_autolink -F Crypto -M Filter::Crypto::Decrypt 11151848.pl DLL check iter: 1 DLL check iter: 2 DLL check iter: 3 No alien system dlls detected Detected link list: c:\perls\5.32.1.1_pdl\c\bin/zlib1__.dll c:\perls\5 +.32.1.1_pdl\c\bin/libcrypto-1_1-x64__.dll Detected alien list: CMD: pp --link c:\perls\5.32.1.1_pdl\c\bin/zlib1__.dll --link c:\perls +\5.32.1.1_pdl\c\bin/libcrypto-1_1-x64__.dll -F Crypto -M Filter::Cryp +to::Decrypt 11151848.pl
      ++swl Many thanks for your clear and concise explanation - very much appreciated!

      I'm guessing that running the resulting executable on the development machine worked because these shared libraries were already installed. Since the pristine machine didn't have them, I need to provide them as part of the exe package.

        Yes, that's correct.

        For my own dev environment I have no perls in the system path. I use the portableshell.bat script that comes with Strawberry perl to set up the environment. Testing is then a case of running the executable in a new shell.

Re: PAR::Filter::Crypto Fails
by eyepopslikeamosquito (Archbishop) on Apr 25, 2023 at 22:53 UTC
      I know this topic has historically been discussed quite a bit and I don't want to start another long discussion, but here is my high-level goal:

      The law department asked me to build an executable such that if somebody did find a way to re-create the original source code, it could be shown to a judge that it wasn't an accidental thing, but something they did on purpose.

      Building an executable with PAR without using a filter means that someone could accidentally stumble over the source code in the cache directory that is generated in %TEMP% after it is run for the first time. I felt something further needed to be done.

      Using PAR::Filter::Bleach seems to satisfy this requirement, but I thought that using PAR::Filter::Crypto would even be better. So I tried to learn about both.

Re: PAR::Filter::Crypto Fails
by LanX (Saint) on Apr 25, 2023 at 21:51 UTC
    Just a guess: it's irritating me that you mix win and *nix path delimiters.

    like ... 296\inc\lib/Filter/Crypto/...

    This might be OK on a win file-system (they don't escape with backslash) but a pure Perl loader might get confused trying to find "escaped characters" in its packaged cache.

    Maybe try switching to pure *nix paths notation and see the packer still has problems?

    Cheers Rolf
    (addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
    Wikisyntax for the Monastery

      It isn't clear to me what you are suggesting the OP could do differently here - the mixed path delimiters appear in the error messages shown, but the program and command used don't appear to introduce any of those delimiters explicitly. So while you may have identified a symptom of an underlying bug somewhere, it isn't clear to me that you have identified an error in what the OP is doing, or any course of action for them to follow.

      But perhaps I misunderstand the intent of your comment.

        • @INC - even on windows - should have / as delimiter
        • PAR is using an INC hook to load modules from memory
        • the INC-hook will load those modules based on a hash look-up
        • if backslashes are used in the string representations of paths they are interpreted as escapes

        > what you are suggesting the OP could do differently here

        • check @INC again
        • check if the same problem is also happening on linux
        • if that fails file a bug report with the crypt module

        Anyway, while this was my intent, it seems like swl already identified the problem in the meantime: --> Re: PAR::Filter::Crypto Fails

        Cheers Rolf
        (addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
        Wikisyntax for the Monastery

Re: PAR::Filter::Crypto Fails
by Anonymous Monk on May 01, 2023 at 23:47 UTC

    Par won't automatically detect DLL's that modules might call. So one way around this is use of the -x argument - which will execute your program as part of packaging to see what it loads

    What you should do is use -x and --xarg=parbuild, then in my program if the first argument is 'parbuild' I trigger a 'build' sub routine that calls and uses all the modules and performs comms etc, this helps ensure all the DLL's get used, and thus detected by par.

      That ensures all the relevant perl libraries, and their associated DLLs, are detected by Module::ScanDeps.

      However it does not tell PAR::Packer which external DLLs to load. External tools like objdump, otool and ldd are needed to find those, and are what App::PP::Autolink uses, depending on the OS.

      Use of the argument to trigger extra module loads is useful. I do the same thing with an environment variable.