litao3rd
litao3rd

Reputation: 191

How to find the platform of a running process

I have a x86_64 machine, and it can run IA32 process because I have installed a 32bits library. Now I want to know what's the platform that a running process is using? 64bits or 32bits?

The only way I can access the process is a ptrace system call; I don't have executable file (like I can just execute the file but I don't have read and write permissions), so I can't get the ELF header.

The OS I'm using is Ubuntu 14.04 LTS.

I don't want to get executable file, and then analyse the ELF format. The ONLY WAY I can access the process is ptrace, or other system calls same as ptrace if you know, please tell me. Because I want to analyse the process in a C program.

Upvotes: 0

Views: 330

Answers (2)

Peter Cordes
Peter Cordes

Reputation: 364000

This was also asked on https://unix.stackexchange.com/questions/106234/determine-if-a-specific-process-is-32-or-64-bit, with limited success / viability for detection methods other than checking ELF headers after getting to them in various ways.

Looking at /proc/<pid>/maps for 64-bit addresses looks viable. So does checking the bitness of /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

(Or file -L to follow symlinks. If you just use file /.../exe, it tells you symbolic link to /tmp/a.out.)

Note that files in /proc track the actual inode, so replacing /tmp/a.out with a different executable does not throw this off. Opening it for reading will open the actual executable that this process has mapped, separate from the name it would report via a readlink() system call. If that inode has no directory entries anymore, file will report symbolic link to /tmp/a.out (deleted), but opening for reading will still get the contents. And renaming a.out will get the kernel to report the new name as the symlink, like /tmp/bar.


This answer previously suggested looking at /proc/<pid>/personality, but the difference I was seeing was that a 32-bit process had the READ_IMPLIES_EXEC bit set. That's likely because I built a 32-bit executable from asm sources I had been playing with at the time, without the .note.GNU-stack,"",@progbits that overrides the default of executable stacks, previously implemented by making all pages executable: Unexpected exec permission from mmap when assembly files included in the project

A 32-bit executable compiled by gcc -m32 has personality 00000000, same as 64-bit /bin/sleep. So this isn't a useful detection mechanism, unfortunately. I was hoping that 32-bit processes would have some bits set like ADDR_LIMIT_32BIT, but apparently that's implicit for a 32-bit process, perhaps as part of the "execution domain" like PER_LINUX32.

I got 00400000 (just READ_IMPLIES_EXEC) for a 32-bit process with executable stacks (and everything else). (And 00440000 when I had it stopped in a debugger.) The proc(5) man page says it tells you the personality as set by personality(2).

Kernel source for personality bit-numbers: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/personality.h

glibc's copy: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/sys/personality.h;hb=HEAD

Mostly leaving this part of the answer here in case the part about decoding personalities is useful to future readers. It's not relevant to finding the bitness of a running process.

Upvotes: 1

deaks
deaks

Reputation: 252

Try using xocopy to create a copy of the executable in question and dump the ELF header from the copy created.

This tool and the problem you are describing was discussed elsewhere and that discussion may be helpful to you as well.

Upvotes: 0

Related Questions