Quick analysis about Jar2exe protection 3
Hi
Today I will show how I unpacked Jar2Exe protection 3.
I made a tool called Exe2Jar that unpack Jar2Exe protection 1 and 2. It was a school project so I didn’t look that much to the protection 3, and someone shown me an issue about the output of my program regarding protection 3. So I decided to rework on it, and implement the protection 3 support.
Exe2Jar : https://github.com/whereisr0da/exe2jar
So if you’re not familiar with Jar2Exe, know that the JAR File are stored in the Exectuable’s Resources since protection 2.
Just to prove my point, here is the original JAR File size on the left and the file size of the Encrypted RCDATA resource on the right.
We have to see how the executable handle resource.
So resources are used with functions like FindResourcesA etc… And as we can see, those functions are imported in the executable.
We just have to follow them to see where there are used. In particular the FindResourcesA that return a ResInfo handle of a given resource id. And here, we found one call that used the same id as our Encrypted JAR File resource.
This ResInfo handle is used here with the LockResource funtion that lock the resource for others thread and return the encrypted content pointer in memory. This pointer is stored in a register that will be used only one time, so we can think that the decryption process is made around here.
I will switch to pseudo code to show you a more trivial representation of the code.
I renamed some resource related objects and we can notice that the function also store the size of the Encrypted JAR File.
HMODULE = GetModuleHandleA(0);
HRESINFO_RCDATA = FindResourceA(HMODULE, 0x80, 0xA);
if ( !HRESINFO_RCDATA )
{
// ...
return 0;
}
SIZE_OR_RCDATA = SizeofResource(HMODULE, HRESINFO_RCDATA);
HANDLE_RCDATA = LoadResource(HMODULE, HRESINFO_RCDATA);
if ( !HANDLE_RCDATA )
{
// ...
return 0;
}
PTR_RCDATA = LockResource(HANDLE_RCDATA);
if ( !PTR_RCDATA )
{
// ...
return 0;
}
So like mentioned earlier, the pointer to raw crypted data is only used by one function, and the size of that data is also used by this one. So it’s an interesting one for us :)
sub_4045A0(SIZE_OR_RCDATA);
// ...
strcpy(&STRING_0, "r1g2s3r4i5h6s7_8e9u0");
// ...
sub_4110C0(PTR_RCDATA, VAR_1, SIZE_OR_RCDATA);
And its definitly look like something looping on a buffer to decrypt it. We can notice that the function iterates on a pointer in an argument that is increased at each round of the loop, loop that iterates for each byte of the encrypted data.
NOTE : I’m bad at crypto, so I’m probably wrong about my re…
sub_4110C0(DWORD *this, char *PTR_RCDATA, BYTE *OUTPUT_BUFFER, int SIZE_OR_RCDATA){
RESULT = SIZE_OR_RCDATA;
if ( SIZE_OR_RCDATA )
{
do
{
// some crypto loop calling sub_411390, possible init ...
// get the ciphered content
CRYPTED_BYTE = *PTR_RCDATA;
// some crypto loop again ...
// the decryption routine
TMP_0 = CRYPTED_BYTE - UNKNOWN_0;
DECRYPTED_BYTE = this->OFFSET_568 ^ this->OFFSET_577;
DECRYPTED_BYTE ^= TMP_0;
// update the ciphered content, with decrypted byte
*OUTPUT_BUFFER = DECRYPTED_BYTE;
// probably something linked to crypto algo
this->OFFSET_241 = DECRYPTED_BYTE ^ this->OFFSET_241;
RESULT = SIZE_OR_RCDATA - 1;
FINISH = SIZE_OR_RCDATA == 1;
++PTR_RCDATA;
++OUTPUT_BUFFER;
--SIZE_OR_RCDATA;
}
while ( !FINISH );
}
return RESULT;
}
So we are sure that this function decrypt our JAR File. And after its call, [esp+0x2AC+OUTPUT_BUFFER] will be filled with the decrypted content.
So from this, we can rush to the JAR File in memory and unpack it. But I want to understand how this function work, So I will continue to reverse it.
While I was watching the decryption code, I was thinking that it was too complex to be created by there people. They will not reinvent the wheel if the goal of this wrapper is to execute Java code.
So they probably used a library to achieve this, I look up about the strings and searched “Crypt” because in general, libraries like this leak a lot of string and patterns in the code. And I was right.
I search on google some strings and I found this old weard chinese source code
Apparently, this code is comming from an old encryption tool from 2002
Probably the main program, I don’t understand why they used this old code in the jar2exe stub
I quickly linked a string to the executable from the source code, and the function around it looks like the same code
So I renamed this function and looked around xrefs, I found a vtable and, surprise, the decryption function that we reverse earlier is in it !
So after renaming some functions, we can clearly understand the decrypt function reversed earlier
And if we come back to the place where the decryption function is called, we can see some calls to XOR256Stream’s functions, and with a little bit of analysis, we can understand what is dealt with.
// setup the CXOR256Stream object
CXOR256Stream* xor256 = new CXOR256Stream::CXOR256Stream();
// get serial string from EOF
char* serialStr = GetSerial();
char keyStr[20] = "r1g2s3r4i5h6s7_8e9u0";
// get the first 21 chars "r1g2s3r4i5h6s7_8"
char* keyStrFirst21 = SubStr(&keyStr, 21);
// add the key to the serial
char* finalKey = AddToStr(serialStr, keyStrFirst21);
// init blocks in function of key
xor256->Initialize(finalKey, strlen(finalKey), 4);
// reset blocks
xor256->ResetChain();
// decrypt the data in function of key blocks
xor256->Decrypt(PTR_RCDATA, DECRYPTED_PTR, SIZE_OF_RCDATA);
So as we can see, the XOR256Stream class is initialised with a key and a round number (4), so only thing we have to get to decrypt the JAR File is the key.
The code above shows that it grabbe the “serial key” of the jar2exe customer stored after the PE EOF (but it’s definitely looking like a timecode), and add it a string cut at the 21th char.
From this we just have to get the serial key and use it to decrypt the JAR File and we are done about the unpack !
I coded a little C++ program that does this stuff like the Jar2Exe stub
And we have decrypted the JAR File !
If you don’t know it, JAR Files are ZIP Files that contain CLASS File that contain the Java bytecode.
And about that we have only one problem, names in the JAR File are randomized, so we have to reconstruct the archive like a normal JAR File.
So we have just to rename decrypted files to reconstruct the original archive.
Example of JAR File :
First the main file of JAR File that indicate the Entrypoint CLASS : MANIFEST.MF
In my case it’s the b5f78a55 file
We can see that the Main-Class is “testapp.TestApp”
So we know that there is a namespace/package called “testapp” and a class named “TestApp”.
For each package, we will create a directory, and place each class in its own directory.
And rename the b5f78a55 to MANIFEST.MF and put it in a META-INF directory
We have only one file left, it’s probably the CLASS File.
Each class file content its path in the program (package + class name), so we just have to disassemble the Java class to get this one (you can use a decompiler but some don’t want to load renamed classes).
So now we have the file class name and path !
We just have to apply it to the folder and recompress the archive and rename the zip to jar.
And voila :0
Conclusion
It was not very hard, but I was lucky to find the crypto lib.
I will implement the protection 3 support in my tool, but Java is not that friendly regarding crypto (not unsigned values etc…) so first I think I will leave the C++ program decrypt the stub. And after I will implement the crypto thing.
And don’t leave those library strings and paterns in your stub.