【问题标题】:gcc - how to detect pointer-based memory accessgcc - 如何检测基于指针的内存访问
【发布时间】:2023-03-21 06:41:01
【问题描述】:

我专注于 micropython,特别是分支 dynamic-native-modules

此功能将在未来允许您将 C/C++ 函数编译为原生 .obj,并将其与 .py 接口一起打包,从而大幅提升速度。

太棒了!但问题是,如果您使用的是 RTOS,doesn't have virtual memory,那么任何正在执行的本机代码都可以访问地址空间的任何部分,包括外围设备、RTOS 的状态等。

您不希望用户能够执行以下操作:

void user_func()
{
/* point to arbitrary memory, potentially the reset registers, flash erase . . . you get the point */
  int * a = (int*)0x1234;  
  *a = 0x10110000; // DESTROY!!!
}

即使是以下情况也应该被禁止:

void user_func()
{
  int a;
  (int*)(&a-1000) = 0x10010111;
}

解决方案?

  • 创建自己的gcc 版本(适用于每种二进制格式)
  • 反编译.obj文件并检测指针的使用(针对每种二进制二进制格式)

反馈意见

我知道阻止恶意用户可能是不可能的,但这不是第一个担心。我们要停止善意但意外的代码。如果不可能停止每一个案例,那ok

如果我们可以禁止/检测显式指针访问并简单地提供有关数组使用的警告,那仍然非常有价值。

警告:您正在使用数组!确保您不会越界

【问题讨论】:

  • 这是 XY 问题的根源。
  • 使用数组并在末尾运行也将在内存中的某个位置运行,也无需显式使用指针。没有任何内存访问的 C/C++ 将有所帮助...
  • 如果特定的 OBJ 可以做一些事情,即使你禁止使用特定语言做这些事情,恶意用户也会想方设法通过其他方式制作这样的 OBJ。这意味着您的系统架构在要求方面存在缺陷。
  • 如果您认为静态分析是检测基于指针和数组的内存访问的唯一可行方法,请投票支持@EugeneSh 的原始评论。Anyway. You can't remove the use of pointers from C without defeating it's completeness. And of course you can't remove it from obj, because it looks like a regular memory access. You can think of some kind of static analysis tool to analyze the compiled program and warning about dangerous constructs. It won't be easy, though.跨度>
  • 是的,对于所有这些情况,您都可以使用模拟器、仿真器、valgrind、软件 mmu(检查 6 执行)等等。所以只要这样做,如果你真的想使用 C++... valgrind 必须在另一个非嵌入式目标上的代码的不同编译中使用。但是应该可以发现越界问题和被操纵的指针。

标签: c++ c gcc decompiling


【解决方案1】:

你最好的机会是一个 GCC 插件,它查看前端生成的 GENERICGIMPLE IR 并实施你想要的策略。根据您希望接受的政策和源代码,这可能需要大量工作并且非常困难。

如果您想要一种纯粹基于语法或基于类型的方法(简单地拒绝所有指针算术),那么具有 AST 的 Clang 比 GCC 更容易使用。

【讨论】:

  • IRs 是什么? (更多占位符)
【解决方案2】:

可能有一种做你想做的事的方法——只要你能避免诚实的错误,而不是故意破坏事情。

首先,您接受 C++ 核心指南并使用工具的支持:https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#S-tools

出于您的目的,它将阻止您的代码在非库代码中使用原始指针和指针算法。时期。核心指南的作用远不止于此,但这与您的问题有关。

然后,您在代码上执行一个简单的 grep 以确保它没有使用受指南祝福的指针 - 这将是一个或多或少简单的 grep 的情况。

【讨论】:

    【解决方案3】:

    在实践中,这是不可能的。

    您可能会考虑更改编译(例如,使用 GCC 插件,如 Florian Weimer's answer 中提到的)以检查对数组的每次访问,但这会使生成的代码明显变慢。你的原生硬件已经够慢了,你不想让它变得更慢。

    Python 并不是完全正确的源语言。它的动态类型已经让它变得很慢了。

    也许您可能会考虑使用静态类型语言,例如 Ocaml(结合 JIT 或 AOT 编译库,例如 GCCJIT 等)。类型系统(及其推断)提高了生成代码的安全性(和速度),并且付出了很多努力(几年,可能值得攻读博士学位 因为你需要做新的研究)你可以改进类型推断,甚至推断出数组索引永远不会越界的情况(甚至不需要索引边界检查)。

    在大多数情况下,升级硬件(升级到 Raspberry Pi 风格的硬件,带有 MMU,并且可能能够拥有带有一些虚拟内存的真实操作系统)可能是最实用的方法

    PS。请注意Rice's theorem。大多数静态源分析无法可靠和良好地工作(从技术角度来说是健全和完整的)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-28
      • 1970-01-01
      • 2020-10-20
      • 1970-01-01
      • 1970-01-01
      • 2021-04-14
      • 1970-01-01
      相关资源
      最近更新 更多