这是情况:

我正在通过使用挂钩ioctl()系统调用的LD_PRELADED模块来分析与驱动程序的程序交互。我正在使用的系统(嵌入Linux 2.6.18内核)幸运地将编码到“请求”参数的数据的长度进行了长度,因此我可以愉快地将IOCTL数据带有正确的长度。

但是,很多这些数据都对其他结构都有指示,我不知道这些数据的长度(毕竟这是我正在调查的内容)。因此,我正在将数据扫描以获取指针,并在该位置倾倒数据。我担心,如果指针接近细分边界,我的代码可能会使我的代码开放到segfaults(我的早期测试似乎表明是这种情况)。

因此,我想知道我可以在试图解雇之前先进行空虚地检查当前过程是否拥有特定的偏移?这甚至可能吗?

编辑:只是一个更新,因为我忘了提及可能非常重要的东西,但目标系统是基于MIP的,尽管我还在X86机器上测试了我的模块。

有帮助吗?

解决方案

打开文件描述符 /dev/null 并尝试 write(null_fd, ptr, size). 。如果返回-1,则 errno 设置 EFAULT, ,内存无效。如果返回 size, ,记忆是安全阅读的。通过一些Posix发明,可能有一种更优雅的方法来查询记忆有效性/权限,但这是经典的简单方法。

其他提示

如果您的嵌入式Linux已安装/Proc/Filesystem,则可以解析/proc/proc/self/maps文件,并验证指针/偏移量。地图文件包含该过程的内存映射,请参阅 这里

我知道没有这种可能性。但是您也许可以取得类似的成就。作为 man 7 signal 提及, SIGSEGV 可以被抓住。因此,我认为你可以

  1. 首先说明一个已知为指针的字节序列
  2. 访问另一个字节,在某个时候触发 SIGSEGV
  3. SIGSEGV的处理程序,标记一个在步骤2的循环中检查的变量
  4. 退出循环,此页面已完成。

有几个问题。

  • 由于几个缓冲区可能生活在同一页面中,因此您可能会输出您认为的一个缓冲区,实际上是几个缓冲区。你 可能 也能够通过 LD_PRELOADafaik的电围栏会导致应用程序为每个动态分配的缓冲区分配整个页面。因此,您不会输出几个缓冲区认为它只是一个缓冲区,但是您仍然不知道缓冲区的结束位置,并且会在最后输出很多垃圾。此外,这种方法无法帮助基于堆栈的缓冲区。
  • 您不知道缓冲区在哪里结束。

未经测试。

您不能只检查段边界吗? (我猜是通过段边界,您的意思是页面边界?)

如果是这样,则对页面边界进行了很好的划界(4K或8K),因此对地址的简单掩盖应处理。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top