Thice Security

De Star 6, 1601 MH Enkhuizen
Thice Security

Perl2Exe back to Perl – 2014

12/08/2014, by Thice, category Code, Malware

Two years ago I published my Perl2Exe back to Perl article in Digital Forensics Magazine, more information can be found in my post here. Since I published this article in a magazine I was not allowed to post it on my own website as well, but since enough time has passed I am now allowed to publish the full article which can be found below.

Reverse engineering Perl2Exe back to Perl


Perl2Exe is a program which converts Perl source code to standalone Windows executable files which hide the Perl code. When a forensic investigator encounters a Perl2Exe program (for example malware) it can take a lot of effort to analyse these files. This article describes a new and easy to follow approach to recover the full Perl source code from these Perl2Exe executable files, making the analysis of these files much easier.



The Perl2Exe program is published by IndigoStar which can be found online at The best way to describe Perl2Exe is the following quote from the IndigoStar website:

Perl2Exe is a command line program for converting Perl scripts to executable files.

This allows you to create stand alone programs in Perl that do not require the Perl interpreter. You can ship the executable files without having to ship your Perl source code.

Source: (17-06-2012)

Perl2Exe converts the source code of the Perl script by packing it inside a single executable together with a Perl interpreter. The Perl source code is included inside the executable in encrypted form and thus it cannot easily be recovered from the executable.

In the past there have been a couple of other projects to retrieve the Perl source code from Perl2Exe executable files (see list at the end of this article). However, none of these projects work with the current versions of Perl and Perl2Exe. In the past couple of years there have been a number of Perl2Exe versions released (see list at the end of this article) and each new version seems to break the previously found solutions to recover the Perl source code.

The two approaches to recover the Perl source code described in this article have been tested successfully against Perl2Exe version v8.82 and higher, up till the latest version at this moment (v11.00). More details on the compatibility with the Perl and Perl2Exe versions can be found further on in this article.



The different Perl versions and Perl2Exe program versions have been tested on multiple Microsoft Windows versions including Windows XP (32-bit) and Microsoft Windows 7 (64-bit) virtual machines as well as live machines. The small and simple test Perl code used for this project is shown below:


Creating Perl2Exe executable files is as simple as running the program with the Perl source code file as an argument, for example:

After running the Perl2Exe program an executable is created from the Perl source code, in this example that executable would be Example_code.exe, and the output of this executable is shown below:

How a Perl2Exe generated program works


The newly created Perl2Exe executable contains the encrypted Perl source code as well as a Perl interpreter. To be able to run the Perl script the Perl2Exe executable needs to launch the Perl interpreter first. A simplified schematic overview of the involved steps is shown in figure 1.


Figure 1 – Overview of Perl2Exe components

To launch the Perl interpreter it is unpacked and stored on the local hard drive by the Perl2Exe executable. The file locations where the Perl interpreter file is stored are shown below:

Windows XP / 2000 / 2003:

Windows Vista / 7:


In both file locations the #### part of the directory name is the process ID number the program is running under, which changes each time the Perl2Exe executable is executed. As soon as the Perl2Exe executable finishes running, the temporary directory will be removed again from the system.

The file that the Perl2Exe executable will write to the temporary directory is named p2x####.dll, the #### part of the filename consists out of three or four digits which refer to the Perl version the Perl interpreter uses. For example the file p2x5142.dll is the Perl interpreter for Perl version 5.14.2 and the file p2x588.dll is the Perl interpreter for Perl version 5.8.8.

The Perl interpreter DLLs written to the temporary directory are packed with the UPX packer, however they can easily be unpacked with UPX as well as can be seen below:


After unpacking the DLL file it can be easier analysed with tools such as IDA ( However that is not the approach we will follow in this article because these DLL files only contain the Perl interpreter and in this case we are interested in the Perl source code.

After storing the Perl interpreter DLL file in the temporary directory the Perl2Exe executable will load it so it can run the Perl script. The Perl script is included in the Perl2Exe executable, but not within the Perl interpreter, the Perl source code is only loaded in to the memory and not written to the local hard drive.


Recovering the Perl script source code

Since the Perl script source code is not written to the hard drive we need to find a way to recover it in a different way. Luckily the Perl interpreter contains code to store certain kinds of other files to the local hard drive in the same temporary directory as the Perl interpreter is stored in. We are going to use this feature to our own benefit and let Perl2Exe do the hard work for us. We can adjust the program code of the Perl interpreter with some small changes so that it will also write the Perl source code to the temporary directory. The Perl interpreter checks which kind of files it reads from memory and if these kind of files need to be stored in the temporary directory. We will adjust the flow of this piece of program code so that it will also write the Perl source code to the temporary directory. A very basic schematic overview of the theory behind the changes to the Perl interpreter is shown in figures 2 and 3.

The original flow of a small part of the Perl interpreter:



Figure 2 – Original flow of a small part of the Perl interpreter


The adjusted flow of a small part of the Perl interpreter:



Figure 3 – adjusted flow of a small part of the Perl interpreter


In the schematics above the Perl script source code would originally not be written to the temporary directory, but after changing the flow of the program it will be.

The adjustments we are going to make to the code are only meant to retrieve the Perl script source code and not to have the program continue in a normal way. Since we adjust some of the program code it can easily become unstable or give an error later on. However, since we are making changes to a temporary file the changes will be gone as soon as the program ends and the temporary directory is removed again. Note: the approach described in this article executes the Perl program, which in case the executable is malware means that this malware is executed on the local system. Be careful and always analyse unknown files in a controlled lab environment such as a Virtual Machine.

To make the proposed adjustment to the program code of the Perl interpreter we will make use of the debugger OllyDbg ( The first step is to load the Perl2Exe executable in OllyDbg, to do so we start OllyDbg and then use the following menu option to load the Perl2Exe executable file:



After the file is loaded we will scroll to the top of the page and then scroll down till we find the string RunPerl, after clicking on this line we will press F2 to set a breakpoint, after doing so the address in front of this line will turn red as can be seen in the screenshot in figure 4.


Figure 4 – OllyDbg screenshot of RunPerl location


The breakpoint we have just set will pause the execution of the Perl2Exe executable at the moment it already has extracted the Perl interpreter to the temporary directory but before this interpreter is started. This allows us to make the adjustment to the Perl interpreter as described earlier. To start the program we are analysing we need to press the play button in the shortcut bar or press the F9 button, both will start the program which will then run and pause at our newly created breakpoint.

After we hit our breakpoint it is time to switch from the Perl2Exe executable to the Perl interpreter. We can easily do this switch within OllyDbg by using the following steps. We need to launch the Executable modules window which we can do by clicking on the light blue square with the E in it on the shortcut bar or by pressing the key combination Alt+E. Within the newly opened window we will see the .exe and .dll files which are loaded by the running program. We will quickly notice that one of these files is the Perl interpreter DLL file which is stored in the temporary directory. This is the file we want to open and we can do this by double clicking it. As soon as this is done we will be looking at the assembly code of the Perl interpreter.

Finding the specific location of the code we want to change can be quite a lot of work, but since this work already has been done by me we will use a simple trick to find this location instead. The trick we will use is to search for a specific unique string which will bring us right to the location where we need to make a small adjustment.

To be able to search for strings in OllyDbg we need to bring up the Text strings window which can easily be done by clicking the right mouse button somewhere inside the main OllyDbg window and select Search for and then select All referenced strings. The screenshot of this action is shown in figure 5.


Figure 5 – Overview of ‘All referenced strings’ command location


The window that is opened shows a lot of text strings in the Perl interpreter file, don’t be alarmed by this, we are only interested in a specific string which we will search for. To open the search window we need to click the right mouse button and select Search for text or press the key combination Ctrl+F.

The string we are going to look for and the code we are going to adjust is different for the Perl2Exe versions 8/9 and 10/11. We will first discuss versions 10 and 11 and then show the difference for versions 8 and 9.


Perl2Exe versions 10 and 11


When analyzing a Perl2Exe executable which is created with Perl2Exe version 10 or 11 we will use the following steps. In the search window we will search for the string P2XDLL, if the string is not found it is quite likely that the Perl2Exe version used by the executable is version 9 or older and the approach for those versions should be followed. If the string is found the Perl2Exe version is version 10 or higher and when double clicking the P2XDLL string it will return us to the Perl interpreter program code at the location that we are interested in. The part of the code we are interested in is shown in the overview below.

The part in the code overview that we want to change is pointed out by the two arrows in front of it, it is the last line before the second line with ASCII “DLL/”. The line contains a jump instruction and this specific jump (JNE, Jump Not Equal) is the location we can change to make sure the Perl source code is going to be saved in the temporary directory. We will remove this jump completely from the code by changing it to NOP (No Operation) instructions, which will do nothing and make sure the code continues after it. To make this change will just need to double click the line with the JNE in it and then change the text in the small pop-up window to NOP, after clicking Assemble we can Close the pop-up. The resulting code after doing this is shown below.


At this moment the program will write all the files it comes across to the temporary directory including the Perl source code we are after. However, after the program finishes the whole temporary directory will be removed again from the system which means we lose all the files again including the Perl source code. To avoid this we will need to set a breakpoint in the program to make sure we can recover the files before the program finishes. We will set the breakpoint in the program right after the creation of the temporary files, the location to do this is shown in the code overview below. To set the breakpoint we need to select this line (the one with ADD ESP, 18) and press the F2 button.

With this breakpoint set we are now ready to start dumping our files to the temporary directory. To start doing this we will need to continue the program which we still got on pause, this can be done by pressing F9 (or using the play button in the shortcut bar). Because of our breakpoint the program will pause after each file creation, but every time we press the F9 button a new file will be created in the temporary directory. After a couple of F9s we will see that a file with the name is created, which is the file which contains the full Perl source code that we are after. Make sure you copy this file from the temporary directory to another location because when the program finishes this directory will be removed again.

Now you got the full Perl source code which should make the analysis of this executable file a lot easier and you probably saved you a lot of time with this quick reverse engineering trick.


Perl2Exe versions 8 and 9

When the P2XDLL string from the previous approach cannot be found it is quite likely that the executable was created with an older Perl2Exe version, for example version 8 or 9. In that case we need to follow a couple of different steps to recover the Perl source code. In the search window we will search for the string .pll which we will then double click to return to the program code of the Perl interpreter, this will land us close to the line we need to adjust. The part of the code we are interested in is shown in the overview below, the line we need to adjust is pointed out with the arrows in front of it.

Because of the flow of the program of this Perl2Exe version we cannot simply remove this jump instruction but we need to change it so that the jump is going to a different destination. The jump destination that we need can be found in the last jump instruction (JNE) before the line containing the ASCII .pll” string we saw before. The exact location can be found in the program code below.

To change the previous jump to this new destination, we need to double click the JNE jump instruction beneath the ASCII “p2x” string and adjust the jump instruction so that it points to the new location we just identified (the one above theASCII “.pll”line). We will change the jump from a JNE (Jump Not Equal) to a normal JMP (Jump) so that all the files will be dropped by the program including the Perl source code that we are after. Because the assembly instruction for this jump is a different size as the instruction we are changing we need to make sure that the option Keep size in OllyDbg is not selected as can be seen in figure 6.


Figure 6 – OllyDbg jump adjustment screen


After changing the jump we need to set a breakpoint to make sure our dumped Perl source code does not get removed when the whole temporary directory gets removed by the program. The breakpoint for this version is quite simple since it will suffice to put the breakpoint on the instruction we just changed (press F2 to set this breakpoint). The changed code and breakpoint location are shown in the code overview below.

After continuing the program (press F9) the program will start writing the different files to the temporary directory and return to the breakpoint every time it has done so. After a couple of F9 presses the file will appear which will contain the full Perl source code that we are after. Once again, make sure to copy this file to a different directory so that you do not lose it when the temporary directory is removed.



With a little bit of hands-on reverse engineering we were able to recover the full Perl source code out of a Perl2Exe executable. This Perl source code will make it a lot easier to analyze the file. What is even better is that the Perl source code also includes any comments that might have been included by the author. Before having to use this approach in a running investigation it might make sense to practice a bit in performing the different steps. Executable files which can be used for this can be found on the website in the links section, all of these executable files will be harmless for the system they are used on.

Quick action list

This is a short reminder list to recover the Perl source code:

  • Open Perl2Exe executable in OllyDbg
  • Set breakpoint on RunPerl
  • Run Perl2Exe executable within in OllyDbg
  • Switch to Perl interpreter DLL file
  • Go to Text strings window
  • Search for PX2DLL or .pll depending on the version and double click it
  • Change jump for specific Perl interpreter version
  • Set breakpoints against removal of the files
  • Continue program
  • Retrieve Perl source code from temp directory


Test files

Online test files for different Perl2Exe versions can be found at:


Links to software mentioned in this article:

Past projects

The following projects have been published in the past with the same goals as this article. However none of them work with the current Perl and Perl2Exe versions:



The approaches described in this article have been successfully tested against multiple different Perl2Exe versions, Perl versions and platforms including:

  • Windows 2000, 2003, XP, Vista and 7 (32-bit and 64-bit)
  • Perl2Exe versions 8, 9, 10 and 11
  • Strawberry Perl versions v5.8.8.4 till v5.14.2
  • ActivePerl version
  • IndigoPerl version V9.02

The following Perl2Exe versions have been released over the years:

  • Perl2Exe V11.00, released Mar 10, 2012
  • Perl2Exe V10.40, released Jun 25, 2011
  • Perl2Exe V10.10, released Feb 3, 2011
  • Perl2Exe V9.110, released Dec 7, 2009
  • Perl2Exe V8.82, release Aug 21, 2007



  1. aedahh |

    Thanks for posting this very interesting article.
    I was looking for way to decompile a perl exe that I have compiled with IndigoStar Perl2Exe (version unknown) in 2007 and end up here.
    I am stuck at finding the break point: search for P2XDLL or .pll both returned item not found.
    Appreciate if you could provide some additional guidance or I can post my perl exe if needed.

    Thanks in advanced

  2. Carlos |


    I tried to follow your instructions which seem fairly straight forward, but I am visually impaired and unfortunately OllyDbg is not fully accessible with my screen reading software. I was wondering if you wouldn’t mind looking at this executable
    and extracting the source for me. I would greatly appreciate your assistance.

    Thanks and regards.

  3. Carlos |

    For the record, as you can see here on Softpedia,
    the gentleman who wrote this program intended for it to be open source. Unfortunately, he passed away a few years ago
    so the source code is not available. He was a blind programmer and he wrote this MIDI drum machine to be accessible with screen readers for the blind. I thought I would teach myself Perl and take a shot at adding some improvements, but I always learn better from examples than manuals or text books alone.

  4. Thice |

    Hi Carlos, I will look a bit further in to this file. I quickly recovered the file, however that did not include the real code of the program as can be seen below:
    package main; # just the main program instanciating the Windows GUI.
    use strict; use warnings;
    use SeqGUI;
    my $ui = SeqGUI ->new();

    I will look in to recovering the SeqGUI code.

  5. Thice |

    The Perl2Exe DLL file in the executable you supplied is p2x586.dll, and in this version the search for .pll will work. I was able to recover the source code of the project by changing the following code:

    CPU Disasm
    Address Hex dump Command Comments
    280935E4 |. 75 1E |JNE SHORT 28093604


    CPU Disasm
    Address Hex dump Command Comments
    280935E4 /E9 36010000 JMP 2809371F
    280935E9 |90 NOP
    280935EA |90 NOP
    280935EB |90 NOP

    If you follow the tutorial carefully you will be able to do the same.

  6. Ben |

    Thank you! This tutorial has been a lifesaver. I took over a project at work where I have about 150 compiled perl exe’s that need updating. The person that wrote them was let go, but he stored the original source on his laptop that IT has already repurposed. I have recovered the source on about half of them. It appears that somewhere along the way, he switched from perl2exe to perlapp. I have been combing through a disassembler on those exe’s and perl516.dll, assuming that it has the same check to write to a file or be placed in memory, but can’t seem to identify the logic flow. Do you have any tips or by chance know a way to dump the source from an exe compiled in perlapp?

  7. Jaime |

    difficult to find that RunPerl… stuck at that point….

  8. Arunkumar A |


    I followed the steps and I was Stuck at finding the “JNE”. I cannot find the “jne” in my exe. What am I missing?. I dont know the perltoexe version. But the dll name is p2x588.dll.

    Awaiting your reply.

So, what do you think ?