更改堆栈地址后ARM系统崩溃

逆向工程 调试 linux 手臂
2021-06-16 03:11:05

-- 使用问题的最新更新进行编辑,尚未解决:( --

在玩 ARM 嵌入式 Linux 系统(版本 3.8.13)时,出于好奇,我创建了一个小的“调试”内核模块。

这个“调试”模块将另一个内核模块中的特定流程分支到这个“调试”模块中的一个函数,该函数执行一些逻辑,然后和平地恢复执行。

为了避免堆栈区域的混乱,第一个执行的逻辑是将 SP 更改为指向“调试”模块代码部分内的空白区域

系统在执行后几秒钟崩溃mov sp, r2,并进入无限循环。r2保存地址到空白区域)。

请注意,崩溃发生在“调试”模块执行任何与堆栈相关的操作码(或实际上任何其他操作码,就此而言)之前。

所以我进行了以下检查:

  • 确保地址是 4 字节对齐的
  • 将区域更改为可写,并且足够大以保存保存在堆栈中的完整上下文切换(大约 0x300 字节)
  • sp少量更改值 (+-0x100) - 不会使系统崩溃
  • 更改sp为某个任意值 - 使系统崩溃。
  • sp暂时更改然后立即恢复其值不会使系统崩溃
  • sp暂时更改、执行 STMFD 操作然后立即恢复sp的值不会使系统崩溃!

从上一个测试中可以清楚地看出,当发生上下文切换时,一些值被保存在堆栈中。如果它指向那个空闲区域,系统就会崩溃

在空闲区域使用堆栈操作似乎没有任何问题,但是当发生某些上下文切换时,系统崩溃了。

可行的想法

  • sp寄存器的可能值是否有限制(也许是内核配置?地址的特定位?)
  • 当在当前模块之外使用,代码部分有某种保护措施可以防止被用作堆栈
  • 上下文切换需要超过 0x300 字节的空间?

谢谢!

1个回答

如果您将堆栈指针设置为代码部分中的某个点,则该页面很可能没有启用写访问权限,因此当处理器开始在堆栈上写入时,您会立即生成权限数据中止错误。

您需要将堆栈指针设置为内存中具有读/写权限设置而不是只读权限的有效页面。查看ARM架构参考手册虚拟内存系统架构章节下的内存访问控制部分。