【问题标题】:How to get value at a memory address in linux shell如何在 linux shell 中的内存地址获取值
【发布时间】:2018-05-25 06:33:24
【问题描述】:

我知道我们可以通过 C 程序或 gdb 获取内存地址处的值。

有什么方法可以通过 bash shell 或类似“单行”的 perl 指令来获取它?

【问题讨论】:

  • 你试图从哪个进程读取内存?内存地址不是全局的。
  • 内核内存?物理内存?虚拟内存? (谁的虚拟内存?)
  • 如果您的目标是全系统内存转储,您可能需要像 LIME 这样的工具,您可以使用像 Volatility 这样的工具进行分析。
  • (相比之下,如果你想在 C 程序中公开内部变量以供外部检查,有更好的方法来做到这一点——我什至看到了一个为此目的而构建的微型嵌入式 Web 服务器)。
  • 我很想知道 close 标志的用途。我认为这在我希望 OP 阅读的任何手册中都不明显。我没有在 SO 上找到重复项。问一个答案是“你不能和/或你不应该”的问题没有错。

标签: linux bash memory


【解决方案1】:

简短回答...不

如果您非常小心,可能会将指令传递到 GDB 并解释输出。想试试看rocky的回答。

它是 unix 进程模型的一部分,一个进程无法看到另一个进程,也无法读取彼此的内存。这是为了安全。有一个特殊的内核 API 可用于查看程序。但是这个 API 的客户端很少。 GDB 是我唯一知道的。

我怀疑您想要实现的目标要么是一个非常糟糕的主意,要么可以在不读取程序内存的情况下完成。

【讨论】:

  • 嗯? gdb 绝对可以被告知作为脚本操作的一部分附加到给定进程。
  • 是的,当然可以。常规流程不能。它有一个特殊的 API。以为我已经说清楚了。有关为什么 GDB 可以但进程不能的更多信息……请参阅此处reverseengineering.stackexchange.com/questions/8531/…
  • 我很清楚 ptrace 系统调用。您最初的回答暗示只能附加使用调试信息编译的程序,这是错误的,并说“我不相信 [it's] 这样设计”关于 gdb 易于编写脚本;这意味着 gdb 无法轻松编写脚本,这是我之前的评论的回应。
  • (实际上,这个答案中的“调试编译程序”限定意味着它仍然意味着只能附加带有调试符号的程序,这仍然是错误的)。
  • 没错,我的措辞有点误导。我已经对其进行了编辑以进行调整。重点仍然存在。 “不能/不应该”。越来越多的限制阻止流程这样做。在 bash 中将其自动化表明它正在为除调试以外的其他事情完成,这是一个糟糕的主意。
【解决方案2】:

以下内容可能接近您可能想要的。如果没有,希望您能够适应。

我首先要说的是,您对“内存地址”的含义非常模糊。下面我将用它来表示当前执行的指令的地址,我将使用 gdb 命令“回溯”来获取。将 gdb 命令从“bt”调整为您想要获取“内存地址”的任何内容。

假设您的程序是 sleeper-for-pid,进程 ID 为 3963

 sudo gdb --ex 'bt 1' --batch -nx -p 3963

将运行附加到进程的 gdb 并提供最新条目的回溯。这是一个例子:

sudo gdb --ex 'bt 1' --batch -nx -p 3963
84  ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) #0  0x00007f5dee71f2f0 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:84

如果你真的只想要带有地址的那一行,你可以用 grep 搜索 #0,例如

sudo gdb --ex 'bt 1' --batch -nx -p 3963 | grep '#0'
(gdb) #0  0x00007f5dee71f2f0 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:84

如果你只想要地址,你可能需要进一步删减,例如

$ sudo gdb --ex 'bt 1' -nx -p 3963| grep '#0' | cut -d' ' -f 4
0x00007f5dee71f2f0

如果您不知道进程 ID,则可以使用 pidof。例如如果命令名称是sleeper-for-pid:

$ sudo gdb --ex 'bt 1' --batch -nx -p $(pidof sleeper-for-pid)

“sudo”可能对你有用,也可能不适合你或被需要。

就个人而言,我更喜欢的不仅仅是最近的回溯条目。所以bt 1 可能会调整为bt 3bt 以获得更完整的回溯。

希望这足以让您入门。

【讨论】:

    【解决方案3】:

    我知道我们可以通过 C 程序或 gdb 获取内存地址的值。有没有办法通过 bash shell 或类似“单行”perl 指令的东西来获取它??

    shell 只是一个程序。您要求做的事情毫无意义。假设 shell 确实允许您检查内存地址(并且您可以轻松地修改 shell 或编写自己的 shell 来执行此操作),内存地址的值用于 shell 的进程。任何其他进程将在同一地址具有不同的内存值。

    【讨论】:

    • 无需修改 shell 的源代码,甚至 -- bash 支持用 C 编写的可加载模块,这些模块添加了新的内置命令。当然可以很容易地为该 shell 自己的地址空间添加 peek 和 poke 支持。
    猜你喜欢
    • 1970-01-01
    • 2012-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多