首页
社区
课程
招聘
[原创]硬上MTK平板
2019-3-1 14:34 18749

[原创]硬上MTK平板

2019-3-1 14:34
18749
三天前,同事拿来了一个定制过的平板,问我能不能自己装个应用上去,我心想这能有多难,就接过来了


第一天,设备上手


拿到手点了一会儿,发现是个叫天奇健教育培训机构给学生定制的PAD(提分派)。它自己开发的桌面,上面只显示学习相关的应用(背单词,答题,校园通知相关的东西)。桌面上唯一一个和Android相关的就是系统设置,点开发现也裁掉了绝大部分功能。除了WIFI设置关于设备以外几乎没有其他选项,而关于设备里面反复点击版本,即便提示开发者模式已经打开,实际也看不到这个菜单。 看来定制的思路完全就是怕学生拿PAD玩耍而不是学习。

平板用的是MTK的MT6580的芯片,设备名字叫k960N_MT6580_32_N,Android 7,内核3.18.35+,连淘宝上都没得卖,只有aliexpress上有个链接,估计是个贴牌机之类的产品。自带的应用都是连接校园内网才能使用,看了一圈也没发现什么一下就能实现下载安装的功能(实在不想花时间琢磨这些应用了)。

试了一会儿发现设备开关和音量上组合可以进bootloader模式,并且fastboot oem unlock竟然能解锁。首先想到的是通过解锁,设备肯定会重置用户数据,也许这个定制的桌面就跟着被删除了。要是回到Android原生的桌面,就有转机了。遗憾的是,重置以后桌面还在,只是应用少了很多。这个桌面应该是把原生桌面直接从/system/app替换了。

不过bootloader已经解锁了,按说现在的权限已经可以改分区,替换掉它这些自定义的东西了。但麻烦在于,这么个无名无姓的平板,无论是源码还是官方固件,网上搜不到任何信息,没有东西让你能替进去的。索性还是下载了一些其他MT6580芯片设备的ROM或者TWRP,挨个尝试fastboot boot xxx.img,看能不能有个奇迹,要的不多,只要不崩,系统能启动。这样好歹能有个img开始改起啊。第一天就在试来试去中度过了,发现非Android 7的boot.img和recovery.img,导致的都是快速重启,Android 7的的img则是启动后卡顿十几秒后重启。

第二天,读取分区


boot.img和recovery.img还是挺娇气的,稍微有点差异就不能正常引导系统,还是得想办法把PAD里的原始镜像DUMP出来自行修改。
搜到MTK芯片有个模式叫MTK Preloader(工厂刷机模式),工厂量产设备时用它可以快速刷写系统,配套的工具叫SP Flash Tool,基本被用来救砖。这种工厂刷机模式非常类似高通的QPST(9008模式),都是由固化在芯片里率先启动的bootrom提供的功能。由于bootrom没法篡改,系统总能黑砖下起死回生。

进入这种模式时差不多都是组合键或者直接短接SOC上的特定触点,手机启动后就会开启一个串口。然后PC端按照约定协议,发送一个用于继续执行的第2阶段的程序文件过去(高通叫prog_emmc_xxx.mdn,MTK一般是MTK_AllInOne_DA.bin)。接下来这个二进制程序会开始执行,并且继续和PC通信,实现改写分区的任务。

SP Flash Tool就是PC端用于和进入这种模式的MTK设备通信的软件,相比高通设备要四处寻找prog_emmc文件不同,MTK设备有个比较通用的 MTK_AllInOne_DA.bin文件作为第二阶段的代码。工厂模式除了可以刷写分区,还能读取分区内容回传。

一般使用这种模式时,读写分区要有个配置文件MT6580_Android_scatter.txt,里面用于配置各个分区所在的磁盘偏移,这样软件才知道你要读的分区究竟在哪。随手打开了一个之前下载的MT6580设备的ROM,就找到了这种配置文件:
- partition_index: SYS0
  partition_name: preloader
  file_name: preloader_keytak6580_weg_n.bin
  is_download: true
  type: SV5_BL_BIN
  linear_start_addr: 0x0
  physical_start_addr: 0x0
  partition_size: 0x400000
  region: EMMC_BOOT_1
  storage: HW_STORAGE_EMMC
  boundary_check: true
  is_reserved: false
  operation_type: BOOTLOADERS
  reserve: 0x00

- partition_index: SYS1
  partition_name: pgpt
  file_name: NONE
  is_download: false
  type: NORMAL_ROM
  linear_start_addr: 0x0
  physical_start_addr: 0x0
  partition_size: 0x80000
  region: EMMC_USER
  storage: HW_STORAGE_EMMC
  boundary_check: true
  is_reserved: false
  operation_type: INVISIBLE
  reserve: 0x00
  ......
- partition_index: SYS8
  partition_name: boot
  file_name: boot.img
  is_download: true
  type: NORMAL_ROM
  linear_start_addr: 0x1D20000
  physical_start_addr: 0x1D20000
  partition_size: 0x1000000
  region: EMMC_USER
  storage: HW_STORAGE_EMMC
  boundary_check: true
  is_reserved: false
  operation_type: UPDATE
  reserve: 0x00

配置文件和手里的设备难免有差,只能作为一个参考。系统一般会分成三个大区EMMC_BOOT_1, EMMC_BOOT_2, EMMC_USER。 我们关心的boot.img位于EMMC_USER分区,至于是不是从0x1D200000开始就不好说了。



一般进入这种刷机模式,需要把电池扣下来,让设备完全断电,然后再把电池放回去,这时插上USB线后就能检测到串口了。软件必须提前执行读或者写的指令,因为该模式可能只有几秒钟的时间窗,窗内没有收到第二阶段的文件就逾期不候了。麻烦又开始了,这个PAD拆开后盖看,电池是焊在板子上的,哪有电池让我扣啊。实在不得已,只能把红色VCC的电源线线焊下来了。



每次进入这种模式时的步骤就变成了:右手食指把红线压回原触点,左手迅速把USB线插入。
经过一段时间的练习,我已经可以大概率地进入工厂刷机状态了。接下来,软件上配置好READ BACK,点击按钮,然后进行左右手互搏后,就完成了一次分区读取。显然,按照之前的剧本惯性来看,仍然没有那么顺利,从 0x1D200000读取回来的果然不是boot.img

于是干脆读了EMMC_USER分区开头0地址开始,长度0x1000的部分,里面有磁盘分区表,可以根据这个自己计算偏移。分区表的开头大概长这个样子:
00000200h: 45 46 49 20 50 41 52 54 00 00 01 00 5C 00 00 00 ; EFI PART....\...
00000210h: 18 37 4C D9 00 00 00 00 01 00 00 00 00 00 00 00 ; .7L?...........
00000220h: FF 7F CE 01 00 00 00 00 00 04 00 00 00 00 00 00 ; ?............
00000230h: FF 7B CE 01 00 00 00 00 00 00 00 00 00 00 00 00 ; {?............
00000240h: 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ; ................

继续往后找就看到各个分区的说明字段了,其中boot分区开始sector是0xF600,sector结束位置是0x175FF
00000700h: A2 A0 D0 EB E5 B9 33 44 87 C0 68 B6 B7 26 99 C7 ; 须骞3D嚴h斗&櫱
00000710h: 39 09 9B 1F 6B E1 C9 4B A5 BC DC 2E E9 69 D8 01 ; 9.?k嵘Kゼ?閕?
00000720h:[00 F6 00 00]00 00 00 00[FF 75 01 00]00 00 00 00 ; .?.....u......
00000730h: 00 00 00 00 00 00 00 00 62 00 6F 00 6F 00 74 00 ; ........b.o.o.t.
00000740h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000750h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000760h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000770h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000780h: A2 A0 D0 EB E5 B9 33 44 87 C0 68 B6 B7 26 99 C7 ; 须骞3D嚴h斗&櫱
00000790h: 21 C7 22 D7 EE 0D B8 4C 8A 83 2C 63 CD 13 93 C7 ; !?最.窵妰,c?撉
000007a0h: 00 76 01 00 00 00 00 00 FF F5 01 00 00 00 00 00 ; .v......?.....
000007b0h: 00 00 00 00 00 00 00 00 72 00 65 00 63 00 6F 00 ; ........r.e.c.o.
000007c0h: 76 00 65 00 72 00 79 00 00 00 00 00 00 00 00 00 ; v.e.r.y.........
000007d0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
000007e0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
000007f0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................

每个sector能存放512字节,所以改写成SP Flash Tool的格式就是:

Start Address: 0xF600 * 512 = 0x1EC00000
Length: 512 * (0x175FF -  0xF600 + 1) = 0x1000000

第二天最后一次左右互搏后,拿到了PAD的boot.img和recovery.img,fastboot boot xxx.img试了一下,可以正常启动

第三天,改分区


现在有了boot.img和recovery.img的镜像,可以动手修改再fastboot flash boot xxx.img刷回了,目的就是让启动后的系统开放一些,比如增加个ADB ROOT。
下面的步骤多少稍微绕了点弯路,主要原因是硬刚boot.img没刚过(无论如何都没法通过修改init.xxx.rc实现开机启动ADB)。

修改img用的工具是mkbootimg_tools,先修改recovery.img:
在/default.prop增加ro.debuggable=1,这样进入recovery后会启动adb;
接下载再patch位于/sbin的adbd,具体就是把drop_privileges函数里执行的东西一个大B跳过,这样ADB就不降权了;

考虑到selinux的限制,不降权的ADB也许没法正常运行,就把/sepolicy也修改一下。
用到sepolicy_inject附件是用cygwin编译的sepolicy_inject),把可能惹麻烦的域都改成permissive:
sepolicy-inject -Z adbd -P rout/ramdisk/sepolicy -o rout/ramdisk/sepolicy
sepolicy-inject -Z shell -P rout/ramdisk/sepolicy -o rout/ramdisk/sepolicy
sepolicy-inject -Z init -P rout/ramdisk/sepolicy -o rout/ramdisk/sepolicy
sepolicy-inject -Z recovery -P rout/ramdisk/sepolicy -o rout/ramdisk/sepolicy

重打包的recovery启动后就带ADB ROOT了,不过只能pushpull,因为/system/bin/sh并不存在,如果recovery像我一样刚好带了挂载/system的功能,可以挂载后再执行adb shell。或者找个类似设备,把/system/bin/system/lib拷贝一份,手动adb push上去也可以。

利用这个高权限接口,把自己的应用传到/data/app下,再重启进入主系统,应用就会自动安装。不过Android 6开始,即便APK带有android.permission.RECEIVE_BOOT_COMPLETED权限,如果从来没有没有被打开过,也是不会开机启动的(它自定义的桌面不显示我们装的应用,所以没法点击打开)。

所以我在/data/app放了两个应用,其中一个是第三方Launcher,装好后再按home键就会弹出选项,启动自定义的Launcher。另一个放在/data/app下的应用就会在第三方桌面下显示了,而他里面就一行代码,用于启动com.android.settings.developmentsettings,为的就是在图形界面下把usb调试打开。

所以,以上繁琐的步骤,其实只为了打开usb调试而已。

最后,然后再把boot.img里的adbd也修改一下,重启就有了ADB ROOT。看/mt6580.fstab知道设备本身没开dm-verity,干脆把它的桌面从/system里给删除了,再后面就随意发挥了

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

最后于 2019-3-1 14:44 被txstc编辑 ,原因:
上传的附件:
收藏
点赞16
打赏
分享
打赏 + 2.00雪花
打赏次数 1 雪花 + 2.00
 
赞赏  yjmwxwx   +2.00 2019/03/05
最新回复 (13)
雪    币: 6769
活跃值: (4422)
能力值: (RANK:600 )
在线值:
发帖
回帖
粉丝
gjden 14 2019-3-1 15:06
2
0
写得不错,辛苦,精华鼓励!
雪    币: 29414
活跃值: (18685)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 8 2019-3-1 15:10
3
1
希望看到更多“硬件”相关的文章
雪    币: 17790
活跃值: (60003)
能力值: (RANK:125 )
在线值:
发帖
回帖
粉丝
Editor 2019-3-1 17:02
4
0
楼主厉害啊 佩服佩服
雪    币: 6977
活跃值: (1775)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
TopC 2019-3-1 17:26
5
0
厉害
雪    币: 351
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
五天 2019-3-1 17:38
6
0
哇塞,楼主牛啊
雪    币: 614
活跃值: (1112)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
qqwawzymu 2019-3-1 17:46
7
0
很厉害。目前对于定制安卓硬件也是感觉很繁琐。。。。。
雪    币: 12500
活跃值: (3038)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
白菜大哥 2019-3-1 19:21
8
0
楼主很厉害呀,可以加个好友吗。
雪    币: 208
活跃值: (119)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mancong 2019-3-1 20:19
9
0
锁bootloader的是相当的恶心,
雪    币: 42
活跃值: (152)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
抓狂的小丸子 2019-3-2 18:51
10
0
厉害
雪    币: 214
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lovedalin 2019-3-5 10:12
11
0
666666666666
雪    币: 199
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tofuliang 2019-3-5 18:11
12
0
想知道如果有工厂镜像,可以根据工厂镜像解锁BootLoader麽?我的魅蓝E3一直在等BootLoader解锁..
雪    币: 2242
活跃值: (169)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
txstc 4 2019-3-8 23:27
13
0
tofuliang 想知道如果有工厂镜像,可以根据工厂镜像解锁BootLoader麽?我的魅蓝E3一直在等BootLoader解锁..
有可能可以,你说的工厂镜像是普通的固件包里解出来的,还是什么其他的
雪    币: 2112
活跃值: (5642)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
微启宇 2019-5-15 21:34
14
0
工厂镜像完整的线刷包  解锁BL可以先去万能的淘宝找找看有没有提供解锁服务的商家
游客
登录 | 注册 方可回帖
返回