Skip to content

Instantly share code, notes, and snippets.

@davehouse
Created September 17, 2021 20:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davehouse/8dfccfbd9366eeb8ee59d165818fed1c to your computer and use it in GitHub Desktop.
Save davehouse/8dfccfbd9366eeb8ee59d165818fed1c to your computer and use it in GitHub Desktop.
macos: from python->sysctl check if a process is running translated with rosetta (false: native arm64)
#!/usr/bin/env python
import os
#print('Python executing as {}'.format(os.uname()[4]))
import sys
from ctypes import *
from ctypes.util import find_library
import struct
libc = cdll.LoadLibrary(find_library("c"))
# sys/sysctl.h
CTL_KERN = 1
KERN_PROC = 14
KERN_PROC_PID = 1
# sys/proc.h
P_TRANSLATED = 131072
kinfo_proc_size = 648 * 4 # sizeof(kinfo_proc)=648
pid = int(sys.argv[1])
"""
// MacOSX11.1.sdk/usr/include/sys/sysctl.h
struct kinfo_proc {
struct extern_proc kp_proc; /* proc structure */
//[...]
// sys/proc.h
struct extern_proc {
union {
struct {
struct proc *__p_forw; /* Doubly-linked run/sleep queue. */
struct proc *__p_back;
} p_st1;
struct timeval __p_starttime; /* process start time */
} p_un;
struct vmspace *p_vmspace; /* Address space. */
struct sigacts *p_sigacts; /* Signal actions, state (PROC ONLY). */
int p_flag; /* P_* flags. */
// [...]
// timeval: [(long)__darwin_time_t, (__int32_t)__darwin_suseconds_t]
"""
def sysctl_procinfo(pid=1):
# https://stackoverflow.com/questions/759892/python-ctypes-and-sysctl
_mem = create_string_buffer(b"", kinfo_proc_size)
_def = (CTL_KERN, KERN_PROC, KERN_PROC_PID, pid)
_arr = c_int * len(_def)
_name = _arr()
for i, v in enumerate(_def):
_name[i] = c_int(v)
_sz = c_size_t(sizeof(_mem))
result = libc.sysctl(_name, len(_def), byref(_mem), byref(_sz), None, c_size_t(0))
if result != 0:
raise Exception('sysctl returned with error %s' % result)
python_bytes_array = string_at(_mem)
return struct.unpack_from('liPPi', _mem, 0)
# kinfo_proc struct contains {long, int, pointer, pointer, int p_flag}
p_flag = sysctl_procinfo(pid)[4]
#print(p_flag)
#print(P_TRANSLATED & p_flag)
# https://www.patreon.com/posts/45121749
# https://github.com/objective-see/ProcessMonitor/blob/1a9c2e0c8044ad10676efad480f200f12060ed7a/Library/Source/Process.m#L252
exit(P_TRANSLATED != P_TRANSLATED & p_flag)
@davehouse
Copy link
Author

davehouse commented Sep 17, 2021

macmini-m1-1:~ administrator$ uname -m
arm64
macmini-m1-1:~ administrator$ ./is_rosetta_translated.py 48535; echo $?
0
macmini-m1-1:~ administrator$ ./is_rosetta_translated.py 1; echo $?
1
macmini-m1-1:~ administrator$ ps -ef|grep 48535
  501 48535     1   0 23Aug21 ??        59:26.87 /usr/local/munki/Python.framework/Versions/3.8/Resources/Python.app/Contents/MacOS/Python /usr/local/munki/app_usage_monitor
  501 34741 34303   0  1:50PM ttys000    0:00.00 grep 48535
macmini-m1-1:~ administrator$ file /usr/local/munki/Python.framework/Versions/3.8/Resources/Python.app/Contents/MacOS/Python
/usr/local/munki/Python.framework/Versions/3.8/Resources/Python.app/Contents/MacOS/Python: Mach-O 64-bit executable x86_64

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment