Research & Development
$ #

How to get a heart attack while using JEB decompiler

Author: Anonymous Duck, 15.09.2022

Once upon a time, we had to reverse engineer an Android application. To do that, we've decided to use our favorite tool of choice - JEB. All was good until we noticed something suspicious…

Method REDACTED;->g0(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V: Decrypted string: "2022.08.30"
Method REDACTED;->g0(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V: Decrypted string: "2022.08.30"
Method REDACTED;->g0(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V: Decrypted string: "15:33:24.375"

We highly doubted that our application had an encrypted string with the exact current date down to a second. It looked like facts about our environment were somehow being "leaked" into the decompilation? When you suspect some shady actions are happening, it's always a good idea to look at the process list:

htop showing JEB spawning suspicious processes


Does the application we're reverse engineering contain a JEB 0-day? Is someone actively trying to exploit us? After a short reverse engineering effort, we've located the suspect, which is a function that looks for su binary on a rooted device:

    public static String H() {
        String s = System.getenv("PATH");
        HashSet hashSet0 = new HashSet();
        String[] arr_s = s.split(":");
        for(int v = 0; v < arr_s.length; ++v) {

        Iterator iterator0 = hashSet0.iterator();
        while(iterator0.hasNext()) {
            Object object0 =;
            String s1 = (String)object0;
            if(!new File(s1 + "/su").exists()) {

            try {
                Process process0 = Runtime.getRuntime().exec(new String[]{s1 + "/su", "-c", "id"}, null, null);
                BufferedReader bufferedReader0 = new BufferedReader(new InputStreamReader(process0.getInputStream()));
                String s2 = bufferedReader0.readLine();
                if(s2 == null) {
                    return null;

                if(!s2.startsWith("uid=0")) {

                return s1 + "/su";
            catch(InterruptedException | IOException iOException0) {
                Log.i("ERROR", Utils.w(iOException0));

        return null;

The hypothesis was that JEB somehow executes this code in its runtime. To verify this idea, we've prepared a modified version of the apk file by unpacking it with apktool, patching strings, and packing the apk back up. Shortly after, we confirmed the hypothesis - indeed, JEB was executing code from the application!

htop showing Jeb spawning "better" processes

However, after opening JEB more than a dozen times in a span of 15 minutes, we've also noticed a fine print in Jeb's console log right after hitting the decompile button.

logs from Jeb while performing decompilation

Hmmm? Let's read more from JEB's website.

note from Jeb's webpage about JDK 18+

Oh. Oooooooh. That explains a lot. So JEB's "emulation" is just executing code in a sandbox. And since Java Security Sandbox doesn't work on Java 18 without an additional console flag - it executes code without any sandboxing on your host machine.

It would be nice to have this notification in a big red message box instead of small print after you hit decompile. At that point it's kind of too late. Especially when you can read this on their blog post:

fragment form JEB's blog about deobfuscators

How to avoid this problem?

Just disable deobfuscators during decompilation or use older Java.

JEB decompilation options

Special note from author:

author of this blog post after nearly getting a heart attack

Extra note: We tried to contact the PNF Software crew twice on their slack before posting this article, but they didn't respond to us.

Update 17.09.2022: The vulnerability was patched in the JEB 4.19.1, thanks to the PNF Software crew for the fast patch.