文章来自微博@穿越楚,方法未经验证,且这不是我使用的破解方法,我的破解方法即将公开,有兴趣的可以自己尝试。
最近在网上发现了神奇的 KDroid 项目,在 Kindle 设备运行 Android 4.4.2,不过作者身为国人,不仅闭源,还收取 160 RMB 作为激活费用,无疑违背了开源精神。由此,本文介绍绕过 KDroid 密码验证的方法。
KDroid 刷机包普遍采用了 esystem.bin 这种打包方式,实际上通过 7-Zip 或者 Ubuntu 上的 file 工具,可以发现其为 ext4 格式的镜像,因此可以通过以下命令,在 Ubuntu 上挂载并编辑系统镜像文件。
sudo mount -o loop -t ext4 esystem.bin system
通过简单的文件浏览与反编译,可以发现,系统使用了开发者生成的 key 签名各个 apk 文件,因此不可以使用 test-keys 签名的 apk 进行替换。然而,可以通过手动破解 Android 核心的方式,禁用签名校验。
准备工作:从 Bitbucket 下载 smali.jar 与 baksmali.jar。
删除
java -Xmx256m -jar baksmali.jar -x system/framework/services.jar -o services
阅读生成的
.method static compareSignatures([Landroid/content/pm/Signature;[Landroid/content/pm/Signature;)I.locals 11 .param p0, "s1" # [Landroid/content/pm/Signature; .param p1, "s2" # [Landroid/content/pm/Signature; .prologue const/4 v7, 0x0 .line 2934 return v7 .method static compareSignatures([Landroid/content/pm/Signature;[Landroid/content/pm/Signature;)I .locals 11 .param p0, "s1" # [Landroid/content/pm/Signature; .param p1, "s2" # [Landroid/content/pm/Signature; .prologue const/4 v7, 0x0 .line 2934 return v7
并重新打包为 services.jar:
java -Xmx256m -jar smali.jar services
使用该文件替换 system/framework/services.jar ,并设置权限 0644。
在进一步的反编译后,发现 system/app/JSONClient.apk 为系统中唯一具有
而若简单删除之,系统则无法启动,也无法从设备抓取日志查看详细原因,因此只能通过代码的修改和精简达到绕过验证的目的。
准备工作: 从 Bitbucket 下载 apktool.jar,并从 GitHub 下载 auto-sign 工具,最好可以手动下载 platform.pk8 与 platform.x509.pem 替换对应的 test-key 文件。
同样地,删除 system/app/JSONClient.odex,并将 system/app/JSONClient.apk 解包:
apktool d system/app/JSONClient.apk --frame-path system/framework
阅读 JSONClient/smali/com/aclient/MainActivity$AT.smali ,将以下字节码
.line 684 .local v4, "subresult":Ljava/lang/String; const-string v5, "PASS" invoke-virtual {v4, v5}, LZ move-result v5 if-nez v5, :cond_2 const-string v5, "SUCC" invoke-virtual {v4, v5}, LZ move-result v5 if-eqz v5, :cond_4 .line 684 .local v4, "subresult":Ljava/lang/String; const-string v5, "PASS"invoke-virtual {v4, v5}, LZ move-result v5 if-nez v5, :cond_2 const-string v5, "SUCC" invoke-virtual {v4, v5}, LZ move-result v5 if-eqz v5, :cond_4
中的
iput-boolean v7, v5, Lcom/aclient/MainActivity;->doreboot:Z
由此,验证通过的条件被更改为任意密码,因此只需联网即可验证通过,同时在逻辑中去除重启的代码,以保存验证通过的状态。
接下来,阅读 JSONClient/smali/com/aclient/MainActivity.smali ,可以发现以下字节码,在主界面创建按钮,使用户可以手动打开 Wi-Fi 设置。
.line 200 :cond_0 new-instance v1, Landroid/content/Intent; const-string v2, "android.settings.WIFI_SETTINGS" invoke-direct {v1, v2}, Landroid/content/Intent;->(LV .line 202 .local v1, "intent":Landroid/content/Intent; const-string v2, "testmode" const/4 v3, 0x1 invoke-virtual {v1, v2, v3}, Landroid/content/Intent;->putExtra(LLandroid/content/Intent; .line 203 invoke-virtual {p0, v1}, Lcom/aclient/MainActivity;->startActivity(Landroid/content/Intent;)V .line 200 :cond_0 new-instance v1, Landroid/content/Intent;const-string v2, "android.settings.WIFI_SETTINGS" invoke-direct {v1, v2}, Landroid/content/Intent;->(LV .line 202 .local v1, "intent":Landroid/content/Intent; const-string v2, "testmode" const/4 v3, 0x1 invoke-virtual {v1, v2, v3}, Landroid/content/Intent;->putExtra(LLandroid/content/Intent; .line 203 invoke-virtual {p0, v1}, Lcom/aclient/MainActivity;->startActivity(Landroid/content/Intent;)V
鉴于程序开始执行之时即会自动打开 Wi-Fi 设置:
.line 364 iget-object v3, p0, Lcom/aclient/MainActivity;->mWifiManager:Landroid/net/wifi/WifiManager; invoke-virtual {v3, v8}, Landroid/net/wifi/WifiManager;->setWifiEnabled(Z)Z .line 365 invoke-virtual {p0}, Lcom/aclient/MainActivity;->getWindow()Landroid/view/Window; move-result-object v3 invoke-virtual {v3}, Landroid/view/Window;->getDecorView()Landroid/view/View; move-result-object v3 invoke-virtual {v3}, Landroid/view/View;->getWindowToken()Landroid/os/IBinder; move-result-object v3 invoke-virtual {p0, v3}, Lcom/aclient/MainActivity;->startWifiActivity(Landroid/os/IBinder;)V .line 364 iget-object v3, p0, Lcom/aclient/MainActivity;->mWifiManager:Landroid/net/wifi/WifiManager;invoke-virtual {v3, v8}, Landroid/net/wifi/WifiManager;->setWifiEnabled(Z)Z .line 365 invoke-virtual {p0}, Lcom/aclient/MainActivity;->getWindow()Landroid/view/Window; move-result-object v3 invoke-virtual {v3}, Landroid/view/Window;->getDecorView()Landroid/view/View; move-result-object v3 invoke-virtual {v3}, Landroid/view/View;->getWindowToken()Landroid/os/IBinder; move-result-object v3 invoke-virtual {p0, v3}, Lcom/aclient/MainActivity;->startWifiActivity(Landroid/os/IBinder;)V
修改按钮对应的代码,将逻辑更改为,使用户点击时可以回到桌面:
.line 200 :cond_0 new-instance v0, Landroid/content/Intent; const-string v1, "android.intent.action.MAIN" invoke-direct v0, v1, Landroid/content/Intent;->(LV .line 202 .local v0, "intent":Landroid/content/Intent; const-string v1, 'android.intent.category.LAUNCHER' invoke-virtual v0, v1, Landroid/content/Intent;->addCategory(LLandroid/content/Intent; .line 203 invoke-virtual {p0, v1}, Lcom/aclient/MainActivity;->startActivity(Landroid/content/Intent;)V .line 200 :cond_0 new-instance v0, Landroid/content/Intent;const-string v1, "android.intent.action.MAIN" invoke-direct v0, v1, Landroid/content/Intent;->(LV .line 202 .local v0, "intent":Landroid/content/Intent; const-string v1, 'android.intent.category.LAUNCHER' invoke-virtual v0, v1, Landroid/content/Intent;->addCategory(LLandroid/content/Intent; .line 203 invoke-virtual {p0, v1}, Lcom/aclient/MainActivity;->startActivity(Landroid/content/Intent;)V
如果知道第三方桌面的 apk 对应的软件包名,以及桌面 Activity(大多为 MainActivity),还可进一步创建 Intent 指向第三方桌面,这样可以防止 system/app/JSONClient.apk 对系统桌面选择的劫持,此处只是抛砖引玉。
之后,使用以下命令重新打包:
apktool b JSONClient JSONClient.apk --frame-path framework
在使用 auto-sign 签名后,替换原系统应用,设置权限 0644。同时,删除
最后,卸载系统镜像,并将镜像文件刷入 Kindle。
在设备启动后,首先会弹出 Wi-Fi 设置窗口。连接无线网络后返回,点击“验证”按钮,在出现“验证成功,重启中”提示后,继续点击“Wi-Fi”按钮,启动第三方桌面。之后,你可以在设置中强行停止 com.aclient ,并在昔日的泡面神器上感受全新的 Android 体验。