Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to decode those JD-GUI error decompiled Bytecode

I want to decompile one apk file to see some part of its source code, but when I get to the part I am intrested in, JD-GUI gives following decompiled code

  /* Error */
  public void loginV2(Context paramContext, String paramString1, int paramInt, String paramString2, String paramString3, String paramString4, AsyncHttpResponseHandler paramAsyncHttpResponseHandler)
  {
    // Byte code:
    //   0: new 20  java/lang/StringBuilder
    //   3: dup
    //   4: getstatic 91    com/ipanel/join/homed/mobile/myt/Config:SERVER_ACCESS   Ljava/lang/String;
    //   7: invokestatic 32 java/lang/String:valueOf    (Ljava/lang/Object;)Ljava/lang/String;
    //   10: invokespecial 35   java/lang/StringBuilder:<init>  (Ljava/lang/String;)V
    //   13: ldc_w 491
    //   16: invokevirtual 41   java/lang/StringBuilder:append  (Ljava/lang/String;)Ljava/lang/StringBuilder;
    //   19: invokevirtual 45   java/lang/StringBuilder:toString    ()Ljava/lang/String;
    //   22: astore 10
    //   24: new 226    cn/ipanel/android/net/http/AsyncHttpClient
    //   27: dup
    //   28: invokespecial 227  cn/ipanel/android/net/http/AsyncHttpClient:<init>   ()V
    //   31: astore 11
    //   33: new 429    org/json/JSONObject
    //   36: dup
    //   37: invokespecial 430  org/json/JSONObject:<init>  ()V
    //   40: astore 12
    //   42: aconst_null
    //   43: astore 9
    //   45: aconst_null
    //   46: astore 8
    //   48: new 20 java/lang/StringBuilder
    //   51: dup
    //   52: invokespecial 169  java/lang/StringBuilder:<init>  ()V
    //   55: aload_1
    //   56: invokestatic 300   com/ipanel/join/homed/mobile/myt/utils/DeviceUtils:getDeviceId  (Landroid/content/Context;)Ljava/lang/String;
    //   59: invokevirtual 41   java/lang/StringBuilder:append  (Ljava/lang/String;)Ljava/lang/StringBuilder;
    //   62: invokevirtual 45   java/lang/StringBuilder:toString    ()Ljava/lang/String;
    //   65: astore 13
    //   67: new 20 java/lang/StringBuilder
    //   70: dup
    //   71: aload 13
    //   73: invokestatic 32    java/lang/String:valueOf    (Ljava/lang/Object;)Ljava/lang/String;
    //   76: invokespecial 35   java/lang/StringBuilder:<init>  (Ljava/lang/String;)V
    //   79: aload 13
    //   81: invokestatic 497   com/ipanel/join/homed/helper/OperationUtils:getMD5  (Ljava/lang/String;)Ljava/lang/String;
    //   84: bipush 7
    //   86: bipush 8
    //   88: invokevirtual 501  java/lang/String:substring  (II)Ljava/lang/String;
    //   91: invokevirtual 41   java/lang/StringBuilder:append  (Ljava/lang/String;)Ljava/lang/StringBuilder;
    //   94: invokevirtual 45   java/lang/StringBuilder:toString    ()Ljava/lang/String;
    //   97: astore 13
    //   99: invokestatic 506   java/util/Calendar:getInstance  ()Ljava/util/Calendar;
    //   102: invokevirtual 510 java/util/Calendar:getTimeInMillis  ()J
    //   105: lstore 14
    //   107: aload 12
    //   109: ldc_w 294
    //   112: aload 13
    //   114: invokevirtual 435 org/json/JSONObject:put (Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
    //   117: pop
    //   118: aload 12
    //   120: ldc_w 302
    //   123: aload_2
    //   124: invokevirtual 435 org/json/JSONObject:put (Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
    //   127: pop
    //   128: aload 12
    //   130: ldc_w 469
    //   133: iload_3
    //   134: invokevirtual 513 org/json/JSONObject:put (Ljava/lang/String;I)Lorg/json/JSONObject;
    //   137: pop
    //   138: aload 12
    //   140: ldc_w 467
    //   143: aload 4
    //   145: invokevirtual 435 org/json/JSONObject:put (Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
    //   148: pop
    //   149: aload 12
    //   151: ldc_w 515
    //   154: aload 5
    //   156: invokestatic 497  com/ipanel/join/homed/helper/OperationUtils:getMD5  (Ljava/lang/String;)Ljava/lang/String;
    //   159: invokevirtual 435 org/json/JSONObject:put (Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
    //   162: pop
    //   163: aload 6
    //   165: invokestatic 112  android/text/TextUtils:isEmpty  (Ljava/lang/CharSequence;)Z
    //   168: ifne +13 -> 181
    //   171: aload 12
    //   173: ldc 99
    //   175: aload 6
    //   177: invokevirtual 435 org/json/JSONObject:put (Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
    //   180: pop
    //   181: aload 12
    //   183: ldc_w 517
    //   186: new 20    java/lang/StringBuilder
    //   189: dup
    //   190: invokespecial 169 java/lang/StringBuilder:<init>  ()V
    //   193: lload 14
    //   195: invokevirtual 520 java/lang/StringBuilder:append  (J)Ljava/lang/StringBuilder;
    //   198: invokevirtual 45  java/lang/StringBuilder:toString    ()Ljava/lang/String;
    //   201: invokevirtual 435 org/json/JSONObject:put (Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
    //   204: pop
    //   205: aload 12
    //   207: ldc_w 522
    //   210: ldc 124
    //   212: invokevirtual 435 org/json/JSONObject:put (Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
    //   215: pop
    //   216: aload 12
    //   218: ldc_w 524
    //   221: new 20    java/lang/StringBuilder
    //   224: dup
    //   225: aload 13
    //   227: invokestatic 32   java/lang/String:valueOf    (Ljava/lang/Object;)Ljava/lang/String;
    //   230: invokespecial 35  java/lang/StringBuilder:<init>  (Ljava/lang/String;)V
    //   233: ldc_w 526
    //   236: invokevirtual 41  java/lang/StringBuilder:append  (Ljava/lang/String;)Ljava/lang/StringBuilder;
    //   239: aload_2
    //   240: invokevirtual 41  java/lang/StringBuilder:append  (Ljava/lang/String;)Ljava/lang/StringBuilder;
    //   243: ldc_w 526
    //   246: invokevirtual 41  java/lang/StringBuilder:append  (Ljava/lang/String;)Ljava/lang/StringBuilder;
    //   249: iload_3
    //   250: invokevirtual 176 java/lang/StringBuilder:append  (I)Ljava/lang/StringBuilder;
    //   253: ldc_w 526
    //   256: invokevirtual 41  java/lang/StringBuilder:append  (Ljava/lang/String;)Ljava/lang/StringBuilder;
    //   259: aload 4
    //   261: invokevirtual 41  java/lang/StringBuilder:append  (Ljava/lang/String;)Ljava/lang/StringBuilder;
    //   264: ldc_w 526
    //   267: invokevirtual 41  java/lang/StringBuilder:append  (Ljava/lang/String;)Ljava/lang/StringBuilder;
    //   270: lload 14
    //   272: invokevirtual 520 java/lang/StringBuilder:append  (J)Ljava/lang/StringBuilder;
    //   275: invokevirtual 45  java/lang/StringBuilder:toString    ()Ljava/lang/String;
    //   278: invokestatic 497  com/ipanel/join/homed/helper/OperationUtils:getMD5  (Ljava/lang/String;)Ljava/lang/String;
    //   281: invokevirtual 435 org/json/JSONObject:put (Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
    //   284: pop
    //   285: new 223   org/apache/http/entity/StringEntity
    //   288: dup
    //   289: aload 12
    //   291: invokevirtual 438 org/json/JSONObject:toString    ()Ljava/lang/String;
    //   294: ldc_w 440
    //   297: invokespecial 442 org/apache/http/entity/StringEntity:<init>  (Ljava/lang/String;Ljava/lang/String;)V
    //   300: astore_2
    //   301: getstatic 448 java/lang/System:out    Ljava/io/PrintStream;
    //   304: new 20    java/lang/StringBuilder
    //   307: dup
    //   308: ldc_w 450
    //   311: invokespecial 35  java/lang/StringBuilder:<init>  (Ljava/lang/String;)V
    //   314: aload 12
    //   316: invokevirtual 438 org/json/JSONObject:toString    ()Ljava/lang/String;
    //   319: invokevirtual 41  java/lang/StringBuilder:append  (Ljava/lang/String;)Ljava/lang/StringBuilder;
    //   322: invokevirtual 45  java/lang/StringBuilder:toString    ()Ljava/lang/String;
    //   325: invokevirtual 455 java/io/PrintStream:println (Ljava/lang/String;)V
    //   328: aload 11
    //   330: aload_1
    //   331: aload 10
    //   333: aload_2
    //   334: ldc -27
    //   336: aload 7
    //   338: invokevirtual 233 cn/ipanel/android/net/http/AsyncHttpClient:post (Landroid/content/Context;Ljava/lang/String;Lorg/apache/http/HttpEntity;Ljava/lang/String;Lcn/ipanel/android/net/http/AsyncHttpResponseHandler;)V
    //   341: return
    //   342: astore 4
    //   344: aload 8
    //   346: astore_2
    //   347: aload 4
    //   349: invokevirtual 456 org/json/JSONException:printStackTrace  ()V
    //   352: goto -24 -> 328
    //   355: astore 4
    //   357: aload 9
    //   359: astore_2
    //   360: aload 4
    //   362: invokevirtual 236 java/io/UnsupportedEncodingException:printStackTrace    ()V
    //   365: goto -37 -> 328
    //   368: astore 4
    //   370: goto -10 -> 360
    //   373: astore 4
    //   375: goto -28 -> 347
    // Local variable table:
    //   start  length  slot    name    signature
    //   0  378 0   this    APIManager
    //   0  378 1   paramContext    Context
    //   0  378 2   paramString1    String
    //   0  378 3   paramInt    int
    //   0  378 4   paramString2    String
    //   0  378 5   paramString3    String
    //   0  378 6   paramString4    String
    //   0  378 7   paramAsyncHttpResponseHandler   AsyncHttpResponseHandler
    //   46 299 8   localObject1    Object
    //   43 315 9   localObject2    Object
    //   22 310 10  str1    String
    //   31 298 11  localAsyncHttpClient    AsyncHttpClient
    //   40 275 12  localJSONObject JSONObject
    //   65 161 13  str2    String
    //   105    166 14  l   long
    // Exception table:
    //   from   to  target  type
    //   48 181 342 org/json/JSONException
    //   181    301 342 org/json/JSONException
    //   48 181 355 java/io/UnsupportedEncodingException
    //   181    301 355 java/io/UnsupportedEncodingException
    //   301    328 368 java/io/UnsupportedEncodingException
    //   301    328 373 org/json/JSONException
  }

I searched web and found that maybe the reason is the apk'a author deliberately made this error to protect the critical part of the code to be decompiled by JD-GUI.

What I want to ask is

  1. Could these so called "Byte code" be understood ? I read the code , authough I am not able to understand the code completely,I think it still keep the actual code info, I found getMD5 function in the code, so could someone explain to me which parameters the code uses and how to do MD5(actually this is the part I am interested in)

  2. Could someone give me some suggestions to help me to understand such codes by myself, for example , give me some reference web links to understand the so called "Byte Code" language's specification(just like c++ or C#), so next time maybe I can do the job myself

Thanks!

ps: I tried another hex viewer , and get following result code

public void loginV2(final Context p0, final String p1, final int p2, final String p3, final String p4, final String p5, final AsyncHttpResponseHandler p6) {
        // 
        // This method could not be decompiled.
        // 
        // Original Bytecode:
        // 
        //     0: new             Ljava/lang/StringBuilder;
        //     3: dup            
        //     4: getstatic       com/ipanel/join/homed/mobile/myt/Config.SERVER_ACCESS:Ljava/lang/String;
        //     7: invokestatic    java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
        //    10: invokespecial   java/lang/StringBuilder.<init>:(Ljava/lang/String;)V
        //    13: ldc_w           "account/user/v2/login"
        //    16: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //    19: invokevirtual   java/lang/StringBuilder.toString:()Ljava/lang/String;
        //    22: astore          8
        //    24: new             Lcn/ipanel/android/net/http/AsyncHttpClient;
        //    27: dup            
        //    28: invokespecial   cn/ipanel/android/net/http/AsyncHttpClient.<init>:()V
        //    31: astore          9
        //    33: new             Lorg/json/JSONObject;
        //    36: dup            
        //    37: invokespecial   org/json/JSONObject.<init>:()V
        //    40: astore          10
        //    42: aconst_null    
        //    43: astore          11
        //    45: new             Ljava/lang/StringBuilder;
        //    48: dup            
        //    49: invokespecial   java/lang/StringBuilder.<init>:()V
        //    52: aload_1        
        //    53: invokestatic    com/ipanel/join/homed/mobile/myt/utils/DeviceUtils.getDeviceId:(Landroid/content/Context;)Ljava/lang/String;
        //    56: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //    59: invokevirtual   java/lang/StringBuilder.toString:()Ljava/lang/String;
        //    62: astore          14
        //    64: new             Ljava/lang/StringBuilder;
        //    67: dup            
        //    68: aload           14
        //    70: invokestatic    java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
        //    73: invokespecial   java/lang/StringBuilder.<init>:(Ljava/lang/String;)V
        //    76: aload           14
        //    78: invokestatic    com/ipanel/join/homed/helper/OperationUtils.getMD5:(Ljava/lang/String;)Ljava/lang/String;
        //    81: bipush          7
        //    83: bipush          8
        //    85: invokevirtual   java/lang/String.substring:(II)Ljava/lang/String;
        //    88: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //    91: invokevirtual   java/lang/StringBuilder.toString:()Ljava/lang/String;
        //    94: astore          15
        //    96: invokestatic    java/util/Calendar.getInstance:()Ljava/util/Calendar;
        //    99: invokevirtual   java/util/Calendar.getTimeInMillis:()J
        //   102: lstore          16
        //   104: aload           10
        //   106: ldc_w           "deviceno"
        //   109: aload           15
        //   111: invokevirtual   org/json/JSONObject.put:(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
        //   114: pop            
        //   115: aload           10
        //   117: ldc_w           "devicetype"
        //   120: aload_2        
        //   121: invokevirtual   org/json/JSONObject.put:(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
        //   124: pop            
        //   125: aload           10
        //   127: ldc_w           "accounttype"
        //   130: iload_3        
        //   131: invokevirtual   org/json/JSONObject.put:(Ljava/lang/String;I)Lorg/json/JSONObject;
        //   134: pop            
        //   135: aload           10
        //   137: ldc_w           "account"
        //   140: aload           4
        //   142: invokevirtual   org/json/JSONObject.put:(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
        //   145: pop            
        //   146: aload           10
        //   148: ldc_w           "pwd"
        //   151: aload           5
        //   153: invokestatic    com/ipanel/join/homed/helper/OperationUtils.getMD5:(Ljava/lang/String;)Ljava/lang/String;
        //   156: invokevirtual   org/json/JSONObject.put:(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
        //   159: pop            
        //   160: aload           6
        //   162: invokestatic    android/text/TextUtils.isEmpty:(Ljava/lang/CharSequence;)Z
        //   165: ifne            178
        //   168: aload           10
        //   170: ldc             "code"
        //   172: aload           6
        //   174: invokevirtual   org/json/JSONObject.put:(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
        //   177: pop            
        //   178: aload           10
        //   180: ldc_w           "timestamp"
        //   183: new             Ljava/lang/StringBuilder;
        //   186: dup            
        //   187: invokespecial   java/lang/StringBuilder.<init>:()V
        //   190: lload           16
        //   192: invokevirtual   java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
        //   195: invokevirtual   java/lang/StringBuilder.toString:()Ljava/lang/String;
        //   198: invokevirtual   org/json/JSONObject.put:(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
        //   201: pop            
        //   202: aload           10
        //   204: ldc_w           "isforce"
        //   207: ldc             "1"
        //   209: invokevirtual   org/json/JSONObject.put:(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
        //   212: pop            
        //   213: aload           10
        //   215: ldc_w           "signature"
        //   218: new             Ljava/lang/StringBuilder;
        //   221: dup            
        //   222: aload           15
        //   224: invokestatic    java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
        //   227: invokespecial   java/lang/StringBuilder.<init>:(Ljava/lang/String;)V
        //   230: ldc_w           "|"
        //   233: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //   236: aload_2        
        //   237: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //   240: ldc_w           "|"
        //   243: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //   246: iload_3        
        //   247: invokevirtual   java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
        //   250: ldc_w           "|"
        //   253: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //   256: aload           4
        //   258: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //   261: ldc_w           "|"
        //   264: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //   267: lload           16
        //   269: invokevirtual   java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
        //   272: invokevirtual   java/lang/StringBuilder.toString:()Ljava/lang/String;
        //   275: invokestatic    com/ipanel/join/homed/helper/OperationUtils.getMD5:(Ljava/lang/String;)Ljava/lang/String;
        //   278: invokevirtual   org/json/JSONObject.put:(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
        //   281: pop            
        //   282: new             Lorg/apache/http/entity/StringEntity;
        //   285: dup            
        //   286: aload           10
        //   288: invokevirtual   org/json/JSONObject.toString:()Ljava/lang/String;
        //   291: ldc_w           "UTF-8"
        //   294: invokespecial   org/apache/http/entity/StringEntity.<init>:(Ljava/lang/String;Ljava/lang/String;)V
        //   297: astore          26
        //   299: getstatic       java/lang/System.out:Ljava/io/PrintStream;
        //   302: new             Ljava/lang/StringBuilder;
        //   305: dup            
        //   306: ldc_w           "para: "
        //   309: invokespecial   java/lang/StringBuilder.<init>:(Ljava/lang/String;)V
        //   312: aload           10
        //   314: invokevirtual   org/json/JSONObject.toString:()Ljava/lang/String;
        //   317: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //   320: invokevirtual   java/lang/StringBuilder.toString:()Ljava/lang/String;
        //   323: invokevirtual   java/io/PrintStream.println:(Ljava/lang/String;)V
        //   326: aload           26
        //   328: astore          11
        //   330: aload           9
        //   332: aload_1        
        //   333: aload           8
        //   335: aload           11
        //   337: ldc             "text/html"
        //   339: aload           7
        //   341: invokevirtual   cn/ipanel/android/net/http/AsyncHttpClient.post:(Landroid/content/Context;Ljava/lang/String;Lorg/apache/http/HttpEntity;Ljava/lang/String;Lcn/ipanel/android/net/http/AsyncHttpResponseHandler;)V
        //   344: return         
        //   345: astore          13
        //   347: aload           13
        //   349: invokevirtual   org/json/JSONException.printStackTrace:()V
        //   352: goto            330
        //   355: astore          12
        //   357: aload           12
        //   359: invokevirtual   java/io/UnsupportedEncodingException.printStackTrace:()V
        //   362: goto            330
        //   365: astore          12
        //   367: aload           26
        //   369: astore          11
        //   371: goto            357
        //   374: astore          13
        //   376: aload           26
        //   378: astore          11
        //   380: goto            347
        //    Exceptions:
        //  Try           Handler
        //  Start  End    Start  End    Type                                  
        //  -----  -----  -----  -----  --------------------------------------
        //  45     178    345    347    Lorg/json/JSONException;
        //  45     178    355    357    Ljava/io/UnsupportedEncodingException;
        //  178    299    345    347    Lorg/json/JSONException;
        //  178    299    355    357    Ljava/io/UnsupportedEncodingException;
        //  299    326    374    383    Lorg/json/JSONException;
        //  299    326    365    374    Ljava/io/UnsupportedEncodingException;
        // 
        // The error that occurred was:
        // 
        // java.lang.IllegalStateException: Expression is linked from several locations: Label_0330:
        //     at com.strobel.decompiler.ast.Error.expressionLinkedFromMultipleLocations(Error.java:27)
        //     at com.strobel.decompiler.ast.AstOptimizer.mergeDisparateObjectInitializations(AstOptimizer.java:2592)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:235)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:214)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:99)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:757)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:655)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:532)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:499)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:141)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:130)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:105)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.buildAst(JavaLanguage.java:71)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.decompileType(JavaLanguage.java:59)
        //     at the.bytecode.club.bytecodeviewer.decompilers.ProcyonDecompiler.decompileClassNode(ProcyonDecompiler.java:120)
        //     at the.bytecode.club.bytecodeviewer.gui.ClassViewer$13.doShit(ClassViewer.java:624)
        //     at the.bytecode.club.bytecodeviewer.gui.PaneUpdaterThread.run(PaneUpdaterThread.java:16)
        // 
        throw new IllegalStateException("An error occurred while decompiling this method.");
    }
like image 227
J1B Avatar asked Jun 25 '17 02:06

J1B


People also ask

Can bytecode be decompiled?

The decompiler can not only convert bytecode to Java code, but it can also debug it. This means you can use breakpoints anywhere in the decompiled code with almost the same experience that you'd normally have when you debug your source code. Of course, you can always open the bytecode viewer for any compiled class.

Can you decompile Java bytecode?

Abstract. Java virtual machines execute Java bytecode instructions. Since this bytecode is a higher level representation than traditional ob- ject code, it is possible to decompile it back to Java source.

What is bytecode decompiler?

Java bytecode decompiler IntelliJ IDEA features the Java bytecode decompiler that shows you compiled bytecode as if it were human-readable Java code. The decompiler is enabled by default. Open a compiled . class file in the editor.


2 Answers

Ran into a similar issue trying to decompile a Java 8 file that used try-with-resources and lambdas.

After trying the following unsuccessfully:

  • JD-GUI (http://jd.benow.ca/)
  • cfr (http://www.benf.org/other/cfr/)
  • jd-cmd (https://github.com/kwart/jd-cmd)

This guy did the trick:

  • Luyten (https://github.com/deathmarine/Luyten)
like image 139
NaanProphet Avatar answered Nov 12 '22 19:11

NaanProphet


First off, JD-GUI is not a very good decompiler. You'll almost certainly get better results using other decompilers.

That being said, it is important to learn how to understand bytecode if you want to become serious about Java reverse engineering.

There are actually two different bytecode "languages". The first is the Java classfile format, which is executed by the JVM. This is what you get when you run a Java desktop application or applet. You can find the specification here: http://docs.oracle.com/javase/specs/jvms/se8/html/index.html

However, Android does not use Java bytecode at all. Instead, it uses its own system, known as Dex bytecode, which is similar, but subtly different. You can find the specification for Dex bytecode here: https://source.android.com/devices/tech/dalvik/dalvik-bytecode

APKs consist of Dex bytecode. However, the listing you showed is Java bytecode. Presumably, you either ran it through Dex2Jar first to translate the Dex file into Java bytecode or you used a tool that did this for you. (You can also use Enjarify to do this, but the bytecode you posted doesn't look like the output of Enjarify).

At any rate, if you're trying to understand an obfuscated binary, you might as well go straight to the source and look at the Dex bytecode, rather than the output of an imperfect conversion tool. I'd recommend checking out smali/baksmali and apktool, which are the best tools I know of for working with dex files.

Update: Now that you've provided the apk, I decompiled it myself, and it really doesn't look like anything nefarious is going on. The code just happens to have a try/catch with multiple catch blocks, which confuses the decompilers you used.

Since there were multiple classes with a loginV2 method in your apk, I decided to focus on com/ipanel/join/homed/utils/APIManager.

Using Enjarify + Krakatau, I get the following decompiled code.

public void loginV2(android.content.Context a, String s, int i, String s0, String s1, String s2, cn.ipanel.android.net.http.AsyncHttpResponseHandler a0)
{
    org.apache.http.entity.StringEntity a1 = null;
    String s3 = new StringBuilder(String.valueOf((Object)com.ipanel.join.homed.Config.SERVER_ACCESS)).append("account/user/v2/login").toString();
    cn.ipanel.android.net.http.AsyncHttpClient a2 = new cn.ipanel.android.net.http.AsyncHttpClient();
    org.json.JSONObject a3 = new org.json.JSONObject();
    label1: {
        java.io.UnsupportedEncodingException a4 = null;
        label0: {
            org.json.JSONException a5 = null;
            label2: {
                java.io.PrintStream a6 = null;
                label4: {
                    label3: {
                        try
                        {
                            try
                            {
                                String s4 = new StringBuilder().append(com.ipanel.join.homed.utils.DeviceUtils.getDeviceId(a)).toString();
                                String s5 = new StringBuilder(String.valueOf((Object)s4)).append(com.ipanel.join.homed.helper.OperationUtils.getMD5(s4).substring(7, 8)).toString();
                                long j = java.util.Calendar.getInstance().getTimeInMillis();
                                a3.put("deviceno", (Object)s5);
                                a3.put("devicetype", (Object)s);
                                a3.put("accounttype", i);
                                a3.put("account", (Object)s0);
                                a3.put("pwd", (Object)com.ipanel.join.homed.helper.OperationUtils.getMD5(s1));
                                if (!android.text.TextUtils.isEmpty((CharSequence)(Object)s2))
                                {
                                    a3.put("code", (Object)s2);
                                }
                                a3.put("timestamp", (Object)new StringBuilder().append(j).toString());
                                a3.put("isforce", (Object)"1");
                                a3.put("signature", (Object)com.ipanel.join.homed.helper.OperationUtils.getMD5(new StringBuilder(String.valueOf((Object)s5)).append("|").append(s).append("|").append(i).append("|").append(s0).append("|").append(j).toString()));
                                a1 = new org.apache.http.entity.StringEntity(a3.toString(), "UTF-8");
                                a6 = System.out;
                                break label4;
                            }
                            catch(org.json.JSONException a7)
                            {
                                a5 = a7;
                            }
                        }
                        catch(java.io.UnsupportedEncodingException a8)
                        {
                            a4 = a8;
                            break label3;
                        }
                        a1 = null;
                        break label2;
                    }
                    a1 = null;
                    break label0;
                }
                {
                    try
                    {
                        try
                        {
                            a6.println(new StringBuilder("para: ").append(a3.toString()).toString());
                            break label1;
                        }
                        catch(org.json.JSONException a9)
                        {
                            a5 = a9;
                        }
                    }
                    catch(java.io.UnsupportedEncodingException a10)
                    {
                        a4 = a10;
                        break label0;
                    }
                    break label2;
                }
            }
            a5.printStackTrace();
            break label1;
        }
        a4.printStackTrace();
    }
    a2.post(a, s3, (org.apache.http.HttpEntity)(Object)a1, "text/html", a0);
}

Krakatau is a bit hard to use, but it has the advantage of being able to handle nearly anything (apart from invokedynamic, which Android luckily doesn't have). However, while it will always give you something, there are cases where the code produced is unnecessarily complicated, and this is one of them - try/catch with multiple catch blocks is handled very poorly.

Fortunately, it is easy to see what the code is actually trying to do and clean it up manually. Here is my manually cleaned up version of the above, which is likely close to the original code, apart from the variable names and fully qualified class references. As you can see, there was no deliberate obfuscation. It just happens by chance to use try/catch which decompilers struggle with.

public void loginV2(android.content.Context a, String s, int i, String s0, String s1, String s2, cn.ipanel.android.net.http.AsyncHttpResponseHandler a0)
{
    org.apache.http.entity.StringEntity a1 = null;
    String s3 = com.ipanel.join.homed.Config.SERVER_ACCESS + "account/user/v2/login";
    cn.ipanel.android.net.http.AsyncHttpClient a2 = new cn.ipanel.android.net.http.AsyncHttpClient();
    org.json.JSONObject a3 = new org.json.JSONObject();

    try
    {
        String s4 = com.ipanel.join.homed.utils.DeviceUtils.getDeviceId(a);
        String s5 = s4 + com.ipanel.join.homed.helper.OperationUtils.getMD5(s4).substring(7, 8);
        long j = java.util.Calendar.getInstance().getTimeInMillis();
        a3.put("deviceno", s5);
        a3.put("devicetype", s);
        a3.put("accounttype", i);
        a3.put("account", s0);
        a3.put("pwd", com.ipanel.join.homed.helper.OperationUtils.getMD5(s1));
        if (!android.text.TextUtils.isEmpty(s2))
        {
            a3.put("code", s2);
        }
        a3.put("timestamp", "" + j);
        a3.put("isforce", "1");
        a3.put("signature", com.ipanel.join.homed.helper.OperationUtils.getMD5(s5 + "|" + s + "|" + i + "|" + s0 + "|" + j);
        a1 = new org.apache.http.entity.StringEntity(a3.toString(), "UTF-8");
        System.out.println("para: " + a3);
    }
    catch(org.json.JSONException a7)
    {
        a7.printStackTrace();
    }
    catch(java.io.UnsupportedEncodingException a8)
    {
        a8.printStackTrace();
    }

    a2.post(a, s3, a1, "text/html", a0);
}
like image 40
Antimony Avatar answered Nov 12 '22 20:11

Antimony