如何在linux中调试正在运行的java进程?

逆向工程 linux 雷达2 调试器 爪哇 反汇编者
2021-06-14 23:43:16

TLDR我想在 linux 机器上对 java 程序进行实时调试,而不是如何/什么调试器附加到 JVM 来完成这项工作。

我希望这是一个很好解决的问题,但是经过几个小时的搜索,我缺乏找到解决方案的术语:

我有一个 java 程序(存储在 jar 文件中),我想它运行时观察(逆向工程?)它我看到很多对 java反编译支持——这根本不是我感兴趣的,所以请不要解释如何做到这一点。我在搜索中遇到的一个主要问题是遇到这些类型的答案。

理想情况下,我会:

  1. 启动程序并找到PID。
  2. 以某种方式将调试器附加到 JVM(这是我不知道该怎么做,并且显然缺乏搜索语言)
  3. 使用调试器设置断点,读/写JVM的任意内存,查看JVM的寄存器和堆栈。
  4. 使用简单的开源命令行工具来执行此操作,例如 Radare2 或 GDB。

我希望在执行此操作时读取 java 字节码(JVM 的指令集),而不是 java 源代码。

我习惯于将 Radare2 和 GDB 用于本机代码(crackmes、CTF 内容、微损坏)。我还看到他们在技术上都支持 Java,但我很难弄清楚如何做到这一点,确切地说。

我需要两件事的帮助:使用什么软件以及如何将程序附加到进程中如果我可以使用radare,奖励积分!

需要明确的是,有问题的 Java 是在 Linux PC 上运行的,而不是在 Android 手机或类似设备上运行。

我还阅读了 JDB,但似乎代码需要使用调试标志进行编译,这对我的情况来说是不可能的——它似乎也不是我正在寻找的。

1个回答

您可以使用 jdb 附加到正在运行的程序,而无需使用调试标志对其进行编译。

在我的机器上,jdb 位于 /usr/local/jdk/jdk1.8.0_202/bin/jdb 和我正在运行的 java 进程的 pid = 14476

sudo /usr/local/jdk/jdk1.8.0_202/bin/jdb -connect sun.jvm.hotspot.jdi.SAPIDAttachingConnector:pid=14476

但是,如果您没有使用调试信息编译您的程序,我认为这将使调试变得更加困难。

有关更多信息,请参阅此参考资料

编辑:我还发现我可以使用 jvisualvm 轻松查看正在运行的进程的变量值,这是一个 oracles jdk 附带的工具。

1) 从命令行启动 jvisualvm。它位于您的 jdk bin 文件夹中。

/usr/local/jdk/jdk1.8.0_202/bin/jvisualvm

2) 在屏幕右侧,您可以看到您机器上正在运行的 java 进程。然后,您可以执行堆转储(右键单击进程)并查看您感兴趣的类的变量值。

堆转储