【问题标题】:How does a debugger peek into another process' memory?调试器如何窥探另一个进程的内存?
【发布时间】:2014-09-25 07:06:56
【问题描述】:

当每个进程都有自己的私有内存空间而外部进程无法访问时,调试器如何访问进程的内存空间?

例如,我可以使用 gdb -p <pid> 将 gdb 附加到正在运行的进程
我可以通过 gdb 访问这个进程的所有内存。

gdb 是如何做到这一点的?

我阅读了 SO 中的相关问题,但似乎没有帖子回答这一点。

【问题讨论】:

  • 这实际上取决于所涉及的调试器以及它附加到目标进程的方式。您可能希望缩小范围(例如,当使用 gdb 启动进程时)。我没有投票赞成关闭,但您可以通过这种方式缩小范围,或者命名您想了解更多的方法(例如远程调试)。

标签: c++ debugging unix memory


【解决方案1】:

当每个进程都有自己的私有内存空间,没有外部进程可以访问...

这是错误的。具有正确权限并使用正确 API 的外部进程可以访问其他进程的内存。

【讨论】:

    【解决方案2】:

    由于这个问题被标记为 Linux 和 Unix,我将稍微扩展一下 David Scwartz 所说的内容,简而言之,“操作系统中有一个 API”。同样的基本原理也适用于 Windows,但实际实现不同,虽然我怀疑操作系统内部的实现做同样的事情,但没有真正的方法知道这一点,因为我们无法检查 Windows 的源代码(但是,我们可以了解操作系统和处理器的工作原理,从而弄清楚必须发生的事情!)

    Linux 有一个名为ptrace 的函数,它允许一个进程(在对权限进行一些检查之后)以各种方式检查另一个进程。这是一个调用,但第一个参数是“你想做什么”。以下是一些最基本的示例 - 还有几十个其他不太“常见”的操作:

    • PTRACE_ATTACH - 连接到进程。
    • PTRACE_PEEKTEXT - 查看附加进程的代码内存(例如反汇编代码)
    • PTRACE_PEEKDATA - 查看附加进程的数据内存(显示变量)
    • PTRACE_POKETEXT - 写入进程的代码内存
    • PTRACE_POKEDATA - 写入进程的数据内存。
    • PTRACE_GETREGS - 复制当前寄存器值。
    • PTRACE_SETREGS - 更改当前寄存器值(例如,set variable x = 7 的调试命令,如果 x 恰好在寄存器中)

    在 Linux 中,由于内存“都是一样的”,PTRACE_PEEKTEXTPTRACE_PEEKDATA 实际上是相同的功能,因此您可以在代码中为 PTRACE_PEEKDATA 提供一个地址,并在堆栈上为PTRACE_PEEKTEXT 它会很乐意为您复制回来。内存在 DATA 内存和 CODE 内存之间“分割”的 OS/处理器组合是有区别的。大多数现代操作系统和处理器都没有这种区别。显然同样适用于PTRACE_POKEDATAPTRACE_POKETEXT

    所以,说“调试器进程”使用:

    long data = ptrace(PTRACE_PEEKDATA, pid, 0x12340128, NULL); 
    

    当使用地址 0x12340128 的PTRACE_PEEKDATA 调用操作系统时,它将“查看”内存在 0x12340128 的相应内存映射(页面对齐,使 0x12340000),如果存在,它将被映射到内核,然后将数据从地址 0x12340128 复制到本地内存中,内存未映射,并将复制的数据作为返回值传回。

    手册将使用的启动说明为:

    父进程可以通过调用 fork(2) 来启动跟踪,并让 结果孩子执行 PTRACE_TRACEME,然后(通常)执行 exec(3)。 或者,父进程可以开始跟踪现有进程 使用 PTRACE_ATTACH。

    更多信息请联系man ptrace

    【讨论】:

      【解决方案3】:

      对于 linux 调试,有一个系统调用ptrace,它可以控制系统上的另一个进程。实际上,如果您是进程的所有者并且您没有手动删除权限,则通常会授予您执行此操作的权限。

      操作系统调用ptrace 本身可以访问内存、程序计数器、寄存器和几乎所有其他相关的东西以进行读写。

      详情请见man ptrace

      如果您对它在调试器中的工作方式感兴趣,请查看 gdb-x.x.x/gdb/linux-nat.c。在那里您可以找到访问其他进程以进行调试的核心内容。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-23
        • 1970-01-01
        • 2016-09-13
        • 2018-09-15
        • 1970-01-01
        • 2011-04-28
        • 1970-01-01
        相关资源
        最近更新 更多