硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2207|回复: 15
收起左侧

[MDK] 关于bootloader为啥需要汇编,转发一篇大神的文章

  [复制链接]

4

主题

126

回帖

138

积分

初级会员

积分
138
发表于 2024-8-6 12:00:22 | 显示全部楼层 |阅读模式

震惊!这个隐藏的Bootloader漏洞究竟有多少人中招?
GorgonMeducer 傻孩子’是LVGL项目,这篇文章解决了我很多疑惑,特转载过来。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117529
QQ
发表于 2024-8-6 12:48:02 | 显示全部楼层
谢谢楼主分享。
回复

使用道具 举报

2

主题

15

回帖

21

积分

新手上路

积分
21
发表于 2024-8-9 20:15:39 | 显示全部楼层
    .section .text
    .global JumpToApp

JumpToApp:
    /* 输入参数:
       R0 - 应用程序的起始地址 (App地址)
    */

    /* 1. 禁用所有中断 */
    cpsid   i               /* 禁用中断 */

    /* 2. 设置主堆栈指针(MSP) */
    LDR     SP, [R0]        /* 设置SP = *(App地址) */

    /* 3. 获取复位向量(应用程序入口地址) */
    LDR     R1, [R0, #4]    /* R1 = *(App地址 + 4),即复位向量 */

    /* 4. 跳转到应用程序 */
    BX      R1              /* 跳转到应用程序 */
请教一下 这是汇编跳转函数,MDK如何加载这个函数,需要重新新建一个.s文件吗
回复

使用道具 举报

1

主题

15

回帖

18

积分

新手上路

积分
18
发表于 2024-8-10 08:41:10 来自手机 | 显示全部楼层
看不明白,什么条件下能复现这个漏洞,app程序里局部变量不都会初始化再用,返回后不管了吗。怎么会影响程序呢
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117529
QQ
发表于 2024-8-10 10:15:39 | 显示全部楼层
ask张 发表于 2024-8-9 20:15
.section .text
    .global JumpToApp

对,这个要新建一个.S汇编文件。
回复

使用道具 举报

10

主题

56

回帖

86

积分

初级会员

积分
86
发表于 2024-8-11 19:09:10 | 显示全部楼层
搞单片机,汇编也需要掌握吗,
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117529
QQ
发表于 2024-8-12 09:26:38 | 显示全部楼层
quanshimutou 发表于 2024-8-11 19:09
搞单片机,汇编也需要掌握吗,

可以不用,xxx.S里面的这种常见代码和RTOS的移植文件,这两个能看懂就够了。
回复

使用道具 举报

5

主题

269

回帖

284

积分

高级会员

积分
284
发表于 2024-8-12 16:29:13 | 显示全部楼层
看了下文章,我把我理解的分享出来,不确定是不是原文想表达的意思
它这个问题的意思是,跳转到app时指向的栈顶地址在一通操作后指向了错误的地址,这在app栈顶处于sram末尾时会导致总线错误。
比如app文件记录的栈顶是0x20002000,由于跳转前的错误,内核拿到的栈顶是0x20002004,如果此时芯片的ram边界刚好是0x20002000,那压栈的时候就会出问题。

但是这个问题并不100%出现,因为app编译出来的栈顶地址并不一定在ram边界上,实际栈顶地址是根据ram消耗量来定的,越大越复杂的工程,栈顶地址就越靠近ram边界,也就越容易出现这个问题。

回复

使用道具 举报

21

主题

481

回帖

544

积分

金牌会员

积分
544
发表于 2024-8-12 16:47:11 | 显示全部楼层
应该是跳转到APP的startup地址吧,毕竟main之前还是有很多步骤的
回复

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 2024-8-12 19:41:18 | 显示全部楼层
更简单一点,把这个跳转函数用纯汇编实现,用寄存器R0传参,调用的时候把APP向量表首地址作为实参传进去就可以了
回复

使用道具 举报

4

主题

126

回帖

138

积分

初级会员

积分
138
 楼主| 发表于 2024-8-13 08:36:15 | 显示全部楼层
大家可以参考ST SBSFU 2.6.2的实现
[Asm] 纯文本查看 复制代码
      PRESERVE8
      THUMB
      AREA    |.text|, CODE, READONLY

      EXPORT SVC_Handler
SVC_Handler
        IMPORT MPU_SVC_Handler
        MRS r0, PSP
        PUSH {LR}
        BL MPU_SVC_Handler
        POP {PC}

      AREA    |.SB_HDP_Code|, CODE, READONLY
      EXPORT jump_to_function
jump_to_function
        ; assume R1 R2 are useless
        LDR R1, [R0]
        LDR R2, [R0,#4]
        MOV SP, R1
        BX  R2

      EXPORT launch_application
launch_application
        ; return from exception to application launch function
        ; R0: application vector address
        ; R1: exit function address
        ; push interrupt context R0 R1 R2 R3 R12 LR PC xPSR
        ;MOV R2, #0x01000000 ; xPSR activate Thumb bit
        MOVS R2, #0x1
        LSLS R2, R2, #24
        PUSH {R2} ; FLAGS=0
        MOVS R2, #1
        BICS R1, R1, R2  ; clear least significant bit of exit function
        PUSH {R1}  ; return address = application entry point
        MOVS R1, #0 ; clear other context registers
        PUSH {R1} ; LR =0
        PUSH {R1} ; R12 =0
        PUSH {R1} ; R3 = 0
        PUSH {R1} ; R2 = 0
        PUSH {R1} ; R1 = 0
        ; set R0 to application entry point
        PUSH {R0} ; R0 = application entry point
        ; set LR to return to thread mode with main stack
        ;MOV LR, #0xFFFFFFF9
        MOVS R2, #6
        MVNS R2, R2
        MOV LR, R2
        ; return from interrupt
        BX LR
        END

C语言调用
[C] 纯文本查看 复制代码
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    /* Reset FPU context */
    SCB->CPACR &= ~((3UL << 10*2)|(3UL << 11*2));  /* reset CP10 and CP11 Full Access */
    FPU->FPCCR &= ~FPU_FPCCR_LSPEN_Msk; /* Disable automatic lazy state preservation for floating-point context */
    FPU->FPCCR &= ~FPU_FPCCR_LSPACT_Msk; /* Clear the lazy state preservation for floating-point context */
#endif /* (__FPU_PRESENT == 1) && (__FPU_USED == 1) */

    /* clear process stack & unprivileged bit */
    __set_CONTROL(__get_CONTROL() & ~0x3U);

    /* returns from interrupt into application */
    launch_application(Address, (uint32_t)jump_to_function);
回复

使用道具 举报

3

主题

295

回帖

304

积分

高级会员

积分
304
发表于 2024-8-13 08:48:51 | 显示全部楼层
tdh03z 发表于 2024-8-10 08:41
看不明白,什么条件下能复现这个漏洞,app程序里局部变量不都会初始化再用,返回后不管了吗。怎么会影响程 ...

因为编译器识别不了在线汇编,所以某些编译条件下__set_MSP这条汇编会插入到不该出现的地方
回复

使用道具 举报

3

主题

295

回帖

304

积分

高级会员

积分
304
发表于 2024-8-13 10:31:48 | 显示全部楼层
turnip 发表于 2024-8-13 08:36
大家可以参考ST SBSFU 2.6.2的实现[mw_shl_code=asm,true]      PRESERVE8
      THUMB
      AREA    |. ...

学到了,感谢分享
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117529
QQ
发表于 2024-8-13 10:44:22 | 显示全部楼层
DX3906 发表于 2024-8-12 16:29
看了下文章,我把我理解的分享出来,不确定是不是原文想表达的意思
它这个问题的意思是,跳转到app时 ...

实际上这个就是MDK AC6做0级优化生成代码问题,别的优化和MDK AC5都没有这个问题。

使用AC6,0级优化,将这个变量做成全局变量也可以解决,不需要用汇编。

早期的时候,我们就倒腾过一次这个问题。


回复

使用道具 举报

0

主题

18

回帖

18

积分

新手上路

积分
18
发表于 2024-8-14 16:03:05 | 显示全部楼层
DX3906 发表于 2024-8-12 16:29
看了下文章,我把我理解的分享出来,不确定是不是原文想表达的意思
它这个问题的意思是,跳转到app时 ...

实质问题是按照AAPCS,用户不应该修改栈顶指针。

实际上大部分编译器的StackTop都是RAM尾。根据消耗量来定的是Heap。不出问题的原因嘛,还有种可能,大部分人用的都不是满配器件。标称的RAM尾后面还是有RAM的。
回复

使用道具 举报

1

主题

8

回帖

11

积分

新手上路

积分
11
发表于 2024-8-15 22:33:44 | 显示全部楼层

这个就是编译器优化出现的指令乱序,不光是这个地方会出现,在业务逻辑的代码里也会出现,你的优化开的越高时,越容易出现

比如

int x,y,z;

void foo() {
x = z;
y= 1;
}

实际上,编译器可能会将 y=1 放到 x=z 前面执行,因为两个操作本来就没有冲突

这个问题可以通过增加 内存屏障 来避免

上面的foo函数改成这样就行了:

x = z;
asm volatile("": : :"memory");
y= 1;

在 gcc 里通过增加 asm volatile("": : :"memory") 可以设置内存屏障,限制编译器在编译期的行为,避免编译器帮你 ”好心“ 打乱指令

这句话 ‘asm volatile("": : :"memory")’ 就是设置屏障,类似于一个结界(也可以理解为分界线 ------- ),等于告诉编译器,“分界线后的代码不要给我挪到分界线前了”,这样编译器就不会好心办坏事

参考:什么是内存屏障(Memory Barriers) - CharyGao - 博客园 (cnblogs.com)

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 13:45 , Processed in 0.047926 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表