【问题标题】:Code execution exploit Cortex M4代码执行利用 Cortex M4
【发布时间】:2018-08-01 10:53:35
【问题描述】:

为了测试 MPU 和利用漏洞,我想从运行在我的 STM32F4 开发板上的本地缓冲区执行代码。

int main(void)
{
  uint16_t func[] = { 0x0301f103, 0x0301f103, 0x0301f103 };
  MPU->CTRL = 0;
  unsigned int address = (void*)&func+1;
  asm volatile(
    "mov r4,%0\n"
    "ldr pc, [r4]\n"
    :    
    : "r"(address)    
  ); 
  while(1);
}

首先,我首先打开 MPU。在 func 中存储了我的指令。在 ASM 部分中,我将地址(拇指为 0x2001ffe8 +1)加载到程序计数器寄存器中。使用 GDB 单步执行代码时,在 R4 中存储正确的值,然后将其传输到 PC 寄存器。但是我最终会进入 HardFault Handler。

编辑: 堆栈如下所示:

0x2001ffe8: 0x0301f103  0x0301f103  0x0301f103  0x2001ffe9

内存中的指令是正确的。 Cortex 权威指南说区域 0x20000000–0x3FFFFFFF 是 SRAM 并且“这个区域是可执行的, 所以你可以在这里复制程序代码并执行它”。

【问题讨论】:

    标签: arm exploit cortex-m


    【解决方案1】:

    您将 32 位值分配给 16 位数组。

    您的指令不会终止,它们会继续运行到 ram 中的任何内容,因此会崩溃。

    您没有将数组的地址加载到程序计数器中您正在将数组中的第一项加载到程序计数器中,这将崩溃,您创建了一个间接级别。

    查看 BX 指令而不是 ldr pc

    您没有将数组声明为静态数组,因此可以将数组优化为无效且未使用,因此这可能会导致它崩溃。

    编译器还应该抱怨您正在将 void* 分配给无符号变量,因此需要在那里进行类型转换。

    作为一种习惯,我建议使用 address|=1 而不是 +=1,在这种情况下,两者都可以。

    【讨论】:

    • 推荐使用 stdint.h 中的 intptr_t 作为整数类型,保证能够保存指针(前提是您使用 >=C99,实际上每个人都应该在 2018 年使用它!)而不是无符号诠释。
    猜你喜欢
    • 1970-01-01
    • 2018-09-29
    • 2015-03-12
    • 2015-02-24
    • 2020-03-22
    • 2013-05-22
    • 2020-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多