作者論壇賬號:小騷
Contacts聯繫人 複製代碼 隱藏代碼包名:com.fock.lockMD5值:0c298c0f5a8847753dd6d352d7a30be8文件大小:936.80 KB來源:某三樓用到的工具
模擬器+Xposed
android studio(看日誌和運算結果)
jeb或者任何可以反編譯apk工具
入口分析
從AndroidManifest.xml分析入口以及服務 主啟動頁面是MainActivity進去看看
複製代碼 隱藏代碼<application android:allowBackup="true" android:debuggable="true" android:icon="@drawable/MT_Bin" android:label="@string/MT_Bin" android:theme="@style/MT_Bin"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <service android:enabled="true" android:exported="true" android:name=".MyService"/> <receiver android:exported="true" android:name=".AutoBroadcast"> <intent-filter android:priority="2147483647"> <action android:name="com.fock.lock.js"/> <action android:name="android.intent.action.BATTERY_CHANGED"/> <action android:name="android.intent.action.DATA_ACTIVITY"/> <action android:name="android.intent.action.DATA_STATE"/> <action android:name="android.intent.action.DATE_CHANGED"/> <action android:name="android.server.checkin.FOTA_CANCEL"/> <action android:name="android.intent.action.MEDIABUTTON"/> <action android:name="android.intent.action.MEDIA_MOUNTED"/> <action android:name="android.intent.action.MEDIA_SCANNER_STARTED"/> <action android:name="android.intent.action.MEDIA_SCANNER_FINISHED"/> <action android:name="android.intent.action.TIME_SET"/> <action android:name="android.intent.action.TIME_TICK"/> <action android:name="android.intent.action.UMS_CONNECTED"/> <action android:name="android.intent.action.WALLPAPER_CHANGED"/> <action android:name="android.intent.action.PACKAGE_ADDED"/> <action android:name="android.intent.action.PACKAGE_REMOVED"/> <action android:name="android.intent.action.PHONE_STATE"/> <action android:name="android.intent.action.SCREEN_OFF"/> <action android:name="android.intent.action.SCREEN_ON"/> <action android:name="android.intent.action.SERVICE_STATE"/> <action android:name="android.intent.action.SIG_STR"/> <action android:name="android.intent.category.ALTERNATIVE"/> <action android:name="android.intent.action.SETTINGS"/> <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> <action android:name="android.net.wifi.WIFI_STATE_CHANGED"/> <action android:name="android.net.wifi.STATE_CHANGE"/> <action android:name="android.intent.action.REBOOT"/> <action android:name="android.intent.action.USER_PRESENT"/> <category android:name="android.intent.category.HOME"/> </intent-filter></receiver></application>
MainActivity裡面就啟動一個服務,到MyService這個服務裡面看看
複製代碼 隱藏代碼public class MainActivity extends Activity { home.php?mod=space&uid=1892347// android.app.Activity protected void onCreate(Bundle bundle0) { LogCatBroadcaster.start(this); super.onCreate(bundle0); this.startService(new Intent(this, MyService.class)); } @Override// android.app.Activity protected void onDestroy() { super.onDestroy(); }}
MyService的onCreate函數 執行了L方法,發現這個就是第一層的代碼
複製代碼 隱藏代碼 @Override// android.app.Service public void onCreate() { super.onCreate(); this.fv = new FloatView(this.getApplicationContext()); this.L(); }第一層分析
先看初始化了哪些東西
![](https://imageproxy.pixnet.cc/imgproxy?url=https://drbanana.ml/img/68747470733a2f2f6d6d62697a2e717069632e636e2f737a5f6d6d62697a5f706e672f4c4650726961536a42555a4a62524d4c483972696161536e555832717454764a68596a546e424f44476e636a6c6238565548474333516f58415a4a6f69637a4d39687a59616f31415965475375534c7a69616961554741776655412f3634303f77785f666d743d706e67.webp)
到點擊事件分析,發現解鎖算法用到了兩個參數
複製代碼 隱藏代碼 @Override// android.view.View$OnClickListener public void onClick(View view0) { if(MyService.this.lp.getText().toString().trim().length() == 0) { return; } // 解鎖算法 if(MyService.this.lp.getText().toString().equals("" + (MyService.this.ck / this.val$Admin ^ MyService.sb(Integer.parseInt(this.val$清))))) { MyService.this.fv.removeView(); MyService.this.Z(); return; } MyService.this.密碼錯誤.setVisibility(0); MyService.this.密碼錯誤.setText("密碼錯誤聯繫半支煙QQxxxxxxxx解鎖"); Runnable runnable0 = MyService.this.runn; MyService.this.hand.postDelayed(runnable0, 2000L); }
使用 YukiHookAPI(Xposed) Hook 獲取關鍵參數
複製代碼 隱藏代碼// 類名 findClass("com.fock.lock.MyService\$100000012").hook { injectMember { method { // 方法名 name = "onClick" // 參數 param(ViewClass) // 返回值 returnType = UnitType } // 方法執行後 afterHook { // 反射獲取 val admin = instance.getParam<Int>("val\$Admin") val 清 = instance.getParam<String>("val\$清") 打印結果 loggerE(msg = "admin: $admin\n清: $清") } } }
還原最終密碼運算
複製代碼 隱藏代碼 // Kotlin 寫法 private fun 第一層() { // 識別碼 val ck = 56983 // 參數1 val arg1 = 14 // 參數2 val arg2 = sb(7) // 識別碼 除以 參數1 異或運算 參數2 val pass = ck / arg1 xor arg2 "第一層密碼: $pass".logd() }
第二層分析
看看初始化了哪些
直接就是一堆讓人頭大的運算
複製代碼 隱藏代碼 @Override// android.view.View$OnClickListener public void onClick(View view0) { int v15; int[][] arr2_v = {new int[]{4, 6, 8, 10, 13, 16, 17, 18, 21, 23, 27, 29, 0x1F, 33, 41, 45, 52, 54, 56, 61, 67, 69, 71, 73, 74, 76, 78, 80, 82, 84, 85, 86}}; int[][] arr2_v1 = new int[arr2_v[0].length][arr2_v.length]; int v; for(v = 0; v < arr2_v.length; ++v) { int v1; for(v1 = 0; v1 < arr2_v[0].length; ++v1) { arr2_v1[v1][v] = arr2_v[v][v1]; } } int[][] arr2_v2 = {new int[]{14, 16, 18, 19, 23, 24, 28, 29, 0x1F, 35, 37, 39, 41, 43, 0x2F, 0x30, 49, 51, 53, 57, 59, 62, 0x40, 66, 69, 73, 76, 0x4F, 81, 83, 85, 87, 0x6F, 0x83, 0x9C}}; int[][] arr2_v3 = new int[arr2_v2[0].length][arr2_v2.length]; int v2; for(v2 = 0; v2 < arr2_v2.length; ++v2) { int v3; for(v3 = 0; v3 < arr2_v2[0].length; ++v3) { arr2_v3[v3][v2] = arr2_v2[v2][v3]; } } int v4; for(v4 = 0; v4 < arr2_v1.length; ++v4) { int v5 = MyService.this.b + arr2_v1[MyService.this.b][MyService.this.b]; MyService.this.c = v5; int v6; for(v6 = 0; v6 < arr2_v3[arr2_v1[MyService.this.b][MyService.this.b]][MyService.this.b]; ++v6) { int v7 = MyService.this.d + arr2_v1[MyService.this.b][MyService.this.b] + arr2_v3[arr2_v3[MyService.this.b][MyService.this.b]][MyService.this.b]; MyService.this.d = v7; } } int v8 = 2 * MyService.this.po1; int v9 = MyService.this.a; int v10 = 11 + 4 * MyService.this.b + v9; int v11 = MyService.this.a * 6 ^ v10; int v12 = MyService.this.po1 - v8 + v11; MyService.this.po2 = v12; int v13 = MyService.this.po2; int v14 = MyService.this.b; if(MyService.this.po1 >= v14 + arr2_v3[MyService.this.b][MyService.this.b]) { v15 = MyService.sb(MyService.this.po2); } else { int v16 = MyService.this.c; int v17 = 5 + 2 * MyService.this.po2 + v16; v15 = MyService.this.po2 ^ v17; } int v18 = v13 + v15 + MyService.this.a ^ 25 >> MyService.sb(20 - MyService.this.b >> 99); int v19 = Integer.parseInt("" + (MyService.this.cl ^ MyService.sb(16 * v18 ^ 3))) / 999; if(MyService.this.lp.getText().toString().equals("" + (v19 * 2 ^ MyService.this.cl))) { MyService.this.fv.removeView(); MyService.this.X(); } }
先使用 Xposed Hook 反射獲取用到 MyService 裡面的幾個參數
複製代碼 隱藏代碼// 同上findClass("com.fock.lock.MyService\$100000024").hook { injectMember { method { name = "onClick" param(ViewClass) returnType = UnitType } afterHook { val myService = instance.getParam<Any>("this\$0") myService?.let { val a = it.getParam<Int>("a") val b = it.getParam<Int>("b") val c = it.getParam<Int>("c") val d = it.getParam<Int>("d") val cl = it.getParam<Int>("cl") val po1 = it.getParam<Int>("po1") val po2 = it.getParam<Int>("po2") loggerE(msg = "a: $a\nb: $b\nc: $c\nd: $d\ncl: $cl\npo1: $po1\npo2: $po2") } } } }
然後把獲取到的參數複製到自己代碼裡面運行一下
複製代碼 隱藏代碼public class IntArray { public static int[][] arr2_v= {new int[]{4, 6, 8, 10, 13, 16, 17, 18, 21, 23, 27, 29, 0x1F, 33, 41, 45, 52, 54, 56, 61, 67, 69, 71, 73, 74, 76, 78, 80, 82, 84, 85, 86}}; public static int[][] arr2_v1 = new int[arr2_v[0].length][arr2_v.length]; public static int[][] arr2_v2 = {new int[]{14, 16, 18, 19, 23, 24, 28, 29, 0x1F, 35, 37, 39, 41, 43, 0x2F, 0x30, 49, 51, 53, 57, 59, 62, 0x40, 66, 69, 73, 76, 0x4F, 81, 83, 85, 87, 0x6F, 0x83, 0x9C}}; public static int[][] arr2_v3 = new int[arr2_v2[0].length][arr2_v2.length]; static int d = 37536; private static final int po1 = 0; private static final int a = 0; private static int po2 = 0; private static int c = 4; static { int v; for (v = 0; v < arr2_v.length; ++v) { int v1; for (v1 = 0; v1 < arr2_v[0].length; ++v1) { arr2_v1[v1][v] = arr2_v[v][v1]; } } int v2; for (v2 = 0; v2 < arr2_v2.length; ++v2) { int v3; for (v3 = 0; v3 < arr2_v2[0].length; ++v3) { arr2_v3[v3][v2] = arr2_v2[v2][v3]; } } int v4; for (v4 = 0; v4 < arr2_v1.length; ++v4) { int v5 = 0 + arr2_v1[0][0]; c = v5; int v6; for (v6 = 0; v6 < arr2_v3[arr2_v1[0][0]][0]; ++v6) { int v7 = d + arr2_v1[0][0] + arr2_v3[arr2_v3[0][0]][0]; d = v7; } } Log.d("xihantest", "\nd: " + d); int v8 = 2 * po1; int v9 = a; int v10 = 11 + 4 * 0 + v9; int v11 = a * 6 ^ v10; int v12 = po1 - v8 + v11; po2 = v12; int v13 = po2; int v14 = 0; int v15; if(po1 >= v14 + arr2_v3[0][0]) { v15 = sb(po2); }else { int v16 = c; int v17 = 5 + 2 * po2 + v16; v15 = po2 ^ v17; } int v18 = v13 + v15 + a ^ 25 >> sb(20 - 0 >> 99); Log.d("xihantest", "v18: " + v18); }}
獲取到最終固定的的v18 = 658,運算方法也顯而易見了
複製代碼 隱藏代碼 private fun 第二層() { // 識別碼 val cl = 44722 // (識別碼 異或運算 658) 除以 999 val v19 = (cl xor 658) / 999 // v19 乘以 2 異或運算 識別碼 val pass = v19 * 2 xor cl "第二層密碼: $pass".logd() }
第三層分析
初始化控件和第二層一樣,直接來到點擊事件這裡分析,這裡解鎖的關鍵是獲取v1的值
複製代碼 隱藏代碼 @Override// android.view.View$OnClickListener public void onClick(View view0) { // 使用了 aes 加密 byte[] arr_b = MyService.this.aes.cipher("Android SignApk".getBytes()); StringBuffer stringBuffer0 = new StringBuffer(); int v; for(v = 0; v < 16; ++v) { if((arr_b[v] & 0xFF) > 15) { stringBuffer0.append(String.format("%x", new Byte(arr_b[v]))); } else { stringBuffer0.append(String.format("0%x", new Byte(arr_b[v]))); } stringBuffer0.append(" "); } // 獲取到這個值 離解鎖就差一步 int v1 = MyService.this.letterToNumber(((String)"" + stringBuffer0.subSequence(3, 36))) / 3000; if(MyService.this.lp.getText().toString().trim().length() == 0) { return; } // 解鎖方式1: 會強行重啟配合開機自啟服務再坑一波錢 if(MyService.this.lp.getText().toString().equals("6" + (v1 ^ MyService.this.cz))) { MyService.this.fv.removeView(); new Timer().schedule(new 100000036(this), 1500L); return; } // 解鎖方式2: 直接刪除當前view 也就是可以回到桌面卸載應用 if(MyService.this.lp.getText().toString().equals("" + (v1 ^ MyService.this.cz))) { MyService.this.fv.removeView(); return; } MyService.this.解鎖.setVisibility(0); MyService.this.解鎖.setText("密碼錯誤,手機恢復正常失敗/nManifest-Version: 1.0Created-By: 1.0 (Android SignApk)"); Runnable runnable0 = MyService.this.runn3; MyService.this.hand3.postDelayed(runnable0, 2000L); }
Aes類就是用dex轉jar大法,把這個jar以及代碼複製過來修一修
複製代碼 隱藏代碼// 這是我寫的 Kotlin 函數 直接獲取結果fun aes(): Int { val aes = Clown(Clown.KeySize.Bits192, keys) val arr_b = aes.cipher("Android SignApk".toByteArray()) val stringBuffer0 = StringBuffer() var v = 0 while (v < 16) { if (arr_b[v].toInt() and 0xFF > 15) { stringBuffer0.append(String.format("%x", arr_b[v])) } else { stringBuffer0.append(String.format("0%x", arr_b[v])) } stringBuffer0.append(" ") ++v } val v1 = letterToNumber("" + stringBuffer0.subSequence(3, 36)) / 3000 return v1}
最終密碼運算
複製代碼 隱藏代碼 private fun 第三層() { // 識別碼 val cz = 158718 // 上面獲取到的 v1 異或運算 識別碼 val pass = "${aes() xor cz}" "第三層密碼: $pass".logd() }
樣本下載地址:https://xihan.lanzouv.com/iRgfI0dt60ed解壓密碼:52pj
-官方論壇
www.52pojie.cn
--推薦給朋友
公眾微信號:吾愛破解論壇
或搜微信號:pojie_52