我有一台x86_64
机器,它可以运行IA32
进程,因为我安装了一个32位的库。现在我想知道正在运行的进程使用的平台是什么? 64 位还是 32 位?
我可以访问该进程的唯一方法是 ptrace
系统调用;我没有可执行文件(比如我只能执行该文件,但我没有读写权限),所以我无法获取 ELF header 。
我使用的操作系统是 Ubuntu 14.04 LTS。
不想获取可执行文件,然后解析ELF格式。 ONLY WAY 我可以访问该进程是 ptrace
,或者其他与 ptrace
相同的系统调用 如果您知道,请告诉我。因为我想分析一个C程序中的进程。
最佳答案
这也在 https://unix.stackexchange.com/questions/106234/determine-if-a-specific-process-is-32-or-64-bit 上被问到,除了在以各种方式获取 ELF header 后检查 ELF header 之外,检测方法的成功/可行性有限。
查看/proc/<pid>/maps
64 位地址看起来可行。检查 /proc/<pid>/exe
的位数也是如此:
$ file - < /proc/$(pidof a.out)/exe
/dev/stdin: ELF 32-bit LSB pie executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=ff6b5084918be4e4daf7e4315fa4d6dd6a039ae7, for GNU/Linux 4.4.0, with debug_info, not stripped
(或 file -L
跟随符号链接(symbolic link)。如果您只使用 file /.../exe
,它会告诉您 symbolic link to /tmp/a.out
。)
请注意 /proc
中的文件跟踪实际的 inode,因此替换 /tmp/a.out
使用不同的可执行文件不会将其关闭。打开它进行阅读将打开此进程映射的实际可执行文件,与它通过 readlink()
报告的名称分开系统调用。如果该 inode 不再有目录条目,文件将报告 symbolic link to /tmp/a.out (deleted)
, 但打开阅读仍会得到内容。并重命名 a.out
将使内核报告新名称作为符号链接(symbolic link),如 /tmp/bar
.
此答案之前建议查看 /proc/<pid>/personality
,但我看到的不同之处在于 32 位进程具有 READ_IMPLIES_EXEC
位设置。这可能是因为我从当时一直在玩的 asm 源构建了一个 32 位可执行文件,没有 .note.GNU-stack,"",@progbits
覆盖可执行堆栈的默认值,之前通过使所有页面可执行来实现: Unexpected exec permission from mmap when assembly files included in the project
由 gcc -m32
编译的 32 位可执行文件有个性00000000
, 与 64 位相同 /bin/sleep
.不幸的是,这不是一个有用的检测机制。我希望 32 位进程将一些位设置为 ADDR_LIMIT_32BIT
, 但显然这对于 32 位进程来说是隐含的,可能是像 PER_LINUX32
这样的“执行域”的一部分。 .
我得到了 00400000
(只是 READ_IMPLIES_EXEC
)用于具有可执行堆栈(以及其他所有内容)的 32 位进程。 (还有 00440000
,当我让它在调试器中停止时。) proc(5)
手册页说它会告诉您 personality(2)
设置的个性.
glibc 的副本:https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/sys/personality.h;hb=HEAD
主要将这部分答案留在这里,以防有关解码个性的部分对 future 的读者有用。它与查找正在运行的进程的位数无关。
关于c - 如何找到正在运行的进程的平台,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30471947/