keer_zu 发表于 2020-6-4 10:21

高通(Qualcomm)LK源码深度分析

在CIA VAULT 7 , NSA Shadow Broker 泄漏事件之后,信息安全也逐渐受到越来越多的关注,作为信息安全行业从业人员,除了参与这一场集体躁动之外,还需回归技术本身,对泄漏的资料和工具进行分析研究,以做到知己知彼。
Sec·Ret 团队在对所有泄漏资料进行分析后,形成了一系列技术研究**并会陆续进行发表,希望在增强自身技术储备的同时,也能够和同行多多交流,共同成长。
在Bootloader系列**中,我们对主流bootloader的前身高通 little kernel 进行了深入的源码分析,并对CIA 泄漏的cadmium.pdf文档中的三星bootloader漏洞进行了分析和复现,在此之外,对主流手机厂商如华为,三星,小米系列手机产品的bootloader进行了标准流程化安全审计,这些工作最后都会以**的形式呈现在bootloader研究系列中。由于自身技术有限,若**中有表述不准确的地方,忘同行指正。



在CIA VAULT 7 , NSA Shadow Broker 泄漏事件之后,信息安全也逐渐受到越来越多的关注,作为信息安全行业从业人员,除了参与这一场集体躁动之外,还需回归技术本身,对泄漏的资料和工具进行分析研究,以做到知己知彼。
Sec·Ret 团队在对所有泄漏资料进行分析后,形成了一系列技术研究**并会陆续进行发表,希望在增强自身技术储备的同时,也能够和同行多多交流,共同成长。
在Bootloader系列**中,我们对主流bootloader的前身高通 little kernel 进行了深入的源码分析,并对CIA 泄漏的cadmium.pdf文档中的三星bootloader漏洞进行了分析和复现,在此之外,对主流手机厂商如华为,三星,小米系列手机产品的bootloader进行了标准流程化安全审计,这些工作最后都会以**的形式呈现在bootloader研究系列中。由于自身技术有限,若**中有表述不准确的地方,忘同行指正。

在CIA VAULT 7 , NSA Shadow Broker 泄漏事件之后,信息安全也逐渐受到越来越多的关注,作为信息安全行业从业人员,除了参与这一场集体躁动之外,还需回归技术本身,对泄漏的资料和工具进行分析研究,以做到知己知彼。
Sec·Ret 团队在对所有泄漏资料进行分析后,形成了一系列技术研究**并会陆续进行发表,希望在增强自身技术储备的同时,也能够和同行多多交流,共同成长。
在Bootloader系列**中,我们对主流bootloader的前身高通 little kernel 进行了深入的源码分析,并对CIA 泄漏的cadmium.pdf文档中的三星bootloader漏洞进行了分析和复现,在此之外,对主流手机厂商如华为,三星,小米系列手机产品的bootloader进行了标准流程化安全审计,这些工作最后都会以**的形式呈现在bootloader研究系列中。由于自身技术有限,若**中有表述不准确的地方,忘同行指正。

git clone git://codeaurora.org/kernel/lk.git

切换到主分支。

git checkout -b mylk remotes/origin/master
配置编译环境。1

export PATH=$PATH:/path/to/arm-linux-androideabi-/bin
export TOOLCHAIN_PREFIX=arm-linux-androideabi-开始编译。编译的时候需要选择对应的目标平台编译,对应目标平台可以在 target 目录下找到。2
➔ ll -F target | grep '/

当前我们编译 msm8916 平台的 lk。

make msm8916 EMMC_BOOT=1
编译时可能遇到 make: *** No rule to make target build-msm8916/lib/openssl/crypto/bn/asm/armv4-mont.o, needed by build-msm8916/lk. Stop. 的问题。解决的方案是将 lib/openssl/crypto/bn/asm 中的 armv4-mont.s 文件重命名为 armv4-mont.S            即可。

lk 启动流程
[*]进行各种早期的初始化工作,包括 cpu, emmc, ddr, clocks, thread etc。
[*]判断进入 recovery 或 fastboot 的条件是否被触发。
[*]从 emmc 中获取 boot.img 并加载到指定内存区域 (scratch region)。
[*]从 scratch region 加载 kernel 到 KERNEL_ADDRESS 。
[*]从 scratch region 加载 ramdisk 到 RAMDISK_ADDRESS 。
[*]加载设备树到 TAGS_ADDRESS 。
[*]关闭 cache, interrupts, 跳转到 kernel。


lk 代码流程我们目前的研究是基于 msm8916 的代码流程来进行,在 msm8916 中不会使用到的代码暂时不分析。lk 是使用 arm 汇编 和 c 语言联合编译而成的,其中偏向硬件和底层的代码使用 arm 汇编 编写,而偏上层提供功能的代码则使用 c 编写。
入口点lk 代码的入口点是在 arch/arm 目录下的以 .ld 为后缀的 link 脚本文件中指定。一共有以下 4 个 link 脚本文件,指定的入口点均为位于 arch/arm/crt0.S 文件中的 _start 函数:

      system-onesegment.ld
      system-twosegment.ld
      trustzone-system-onesegment.ld
      trustzone-test-system-onesegment.ld


具体使用哪一文件在 platform/msm8916/rules.mk 中指定。
_start 最主要的作用是设置一些 cpu 的特性,然后初始化各种 c 程序运行需要的栈环境,完成后直接跳转到 kmian 函数进入 c 语言环境。

kmainkmain 函数位于 kernel/main.c 文件中, kmain 所做的工作可以用下面的流程图表示:



thread_init_earlythread_init_early 的实现位于 kernel/thread.c 文件中,其代码结构如下:
/**
* @briefInitialize threading system
*
* This function is called once, from kmain()
*/
void thread_init_early(void)
{
int i;

/* initialize the run queues */
for (i=0; i < NUM_PRIORITIES; i++)
    list_initialize(&run_queue);

/* initialize the thread list */
list_initialize(&thread_list);

/* create a thread to cover the current running state */
thread_t *t = &bootstrap_thread;
init_thread_struct(t, "bootstrap");

/* half construct this thread, since we're already running */
t->priority = HIGHEST_PRIORITY;
t->state = THREAD_RUNNING;
t->saved_critical_section_count = 1;
list_add_head(&thread_list, &t->thread_list_node);
current_thread = t;
}






drwxr-xr-x   9 takboostaff   306B May4 15:05 apq8084/
drwxr-xr-x   4 takboostaff   136B May4 15:05 armemu/
drwxr-xr-x   4 takboostaff   136B May4 15:03 beagle/
drwxr-xr-x   6 takboostaff   204B May4 15:05 fsm9010/
drwxr-xr-x   6 takboostaff   204B May4 15:05 fsm9900/
drwxr-xr-x   7 takboostaff   238B May4 15:05 mdm9607/
drwxr-xr-x   7 takboostaff   238B May4 15:05 mdm9615/
drwxr-xr-x   8 takboostaff   272B May4 15:05 mdm9625/
drwxr-xr-x   9 takboostaff   306B May4 15:05 mdm9635/
drwxr-xr-x   9 takboostaff   306B May4 15:05 mdm9640/
drwxr-xr-x   8 takboostaff   272B May4 15:05 msm7627_surf/
drwxr-xr-x   9 takboostaff   306B May4 15:05 msm7627a/
drwxr-xr-x   8 takboostaff   272B May4 15:05 msm7630_surf/
drwxr-xr-x   9 takboostaff   306B May4 15:05 msm8226/
drwxr-xr-x   9 takboostaff   306B May4 15:05 msm8610/
drwxr-xr-x   8 takboostaff   272B May4 15:05 msm8660_surf/
drwxr-xr-x10 takboostaff   340B May4 15:05 msm8909/
drwxr-xr-x   9 takboostaff   306B May4 15:05 msm8916/
drwxr-xr-x11 takboostaff   374B May4 15:05 msm8952/
drwxr-xr-x   9 takboostaff   306B May4 15:05 msm8960/
drwxr-xr-x   9 takboostaff   306B May4 15:05 msm8974/
drwxr-xr-x11 takboostaff   374B May4 15:05 msm8994/
drwxr-xr-x11 takboostaff   374B May4 15:05 msm8996/
drwxr-xr-x   6 takboostaff   204B May4 15:05 msmtitanium/
drwxr-xr-x   4 takboostaff   136B May4 15:03 osk5912/
drwxr-xr-x   3 takboostaff   102B May4 15:05 pc-x86/
drwxr-xr-x   3 takboostaff   102B May4 15:03 qemu-arm/
drwxr-xr-x   8 takboostaff   272B May4 15:05 qsd8250_ffa/
drwxr-xr-x   8 takboostaff   272B May4 15:05 qsd8250_surf/
drwxr-xr-x   8 takboostaff   272B May4 15:05 qsd8650a_st1x/
drwxr-xr-x   6 takboostaff   204B May4 15:03 sam7ex256/
drwxr-xr-x   7 takboostaff   238B May4 15:05 surf-msm7k/
drwxr-xr-x   6 takboostaff   204B May4 15:05 surf-qsd8k/

当前我们编译 msm8916 平台的 lk。

make msm8916 EMMC_BOOT=1
编译时可能遇到 make: *** No rule to make target build-msm8916/lib/openssl/crypto/bn/asm/armv4-mont.o, needed by build-msm8916/lk. Stop. 的问题。解决的方案是将 lib/openssl/crypto/bn/asm 中的 armv4-mont.s 文件重命名为 armv4-mont.S            即可。

lk 启动流程
[*]进行各种早期的初始化工作,包括 cpu, emmc, ddr, clocks, thread etc。
[*]判断进入 recovery 或 fastboot 的条件是否被触发。
[*]从 emmc 中获取 boot.img 并加载到指定内存区域 (scratch region)。
[*]从 scratch region 加载 kernel 到 KERNEL_ADDRESS 。
[*]从 scratch region 加载 ramdisk 到 RAMDISK_ADDRESS 。
[*]加载设备树到 TAGS_ADDRESS 。
[*]关闭 cache, interrupts, 跳转到 kernel。


lk 代码流程我们目前的研究是基于 msm8916 的代码流程来进行,在 msm8916 中不会使用到的代码暂时不分析。lk 是使用 arm 汇编 和 c 语言联合编译而成的,其中偏向硬件和底层的代码使用 arm 汇编 编写,而偏上层提供功能的代码则使用 c 编写。
入口点lk 代码的入口点是在 arch/arm 目录下的以 .ld 为后缀的 link 脚本文件中指定。一共有以下 4 个 link 脚本文件,指定的入口点均为位于 arch/arm/crt0.S 文件中的 _start 函数:

      system-onesegment.ld
      system-twosegment.ld
      trustzone-system-onesegment.ld
      trustzone-test-system-onesegment.ld


具体使用哪一文件在 platform/msm8916/rules.mk 中指定。
_start 最主要的作用是设置一些 cpu 的特性,然后初始化各种 c 程序运行需要的栈环境,完成后直接跳转到 kmian 函数进入 c 语言环境。

kmainkmain 函数位于 kernel/main.c 文件中, kmain 所做的工作可以用下面的流程图表示:



thread_init_earlythread_init_early 的实现位于 kernel/thread.c 文件中,其代码结构如下:
/**
* @briefInitialize threading system
*
* This function is called once, from kmain()
*/
void thread_init_early(void)
{
int i;

/* initialize the run queues */
for (i=0; i &lt; NUM_PRIORITIES; i++)
    list_initialize(&amp;run_queue);

/* initialize the thread list */
list_initialize(&amp;thread_list);

/* create a thread to cover the current running state */
thread_t *t = &amp;bootstrap_thread;
init_thread_struct(t, "bootstrap");

/* half construct this thread, since we're already running */
t-&gt;priority = HIGHEST_PRIORITY;
t-&gt;state = THREAD_RUNNING;
t-&gt;saved_critical_section_count = 1;
list_add_head(&amp;thread_list, &amp;t-&gt;thread_list_node);
current_thread = t;
}





keer_zu 发表于 2020-6-4 10:23

https://www.freebuf.com/news/135084.html

keer_zu 发表于 2020-6-5 11:55

https://gitlab.com/legato.io/lk
页: [1]
查看完整版本: 高通(Qualcomm)LK源码深度分析