Exetools

Exetools (https://forum.exetools.com/index.php)
-   General Discussion (https://forum.exetools.com/forumdisplay.php?f=2)
-   -   Reversing obfuscated and encrypted JAR file (https://forum.exetools.com/showthread.php?t=19328)

Chuck954 09-12-2019 23:27

Reversing obfuscated and encrypted JAR file
 
I have tried numerous tools and haven't found much luck. I have a program that I have pretty much cracked but not completely. A handful of options need the jar file to run and if the jar file runs it closes out the program.

The program starts java.exe and it opens the encrypted jar file and runs it. I believe it was obfuscated with proguard. It has a few classes in it that show it decrypting the stream and reading the class files. However the majority of the files inside it are encrypted and you can't tell anything. I took a dump in visualvm.exe and I can see a lot of info but nothing stands out yet. Not sure if anyone has any advice on how I might be able to decrypt the classes so I can see it?

This is the code of one of the loader files it has. All the public deobfuscation tools failed. I'm guessing since it's encrypted as well. I'm not very familiar with java yet so any pointers would help.

Thanks!

Code:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class LoaderB
  extends URLClassLoader
{
  protected LoaderB(ClassLoader parent, LoaderB prevClsLoader)
  {
    super(new URL[0], parent);
  }
 
  public void init(String[] args) {}
 
  static byte[] zip(byte[] data)
  {
    try
    {
      ByteArrayInputStream bais = new ByteArrayInputStream(data);
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
     
      GZIPOutputStream gzos = new GZIPOutputStream(baos);
     
      byte[] b = new byte['?'];
     
      int i = bais.read(b);
      while (i != -1)
      {
        gzos.write(b, 0, i);
        i = bais.read(b);
      }
      gzos.finish();
      gzos.flush();
      gzos.close();
     
      return baos.toByteArray();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    return null;
  }
 
  static byte[] load(InputStream is)
  {
    try
    {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
     
      byte[] b = new byte['?'];
     
      int i = is.read(b);
      while (i != -1)
      {
        baos.write(b, 0, i);
        i = is.read(b);
      }
      baos.flush();
      baos.close();
     
      return baos.toByteArray();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    return null;
  }
 
  public static byte[] unzip(byte[] data)
  {
    try
    {
      ByteArrayInputStream bais = new ByteArrayInputStream(data);
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
     
      GZIPInputStream gzis = new GZIPInputStream(bais);
     
      byte[] b = new byte['?'];
     
      int i = gzis.read(b);
      while (i != -1)
      {
        baos.write(b, 0, i);
        i = gzis.read(b);
      }
      baos.flush();
      baos.close();
     
      return baos.toByteArray();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    return null;
  }
 
  static byte[] crypt(Crypter crypter, byte[] data)
  {
    try
    {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      OutputStream os = crypter.getOutputStreamE(baos);
     
      os.write(data);
     
      os.flush();
      os.close();
      baos.close();
      return baos.toByteArray();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    return null;
  }
 
  static byte[] decrypt(Crypter crypter, byte[] data)
  {
    try
    {
      ByteArrayInputStream bais = new ByteArrayInputStream(data);
      InputStream is = crypter.getInputStreamD(bais);
     
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
     
      byte[] b = new byte['?'];
     
      int i = is.read(b);
      while (i != -1)
      {
        baos.write(b, 0, i);
        i = is.read(b);
      }
      baos.flush();
      baos.close();
     
      return baos.toByteArray();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    return null;
  }
}


chants 09-13-2019 15:03

If it launches a separate java.exe instance, can just look at the command line and see where the jar file is located and grab it?

The code above does not contain crypter which does the encrypt/decrypt, though its doubtful needed since you will use java and this class to do the work anyway. But also we do not see the loader which actually "executes" the "jar" file.

Otherwise, either check for process functions which invoke JVM java.exe or look for code along the lines of:
Code:

// Create a new JavaClassLoader
ClassLoader classLoader = this.getClass().getClassLoader();

// Load the target class using its binary name
Class loadedMyClass = classLoader.loadClass(classBinName);

Then you can also trace how the class is processed before loading if you want the jar in case it is not invoked by java.exe but instead by dynamic loading. Check more topics on dynamic loading for more info.

Chuck954 09-13-2019 21:47

Thanks for getting back. I know exactly where the jar is and in IDA I can see where it gets the command line info to launch java and the jar file. I can use a tool like APImonitor to see it load java and what APIs are called.

When I extract the JAR contents it has two folders

META-INF which has maven, a services folder and lib folder.

Second folder starts with VN and has the class files. I've seen it mention VNcrypt a few times.

Uploaded a screenshot of the VN folder with these files.

It has 5 .class.
LoaderNoWait.class
LoaderJfx.class
Loader.class
LoaderB.class
a0.class

Then it has 19 .clasz files

a1.clasz
a2.clasz
a3.clasz
through
a17.clasz
a27.clasz
a36.clasz

In the first folder with the META-INF and VN folder, it has around 35,000 files. I took a screenshot of some of them. All look like that.

https://imgur.com/mjrlApo

https://imgur.com/wutVgq6


I believe I can change the command line that loads java and the jar file if needed. Thanks for your time!

Chuck954 09-27-2019 20:52

I have made some progress with it and found a decent Java debugger that allows me to step through code and pause it as it decrypts and unzips the classes. I used a hex editor and found the class starts when I see CAFE BABE in the memory. It's kind of a pain to figure out what's the complete class or just part of it as well as where it ends.

Anyone have any suggestions on how to intercept the Java byte-code in the memory without painstakingly searching through memory.

At the moment I'm just trying to get all the byte code for the encrypted classes and see what I'm working with.

sendersu 09-29-2019 18:54

whats the name of "a decent Java debugger that allows me to step through code and pause it "

never seen such a tool before to be honest...
is it a kind of super tool for .net - dnSpy?

Chuck954 09-29-2019 20:59

Well perhaps "step through code" is a bit of a stretch since I don't have original source, although I have managed to get several of the decrypted byte code classes from memory. I can set a breakpoint as each class is loaded and it pauses after each decryption so I can get the decrypted byte code in memory

I have only been studying Java for a few months and so still learning quite a bit. I found a newer version of jdebug with a 30 day trial. However the authors domain expired. I found an earlier version with a crack below. It's not perfect and kind of cumbersome but it allowed me to view the stack and a lot of different data. There was another one but I forgot the name at the moment.


https://webscene.ir/tools/show/JDebugTool-and-crack-v4.1.1

sendersu 09-30-2019 02:14

wow, this tool is from 2008, does it really capable of debugging nowadays javas?
2) it is pass locked

Chuck954 09-30-2019 04:56

Woops sorry. Password is www.webscene.ir
The newer version is much more streamlined but it did surprisingly work well for me. It's got a lot of options. I had been using javasnoop but it just never worked right.

If I get some time I'll try and figure out how the newer version stores the 30 day trial countdown and see if I can easily bypass it.

Chuck954 10-11-2019 10:04

Ha! Finally did it!!! I found a class dumper on github that actually worked after modifying and figuring out the crappy instructions. Ended up modifying the source code a bit and after a couple days I got it working. It dumped 96 encrypted classes that were encrypted then obfuscated. This seriously worked better then I could have ever Imagined. I've spent several days now working with the byte code and made huge progress. Considering I've never worked with Java, I am very pleased with the results. I still have a ways to go but since I expected modifying the poorly converted byte code to be the issue, I am excited with my progress. Been working on this since May... I am willing to release the modified source code I used if anyone's interested. I've invested a lot of time in decrypting the proguard Java obfuscation my target uses.


All times are GMT +8. The time now is 04:06.

Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX