转载

技术分享:逆向三星S6的调制解调器

技术分享:逆向三星S6的调制解调器

在这篇文章中,我们会着重探讨三星S6调制解调器SM-G920F。我对这个设备的modem.bin文件结构非常好奇。虽然我还没能把这个文件完全解密/去模糊,但是希望这篇文章可以快速协助你了解这个文件并将其解码。

获取文件

下载三星 SM-G920F Galaxy S6 固件

解压文件

我使用OS X上的UnZip 5.52出现了点问题(PK compat.error),所以我在Ubuntu 15.04使用了UnZip 6.00代替。

unzip <firmware.zip> mv <firmware.tar.md5> <firmware.tar> tar xvf <firmware.tar>

你应该以这些内容为结束:

boot.img cache.img cm.bin hidden.img modem.bin recovery.img sboot.bin system.img

解构modem.bin

字节顺序:我们在modem.bin中看到的内容多数是由Little-Endian格式组成。最高有效字节位位于最高内存地址。举个例子:如果你看到下面的BOOT的SIZE,字节顺序是 48 2B 00 00,但是读取和发送都只有0x2B48作为非零数字前的任何十进制数。

TOC[0] = TOC

在十六进制编辑器中打开modem.bin,让我看看看这个文件发生了什么。

第一个2×200字节叫做TOC,我要提出一种非常有理想的猜测,它代表内容的表。它的功能是提供有关文件本身的信息,包括所有部分:TOC,BOOT,MAIN,NV 和 OFFSET,以及提供的指向这些部分的索引。

技术分享:逆向三星S6的调制解调器

虽然上面的截图只显示了地址为0000h到0090h,其余字节都是0填充0×200字节。

TOC[1] = BOOT

如果你想要隔离文件中的BOOT部分,你需要计算基于头文件中的SIZE参数的偏移量。所以它看起来如下:

dd if=modem.bin bs=1 skip=512 count=11080 of=modem.bin_boot  # calculated by using the 0x200 byte offset in decimal. skip=512   # calculated by using the 0x2B48 byte SIZE of BOOT in decimal. count=11080

技术分享:逆向三星S6的调制解调器

技术分享:逆向三星S6的调制解调器

TOC[2] = MAIN

和BOOT一样,你要使用下面的dd命令隔离MAIN:

dd if=modem.bin bs=1 skip=11592 count=40394816 of=modem.bin_main

技术分享:逆向三星S6的调制解调器

技术分享:逆向三星S6的调制解调器

*VERSION 是一种基于分析很多固件之后的猜想。  确保能够逆向 cbd prepare_boot_args 或相关函数确定上面的分析是正确的。

TOC[3] = NV

技术分享:逆向三星S6的调制解调器

技术分享:逆向三星S6的调制解调器

TOC[4] = OFFSET

我从来没看过cbd进程或者发送这部分,所以我假设它的使用是本地到modem.bin文件而不是到CP。也许BOOT正在以某种方式使用它。

解码BOOT

当查看BOOT代码时,你可能已经注意到了一些模式。下面我要告诉大家我从Dang et al的Practice Reverse Engineering 书 中学到的窍门:

The ability to recognize instruction boundaries in a seemingly random blob of data is important. Maybe you will appreciate it later.

在看起来是随机的blob的数据中识别命令界限的能力非常重要!你之后会非常感谢这个技能。

他说的非常棒是不是!

让我们重新回顾以下BOOT的chunk:

技术分享:逆向三星S6的调制解调器

TL;DR – 这些ARM指令,我们接下来会反汇编sh*t。

查看这个部分很容易发现它的模式。几乎每4个字节都以0xE*结束-结果ARM分支指令使用最高位比特作为 条件码 。这些码控制指令的执行,并且通常基于在 应用程序状态寄存器 或APSR中的标志。所以,如果你想要告诉指令经常执行,你将使用AL条件,这个条件是1110b或者0xE。如果你有crackmes的经验,当你想改变一个条件JMP(x86)或B(ARM)的状态类似于转化Z或者0标志。

TODO:在文章后面这部分,我们将介绍BOOT逆向

CP BOOT过程

下面内容是基于多次crash调制解调器的,逆向cbd和BOOT。

cbd  # CP Boot Daemon lives in /sbin on the device CP   # Cell Processor or Modem AP  # Application Processor, where Android OS lives BOOT  # BOOT section of the modem.bin

/dev/umts_boot0

由用于多数涉及CP boot链的I/O的rild打开。

misc_ioctl:  IOCTL_MODEM_ON  IOCTL_MODEM_BOOT_ON  IOCTL_MODEM_DL_START  # Starts `mem_start_download`  IOCTL_MODEM_SET_TX_LINK  # Sets Boot Link / Main Link  IOCTL_MODEM_FW_UPDATE  # Called after stages are sent to CP  IOCTL_MODEM_BOOT_OFF  # Sent after Stage 3 is sent to CP  IOCTL_MODEM_BOOT_DONE  # Final IOCTL for CP boot chain

start_shannon333_boot

shannon_normal_boot

LLI STATUS mount

prepare_boot_args

技术分享:逆向三星S6的调制解调器

mem_start_download

通过抓取modem.bin的BOOT部分IOCTL_MODEM_DL_START触发,然后将它发送给CP启动boot代码。代码似乎来自Android内核中的link_device_bootdump.c。

magic == 0x424F4F54 or BOOT

技术分享:逆向三星S6的调制解调器

std_dl_send_bin

通过BOOT代码发送解析的modem.bin到CP RAM。我觉得CMD = 是 private IOCTL command ID。

第1阶段:0×200字节头

技术分享:逆向三星S6的调制解调器

第二阶段:0×2686040字节 MAIN

技术分享:逆向三星S6的调制解调器

为MAIN检查CRC

我猜它是发送MAIN CRC到BOOT进行验证

技术分享:逆向三星S6的调制解调器

第三阶段:0×100000字节 NVRAM

技术分享:逆向三星S6的调制解调器

check_factory_log_path

设置 /sdcard/log/ ,SM-G920F没有SD卡槽,所以使用一个拙劣的虚拟SD守护进程,这个守护进程看起来没有正常工作,因为我没有在目录中找到任何存储信息。设置这个的方法应该非常简单。

std_udl_req_resp

我不确定为什么 cbd 调用了这些函数, 但是调用是在 std_dl_send_bin 之前进行的。

服务模式功能

服务模式功能:三星在逆向过程中提供了很多帮助。

# Enable CP Debugging am broadcast -a android.provider.Telephony.SECRET_CODE -d android_secret_code://66336  <device resets>  # Enable CP RAMDUMP am broadcast -a android.provider.Telephony.SECRET_CODE -d android_secret_code://9090  <device resets>  # Cause CP RAMDUMP am broadcast -a android.provider.Telephony.SECRET_CODE -d android_secret_code://CP_RAMDUMP  # SysDump, Copy to SD Card am broadcast -a android.provider.Telephony.SECRET_CODE -d android_secret_code://9900

我还需要弄清楚这些东西是如何组织的。希望这边文章能够帮助有兴趣的同学们进行研究。

*原文: Arm.ninja FB小编/FireFrank编译,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)

原文  http://www.freebuf.com/articles/terminal/98495.html
正文到此结束
Loading...