Home > Code, Malware > Perl2Exe back to Perl – 2014

Perl2Exe back to Perl – 2014

August 12th, 2014 Leave a comment Go to comments

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.

Perl2Exe

 

The Perl2Exe program is published by IndigoStar which can be found online at http://www.indigostar.com/. 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: http://www.indigostar.com/perl2exe.php (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.

Setup

 

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.

ThB_Perl2Exe_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 (http://www.hex-rays.com/products/ida/index.shtml). 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:

 

ThB_Perl2Exe_Figure_2

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

 

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

 

ThB_Perl2Exe_Figure_3

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 (http://www.ollydbg.de/). 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.

 ThB_Perl2Exe_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.

 ThB_Perl2Exe_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 n.pl is created, which is the main.pl 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.

 ThB_Perl2Exe_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 _main.pl 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.

 

Conclusion

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

Links

Test files

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

Software

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:

 

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 5.12.4.1205
  • 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

Source: http://www.indigostar.com/perl2exe.php

  1. aedahh
    October 29th, 2015 at 00:18 | #1

    Hello,
    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. Thice
    November 18th, 2015 at 15:10 | #2

    Please send me the EXE file to check.

  3. aedahh
    February 22nd, 2016 at 18:51 | #3

    Hello, I was hoping that I will not need to continue with that project, but looks like I will need to do some update for newer OS with this test script.
    I have upload file to Dropbox, url here https://www.dropbox.com/s/d8psz4rel2kof4j/xpPrint3.zip?dl=0
    Thanks

  4. Carlos
    March 21st, 2016 at 16:11 | #4

    Hello,

    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
    http://homeserver.pcanywhere.net:8080/Public/drums.exe
    and extracting the source for me. I would greatly appreciate your assistance.

    Thanks and regards.

  5. Carlos
    April 11th, 2016 at 05:49 | #5

    For the record, as you can see here on Softpedia,
    http://www.softpedia.com/get/Multimedia/Audio/Other-AUDIO-Tools/Beats-Me.shtml#download
    the gentleman who wrote this program intended for it to be open source. Unfortunately, he passed away a few years ago
    http://www.webbie.org.uk/Veli-Pekka/accessibility.html
    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.

  6. Thice
    April 11th, 2016 at 19:14 | #6

    @Carlos
    Hi Carlos, I will look a bit further in to this file. I quickly recovered the main.pl 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();
    $ui->addTracks();
    $ui->addSteps();
    $ui->addPatternButtons();
    $ui->addSong();
    $ui->addSongButtons();
    $ui->addSlider();
    $ui->addMenus();
    $ui->addHotkeys();
    $ui->run();
    —————————————-

    I will look in to recovering the SeqGUI code.

  7. Thice
    April 11th, 2016 at 19:24 | #7

    @aedahh
    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

    To:

    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.

  8. Caarlos
    April 11th, 2016 at 23:53 | #8

    Thanks Thice. I appreciate the assistance.

  9. Thice
    April 12th, 2016 at 15:38 | #9

    @Caarlos
    Hi Carlos, check your email 🙂

  10. Ben
    January 11th, 2017 at 13:43 | #10

    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?

  1. September 2nd, 2014 at 21:08 | #1