高中时候写的草稿,到了大学了应该能放心发了吧_(:з」∠)_
教室门口的智能班牌是个跑AOSP 8.1的rk3399,平时我们当平板用。但被维护员更新launcher后,开机就会自动屏蔽状态栏和导航栏,无法退出班牌程序,除非输入密码进入维护模式。好在咕咕此前已提取了launcher和软件,尝试反编译破解发现逻辑并不难,故分享。
确定密码是否为联网下发
首先进入对应界面随便输入个密码,并在此时打开抓包工具。两个App在提交密码时都没有出现任何网络请求——说明其密码均为本地算法生成。
那很好了,直接解包开干😋
破解MDM launcher
以下是班牌的默认桌面:

首先打开密码输入界面,查看提示文字以定位class。

那么直接解包APK,打开它的dex,搜索“请输入密码”,找到了该对话框所在的class。

要想分析输入密码后发生了什么,就看点击文字为“确定”的按钮后会发生什么。该按钮的代码即.line 1407中的内容:
new-instance v2, Lcom/eyijiao/mdm/MainActivity$3;
invoke-direct {v2, p0, v0}, Lcom/eyijiao/mdm/MainActivity$3;-><init>(Lcom/eyijiao/mdm/MainActivity;Landroid/widget/EditText;)V
const-string v0, "确定"
invoke-virtual {v1, v0, v2}, Landroid/app/AlertDialog$Builder;->setPositiveButton(Ljava/lang/CharSequence;Landroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder;
第1行,创建了类com.eyijiao.mdm.MainActivity$3的实例,保存到名为v2的寄存器。第2行,调用了实现了DialogInterface.OnClickLinstenerAPI的类v2,将寄存器v1(即用户输入的密码,见图第9611行)的内容作为参数传递了过去。
而根据Android API文档,用户点击按钮时会调用实现该API的类的onClick()抽象方法。此时我们就可以定位到com.eyijiao.mdm.MainActivity$3的onClick方法,它就是密码被传递的地方:

第67~84行,程序将传入的EditText数据转为字符串存储在p1中,然后程序比对p1是否为空(第86~97行),非空则将p1赋给v0,并以v0为参数调用MainActivity.access$1700()方法:成功则跳转AppInfosActivity(第112~126行,即维护界面),失败则提示密码错误(第128~141行)
然而找到access$1700,发现它传给getPsd()方法了😅搁这套娃呢

回到MainActivity找到getPsd,发现也是纯逆天——这玩意儿是当天日期生成的!
首先,给Calendar对象设置为当前日期。

然后获取该对象的月份和日,分别存储在v1和v0。

将v1(月)和v0(日)以字符串形式拼接起来,存储在v0。举个栗子:今天是7月21日,那么v0寄存的就是"721"。

最后转换为数字再乘以0x141,即十进制的321,就是密码!比如721×321=231441,那么231441就是7月21日的密码。(我去这不是三角洲吗)

现在MDM laucher已经被顺利破开了,接下来就是班牌主程序了。乖乖躺好吧我要开动啦~~
破解主程序
正在施工中......
说结论!
MDM桌面的密码是:当月和当日拼接后乘以321。举个栗子,721×321=231441,那么231441就是7月21日的密码。
班牌主程序的密码需要打开这个链接扫描二维码即可~
