折腾:
【已解决】为何Python中32字节的md值和小花生中getMD5Str计算出的md5值不同
期间,
现在确认之前Python计算出md5值不对的原因是:
StringBuilder localStringBuilder = new StringBuilder(); localStringBuilder.append(MainActivity.userId); localStringBuilder.append(l); localStringBuilder.append((String)localObject); localStringBuilder.append(paramString); localStringBuilder.append(“AyGt7ohMR!xxx#N"); paramString = StringUtil.md5(localStringBuilder.toString());
中的paramString参数搞错了
-》此处的paramString实际上已经是被赋值为
paramString = getToken(MainActivity.userId);
-》要去搞清楚此处的getToken的逻辑
-》才能拿到正确的paramString
-》才能继续计算出正确的md5
-》才能继续正常请求api,获取到期望返回的json数据
结果此处的
com/huili/readingclub/model/ModelSecurity.java
/* Error */ private static String getToken(String paramString) { // Byte code: // 0: aload_0 // 1: invokestatic 81 com/huili/readingclub/utils/StringUtil:isNullOrEmpty (Ljava/lang/String;)Z // 4: ifeq +5 -> 9 // 7: aconst_null // 8: areturn // 9: aload_0 // 10: invokestatic 87 java/lang/Integer:parseInt (Ljava/lang/String;)I // 13: iconst_1 // 14: if_icmpge +5 -> 19 // 17: aconst_null // 18: areturn // 19: getstatic 22 com/huili/readingclub/model/ModelSecurity:userTokens Ljava/util/HashMap; // 22: aload_0 // 23: invokevirtual 135 java/util/HashMap:containsKey (Ljava/lang/Object;)Z // 26: ifeq +14 -> 40 // 29: getstatic 22 com/huili/readingclub/model/ModelSecurity:userTokens Ljava/util/HashMap; // 32: aload_0 // 33: invokevirtual 139 java/util/HashMap:get (Ljava/lang/Object;)Ljava/lang/Object; // 36: checkcast 56 java/lang/String // 39: areturn // 40: invokestatic 145 com/huili/readingclub/MyApplication:getApplication ()Lcom/huili/readingclub/MyApplication; // 43: invokestatic 151 com/huili/readingclub/network/XutilsHttpClient:isNetWorkAvaiable (Landroid/content/Context;)Z // 46: ifne +5 -> 51 // 49: aconst_null // 50: areturn // 51: invokestatic 99 com/huili/readingclub/utils/DateUtils:get1970ToNowSeconds ()J // 54: lstore_1 // 55: new 101 java/lang/StringBuilder // 58: dup // 59: invokespecial 102 java/lang/StringBuilder:<init> ()V // 62: astore_3 // 63: aload_3 // 64: aload_0 // 65: invokevirtual 109 java/lang/StringBuilder:append (Ljava/lang/String;)Ljava/lang/StringBuilder; // 68: pop // 69: aload_3 // 70: lload_1 // 71: invokevirtual 106 java/lang/StringBuilder:append (J)Ljava/lang/StringBuilder; // 74: pop // 75: aload_3 // 76: ldc 111 // 78: invokevirtual 109 java/lang/StringBuilder:append (Ljava/lang/String;)Ljava/lang/StringBuilder; // 81: pop // 82: aload_3 // 83: invokevirtual 115 java/lang/StringBuilder:toString ()Ljava/lang/String; // 86: invokestatic 118 com/huili/readingclub/utils/StringUtil:md5 (Ljava/lang/String;)Ljava/lang/String; // 89: astore_3 // 90: getstatic 27 com/huili/readingclub/model/ModelSecurity:lock Ljava/util/concurrent/locks/Lock; // 93: invokeinterface 153 1 0 // 98: new 155 java/lang/Thread // 101: astore 4 // 103: new 6 com/huili/readingclub/model/ModelSecurity$1 // 106: astore 5 // 108: aload 5 // 110: aload_0 // 111: lload_1 // 112: aload_3 // 113: invokespecial 158 com/huili/readingclub/model/ModelSecurity$1:<init> (Ljava/lang/String;JLjava/lang/String;)V // 116: aload 4 // 118: aload 5 // 120: invokespecial 161 java/lang/Thread:<init> (Ljava/lang/Runnable;)V // 123: aload 4 // 125: invokevirtual 164 java/lang/Thread:start ()V // 128: getstatic 35 com/huili/readingclub/model/ModelSecurity:condition Ljava/util/concurrent/locks/Condition; // 131: invokeinterface 169 1 0 // 136: getstatic 22 com/huili/readingclub/model/ModelSecurity:userTokens Ljava/util/HashMap; // 139: aload_0 // 140: invokevirtual 135 java/util/HashMap:containsKey (Ljava/lang/Object;)Z // 143: ifeq +24 -> 167 // 146: getstatic 22 com/huili/readingclub/model/ModelSecurity:userTokens Ljava/util/HashMap; // 149: aload_0 // 150: invokevirtual 139 java/util/HashMap:get (Ljava/lang/Object;)Ljava/lang/Object; // 153: checkcast 56 java/lang/String // 156: astore_0 // 157: getstatic 27 com/huili/readingclub/model/ModelSecurity:lock Ljava/util/concurrent/locks/Lock; // 160: invokeinterface 172 1 0 // 165: aload_0 // 166: areturn // 167: getstatic 27 com/huili/readingclub/model/ModelSecurity:lock Ljava/util/concurrent/locks/Lock; // 170: invokeinterface 172 1 0 // 175: aconst_null // 176: areturn // 177: astore_0 // 178: goto +18 -> 196 // 181: astore_0 // 182: aload_0 // 183: invokevirtual 175 java/lang/Exception:printStackTrace ()V // 186: getstatic 27 com/huili/readingclub/model/ModelSecurity:lock Ljava/util/concurrent/locks/Lock; // 189: invokeinterface 172 1 0 // 194: aconst_null // 195: areturn // 196: getstatic 27 com/huili/readingclub/model/ModelSecurity:lock Ljava/util/concurrent/locks/Lock; // 199: invokeinterface 172 1 0 // 204: aload_0 // 205: athrow // Local variable table: // start length slot name signature // 0 206 0 paramString String // 54 58 1 l long // 62 51 3 localObject Object // 101 23 4 localThread Thread // 106 13 5 local1 1 // Exception table: // from to target type // 98 157 177 finally // 182 186 177 finally // 98 157 181 java/lang/Exception }
-》竟然是代码error出错,无法得到源码的。。。
尝试分析看看这段代码,看看是否能找到可能的逻辑。
好像是内部用到了userTokens这个HashMap
但是却找不到哪里得到的数据
好像是从网络中获取到的?
后续好像又用md5,timestamp等处理了?
那想办法去试试:
- 用其他工具导出jar包得到源码
- 看看代码是否正常显示
- 找找其他版本的apk,再去试试
- 或许dump出来的dex,dex转jar,jar导出的java就正常显示源码了?
然后换用Luyten,还真可以看到正常原始java代码了:
然后去整理:
【整理】把jar包转换为java源代码的java反编译器的整理和对比
另外,也去试试别人提到的,貌似效果不错的CFR:
【已解决】用java反编译器CFR从jar包导出java源代码
然后拷贝出代码:
private static String getToken(String s) { if (StringUtil.isNullOrEmpty(s)) { return null; } if (Integer.parseInt(s) < 1) { return null; } if (ModelSecurity.userTokens.containsKey(s)) { return ModelSecurity.userTokens.get(s); } if (!XutilsHttpClient.isNetWorkAvaiable((Context)MyApplication.getApplication())) { return null; } final long get1970ToNowSeconds = DateUtils.get1970ToNowSeconds(); final StringBuilder sb = new StringBuilder(); sb.append(s); sb.append(get1970ToNowSeconds); sb.append(“AyGt7ohMR!xx#N"); final String md5 = StringUtil.md5(sb.toString()); ModelSecurity.lock.lock(); try { try { new Thread(new Runnable() { @Override public void run() { ModelSecurity.lock.lock(); try { try { final StringBuilder sb = new StringBuilder(); sb.append("http://www.xiaohuasheng.cn:83/UserService.svc/getToken/"); sb.append(s); sb.append("/"); sb.append(get1970ToNowSeconds); sb.append("/"); sb.append(md5); final HttpURLConnection httpURLConnection = (HttpURLConnection)new URL(sb.toString()).openConnection(); httpURLConnection.setRequestMethod("GET"); httpURLConnection.setRequestProperty("Content-Type", "application/json"); httpURLConnection.setRequestProperty("Authorization", "NSTp9~)NwSfrXp@\\"); final Map<?, ?> jsonToMap = JsonUtil.jsonToMap(new String(toByteArray(httpURLConnection.getInputStream()), "UTF-8")); if (jsonToMap == null) { ModelSecurity.condition.signalAll(); ModelSecurity.lock.unlock(); return; } final StringBuilder sb2 = new StringBuilder(); sb2.append(jsonToMap.get("M")); sb2.append(""); if (!sb2.toString().equals("1001")) { ModelSecurity.condition.signalAll(); ModelSecurity.lock.unlock(); return; } final StringBuilder sb3 = new StringBuilder(); sb3.append(jsonToMap.get("J")); sb3.append(""); final List<?> jsonToList = JsonUtil.jsonToList(MessageGZIP.uncompressToString(Base64.decode(sb3.toString()), "UTF-8")); ...... }
然后剩下就是,继续抓包分析,找到对应userId的getToken的值了。
去找到:
http://www.xiaohuasheng.cn:83/UserService.svc/getToken/{userId}/{timestamp}
的请求去看看对应的值了。
然后抓包到了:
GET /UserService.svc/getToken/1134723/1554276832/a56826c5013b7c5c85e7012a8fe7ce1b HTTP/1.1 Content-Type: application/json Authorization: NSTp9~)NwSfrXp@\ User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.4.2; A0001 Build/KOT49H) Host: www.xiaohuasheng.cn:83 Accept-Encoding: gzip Connection: keep-alive HTTP/1.1 200 OK Cache-Control: private Content-Length: 127 Content-Type: application/json; charset=utf-8 Server: Microsoft-IIS/7.5 Set-Cookie: ASP.NET_SessionId=ljdtlluhnj1bqf44hgfekjhs; path=/; HttpOnly X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Wed, 03 Apr 2019 07:33:55 GMT Connection: keep-alive {"C":2,"J":"H4sIAAAAAAAEAIuuVspLzE1VslIyMUgxMjIzT9M1NrVM1TUxNTLTtTQ1TNQ1MzM1tEw1tTCzSDZWqo0FACB75XoxAAAA","M":"1001","ST":null}
解码后的json是:
[ { "name": "40d2267f-359e-4526-951a-66519e5868c3" } ]
-》此处
- userId是:1554276832
- 返回的token是:40d2267f-359e-4526-951a-66519e5868c3
然后继续回去之前的:
【未解决】Python实现小花生中addSignature的md5加密生成签名的逻辑