Sunday, December 14, 2014

Unpacking Launch4j 3.5: Extracting The Jar File


Unpacking Launch4j 3.5: Extracting The Jar File:

Welcome to this short tutorial for unpacking Launch4j. Launch4j is a Java executable wrapper for Windows which makes the process of deploying a Java application on windows a little less arduous. It bundles the Java application with all of its command line arguments into a single executable and passes itself directly to the java runtime or "java.exe" upon execution. The goal of this tutorial is to show you how to recover/extract/unpack the original jar file and retrieve the command line arguments from the executable. While most protection detecting utilities do not detect launch4j, it is quite easy to identify this wrapper by using string references to find the string 'Launch4j'.

The application we will be working with is the demo project included with Launch4j called SimpleApp. It is located in the Launch4j installation directory in the folder '%Launch4j%\demo\SimpleApp\'. To begin, we will open our file 'SimpleApp.exe' in LordPE and click the sections button. This window will allow us to determine the Raw Offset and size of the resource section which usually has the name '.rsrc'.   

 As we can see in the picture, the raw offset is '6000h' and its raw size is '1C00h'. The jar file is always located directly after the end of the last section and spans all the way until the end of the file, so '6000h + 1C00h= 7C00h'. This means that 7C00h is the raw offset of the Jar file. Let's open the application up in winhex to verify.


As you can see here, we have reached the beginning of the Jar archive which is indicated by the 'PK' file type identifier. As stated above, the end of the archive will be the last byte in our file. In order to make sure we select everything correctly, we need to mark this offset as the 'beginning of block' through the right click menu.


Once you have done this, we can simply scroll to the last offset and mark it as the 'end of block'. 


This will automatically select all of the bytes in our archive and allow us to extract and save them as another file. To do this, right click the selection and click the 'Edit' button.











From here, another menu will appear. Go to the option 'Copy Block' and in the sub-menu, click 'Into New File'.























Afterwards, a save dialog will appear. In this example, I decided to name the file 'SimpleApp2.jar'.

























After clicking save, let's run our extracted file and see the results.





















As you can see, our extraction was successful and the file runs correctly, so our work is done. 

While this file runs correctly as is, in some cases, the author may pass additional command line arguments to the java runtime. If we do not recover these parameters, some applications may not run correctly.  To do so, we can open the original file in ollydbg and set a breakpoint on the API CreateProcessA. After running the application, we will shortly break here and we can read the arguments off of the stack. Below, we can look at the following example from another target.








In this example, we can can see that application is passing the parameters -Xms256M and -Xmx800M which tells the application the minimum and maximum ram amount to allocate to the process. Without these parameters, the application may not have the ram it requires to perform certain tasks. That is why it is crucial to recover these parameters to insure that the extracted jar will work correctly. 

Another approach to recovering these parameters would be to search for them with a resource editor. While this approach may not be as reliable as the one above, it may be best when working with malicious code.



















In this example, I was able to find the parameters stored in the RC Data directory of the resource table. 

I hope that you were able to walk away with some new knowledge. If there is something that you are not quite able to grasp or understand, please feel free to post your questions or comments below. Until next time, happy reversing.

8 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. i guess looking at the source code, especially the resource.h (which details what the resource id's are) was overlooked? and why would a protection scanner detect this? its hardly a protection is it? ill add in detection for it anyway

    ReplyDelete
  3. Oh, I am glad that you noted that there was extensive information about the resources in the source code documentation. I never took the time to download and review it. A detection for this would be nice in a standard pe info tool to let an individual know that this is just a java app disguised as an executable. Thank you for your hard work and for taking the time to comment on this. :)

    ReplyDelete
  4. its just a java -> exe kind of wrapper isnt it? i guess with a bit of extra stuff like splash screens and commandline stuff, i didnt look at the code in much detail though, but i'll add it in as detectable, shouldnt be too hard.. not sure it'll make it for the christmas release though as i have a ton of bugs to fix for that and time is ticking away

    ReplyDelete
  5. Scanning -> C:\temp\launch4j\demo\SimpleApp\SimpleApp.exe
    [Hash] MD5 (16) -> 762ed272f119d0494a8d6dd7f50a0b4c
    [Hash] SHA1 (20) -> 62357ee5b9ea6226dff821350357f66d576847a8
    [Hash] SHA256 (32) -> 345ea4ce0c8217159331274291264ff54c016dc25ed7b7942f76fc5416634542
    [Hash] SHA384 (48) -> b745c302072fab51b8b4d2230e7a94abc0a63364de89a460f7de093640ea7073385c46a4d852bac6b4fa9fdd9d0a21bd
    [Hash] SHA512 (64) -> 1283d68ef747e2baf422a544a2dac86ff0da51f4207732ee162a3e04a62470c30b14a87a6e66bad1338decd8f6ce96543d9ac82d51eb518b7f6254e5bf2c2e42
    [Hash] CRC32 (04) -> 26696926
    [Hash] ADLER32 (04) -> 93fd7457
    [Hash] FNV (04) -> e07068d7
    - Hashing Took : 0.0 Second(s) [000000000h (0) tick(s) (8 function(s)) (0.0 byte(s)/s)]
    File Type : 32-Bit Exe (Subsystem : Win GUI / 2), Size : 36332 (08DECh) Byte(s)
    Compilation TimeStamp : 0x5436EB73 -> Thu 09th Oct 2014 20:09:23 (GMT)
    [TimeStamp] 0x5436EB73 -> Thu 09th Oct 2014 20:09:23 (GMT) | PE Header | - | Offset: 0x00000088 | VA: 0x00400088 | -
    -> File has 4984 (01378h) bytes of appended data starting at offset 07A74h
    [ZoneIdentifier] 3 -> INTERNET
    [File Heuristics] -> Flag #1 : 00000000001001001101000000100100 (0x0024D024)
    [Entrypoint Section Entropy] : 6.10 (section #0) ".text " | Size : 0x4788 (18312) byte(s)
    [DllCharacteristics] -> Flag : (0x0540) -> ASLR | DEP | NOSEH
    [ImpHash] -> 5c015bd7e84af79e092e9447b444a0b6
    [SectionCount] 6 (0x6) | ImageSize 0x14000 (81920) byte(s)
    [DataDirs] Total: 16 | Processed: 16 | Empty: 14 | SizeOnly (strange): 0 | VAOnly (strange) : 0
    [DataDirs] Valid: 2 | Invalid: 0 | IMPS | RSRC
    [!] Launch4j detected !
    [ExtraInfo] Id: 2 (0x2) (JAVA_MIN_VER) | Size: 6 | -> 1.6.0
    [ExtraInfo] Id: 4 (0x4) (SHOW_SPLASH) | Size: 5 | -> true
    [ExtraInfo] Id: 5 (0x5) (SPLASH_WAITS_FOR_WINDOW) | Size: 5 | -> true
    [ExtraInfo] Id: 6 (0x6) (SPLASH_TIMEOUT) | Size: 3 | -> 60
    [ExtraInfo] Id: 7 (0x7) (SPLASH_TIMEOUT_ERR) | Size: 5 | -> true
    [ExtraInfo] Id: 8 (0x8) (CHDIR) | Size: 2 | -> .
    [ExtraInfo] Id: 10 (0xA) (ERR_TITLE) | Size: 10 | -> SimpleApp
    [ExtraInfo] Id: 17 (0x11) (WRAPPER) | Size: 5 | -> true
    [ExtraInfo] Id: 18 (0x12) (JDK_PREFERENCE) | Size: 2 | -> 1
    [ExtraInfo] Id: 20 (0x14) (PRIORITY_CLASS) | Size: 3 | -> 32
    [ExtraInfo] Id: 21 (0x15) (DOWNLOAD_URL) | Size: 25 | -> http://java.com/download
    [ExtraInfo] Id: 30 (0x1E) (RUNTIME_BITS) | Size: 2 | -> 3
    [ExtraInfo] Id: 31 (0x1F) (RESTART_ON_CRASH) | Size: 5 | -> true
    [ExtraInfo] Id: 101 (0x65) (STARTUP_ERR) | Size: 50 | -> An error occurred while starting the application.
    [ExtraInfo] Id: 102 (0x66) (BUNDLED_JRE_ERR) | Size: 115 | -> This application was configured to use a bundled Java Runtime Environment but the runtime is missing or corrupted.
    [ExtraInfo] Id: 103 (0x67) (JRE_VERSION_ERR) | Size: 53 | -> This application requires a Java Runtime Environment
    [ExtraInfo] Id: 104 (0x68) (LAUNCHER_ERR) | Size: 104 | -> The registry refers to a nonexistent Java Runtime Environment installation or the runtime is corrupted.
    [CompilerDetect] -> MinGW
    - Scan Took : 0.218 Second(s) [0000000DAh (218) tick(s)] [558 of 573 scan(s) done]

    // done

    it'll be in the christmas release.. happy holidays

    ReplyDelete
  6. Wow, that was quick. Very good work. I will happily test the beta release. I have multiple targets which use this protection.

    ReplyDelete
  7. i'll pm you a link on the other place

    ReplyDelete
  8. This comment has been removed by the author.

    ReplyDelete

Note: Only a member of this blog may post a comment.