【问题标题】:Syscall in android NDKandroid NDK 中的系统调用
【发布时间】:2018-06-02 09:59:08
【问题描述】:

我尝试使用this syscall macro for arm_64

它适用于 SYS_open、读取和关闭。我可以正常看到文件内容。

之后,Android APK 崩溃并显示以下消息:

A/libc:检测到堆栈损坏 A/libc:致命信号 6 (SIGABRT) 在 0x00007689 (code=-6), 线程 32141 (Thread-2910)

有人知道怎么解决吗?

【问题讨论】:

  • 你能发一个minimal reproducible example这个吗?代码以及你是如何编译它的?除非您通过将错误的指针传递给read 来创建缓冲区溢出,否则这将如何破坏堆栈并不明显。
  • @PeterCordes 嘿彼得,我期待您在另一个线程(聊天)中的回答,我已经在那里写了详细信息。我今天准备一个最小的例子。
  • 我没有无限的时间(很遗憾)。如果我能解决这个问题,我会在你的另一个问题的答案中添加细节,而不是埋在某个地方的聊天中。如果您的另一个问题首先说“C++”,我不会只给您一个 C 答案。
  • @PeterCordes 我知道,对不起。但我需要一点帮助。最小代码:godbolt.org/g/KFpQyf,但它给出了一些注册错误。我已经在 Android NDK for arm_64 中尝试过这个,它可以编译
  • 有人可以帮忙吗?

标签: android assembly android-ndk system-calls


【解决方案1】:

您发布的 Godbolt 链接上的代码中至少有一个错误。这些语句导致缓冲区溢出(周围的代码和 if() 条件被删除。)

char buffer[2048];

    length = syscall_read(fd, buffer, sizeof(buffer));

        buffer[length] = 0;
如果sys_read 返回2048,

buffer[length] = 0; 访问数组外部。正如手册页所述,read() 尝试读取count 字节,而不是count-1。如果数组被分配在重要的下方,这可能会导致您的堆栈损坏。

如果您想将 0 终止符用作 C 隐式长度字符串,而不是使用 writememcpy 或其他任何内容的显式长度缓冲区+大小,则必须为 0 终止符留出空间。请记住,文件数据可以包含0 字节。

像往常一样,使用调试器,并确保您的代码与正常的系统调用以及内联包装器一起工作。

【讨论】:

  • 谢谢,我已将syscall_read 的第三个参数修改为sizeof(buffer) - 1问题依旧。实际上文件长度小于 1024,甚至没有接近 2048。我仍然有堆栈损坏。
  • @Phillip:你strace它是为了确保系统调用成功吗?或者将内容注释掉,直到问题消失,然后查看该行的代码踩到了哪些内存? (假设在禁用优化的情况下问题仍然存在,因此每一行都编译为单独的 asm 块)。如果您通常调用read() 而不是您的内联版本,问题是否仍然存在?即使我愿意,我也没有任何 Android 开发环境来测试它。您的问题甚至没有您的代码,更不用说来自调试器的任何信息,如果有人可以帮助您,请 IDK。
  • 谢谢,我已经重命名了类型并在 openat 之前添加了 faccessat 并且它开始正常工作:)
  • @Phillip:添加faccessat 可能只是一个巧合,不同的代码生成隐藏了你有的任何错误。如果类型错误,更改类型可能会产生差异,否则只是占用更多或更少的堆栈空间可能再次隐藏错误。
  • 我将对其进行深入测试,如果遇到任何类似的错误,我将在此处添加结果。现在它似乎工作了,我已经尝试了 getpid exit 和 open read write close 调用 100 次,看起来还可以
猜你喜欢
  • 1970-01-01
  • 2012-05-24
  • 1970-01-01
  • 2014-05-21
  • 2011-06-11
  • 1970-01-01
  • 2014-12-25
  • 2016-11-08
  • 1970-01-01
相关资源
最近更新 更多