arm - 代码执行利用 Cortex M4
问题描述
为了测试 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,并且“该区域是可执行的,因此您可以在此处复制程序代码并执行它”。
解决方案
您将 32 位值分配给 16 位数组。
您的指令不会终止,它们会继续运行到 ram 中的任何内容,因此会崩溃。
您没有将数组的地址加载到程序计数器中您正在将数组中的第一项加载到程序计数器中,这将崩溃,您创建了一个间接级别。
查看 BX 指令而不是 ldr pc
您没有将数组声明为静态,因此可以将数组优化为已死且未使用,因此这可能会导致它崩溃。
编译器还应该抱怨您将 void* 分配给无符号变量,因此需要在那里进行类型转换。
作为一个习惯,我建议使用 address|=1 而不是 +=1,在这种情况下,两者都可以。
推荐阅读
- java - 在java中通过println打印字符序列时出错
- iis - 在 ASP.Net Core 2 中刷新 Window 身份验证用户的用户声明和角色
- bash - Is my bash script vulnerable to command injection?
- command-line - 如何从终端编辑 py 文件?
- python - pandas won't import despite trying many versions of python
- javascript - 图像无法正确加载
- python - 使用下拉列表过滤带有 django-filters 的 django-tables2 表
- javascript - 我是否必须取消订阅由 Angular 组件创建的订阅?
- javascript - 如何安全地为 bigquery 节点插入转义用户输入?可以在 bigquery.insert 节点库上使用参数化查询吗?
- java - 通过共享首选项从另一个活动 onCheckedChange 更改按钮的背景颜色(?)