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
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)
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.");
}
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.
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.
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.
Ran into a similar issue trying to decompile a Java 8 file that used try-with-resources and lambdas.
After trying the following unsuccessfully:
This guy did the trick:
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With