Source code for rpcclient.darwin.structs

from construct import Adapter, Aligned, Array, BitsInteger, BitStruct, Bytes, Computed, CString, Default, Enum, \
    FlagsEnum, GreedyRange, Hex, Int8ul, Int16sl, Int16ub, Int16ul, Int32sl, Int32ub, Int32ul, Int64sl, Int64ul, \
    LazyArray, Octet, PaddedString, Padding, Seek, Struct, Switch, Tell, Union, this

from rpcclient.structs.consts import AF_INET, AF_INET6, AF_UNIX
from rpcclient.structs.generic import UNIX_PATH_MAX, gid_t, in_addr, long, mode_t, short, st_flags, time_t, u_char, \
    u_int32_t, u_short, uid_t, uint8_t, uint32_t, uint64_t

MAXPATHLEN = 1024
_SYS_NAMELEN = 256

utsname = Struct(
    'sysname' / PaddedString(_SYS_NAMELEN, 'utf8'),
    'nodename' / PaddedString(_SYS_NAMELEN, 'utf8'),
    'release' / PaddedString(_SYS_NAMELEN, 'utf8'),
    'version' / PaddedString(_SYS_NAMELEN, 'utf8'),
    'machine' / PaddedString(_SYS_NAMELEN, 'utf8'),
)

pid_t = Int32ul
exitcode_t = Int32sl
ino_t = Int32ul
dev_t = Int32ul
off_t = Int64ul
nlink_t = Int16ul
blkcnt_t = Int64ul
blksize_t = Int32ul
ino64_t = Int64ul
fsid_t = Array(2, Int32sl)
mach_port_t = Int64ul
io_name_t = PaddedString(1024, 'utf8')
io_object_t = Int64ul
vm_prot_t = Int32ul
vm_inherit_t = Int32ul
boolean_t = Int32ul
memory_object_offset_t = Int64ul
vm_behavior_t = Int32ul
mach_vm_address_t = Int64ul
mach_vm_size_t = Int64ul
integer_t = Int32sl

timespec = Struct(
    'tv_sec' / long,
    'tv_nsec' / long,
)
dirent32 = Struct(
    'd_ino' / ino_t,
    'd_offset' / Int16ul,
    'd_reclen' / Int8ul,
    'd_namelen' / Int8ul,
    'd_name' / PaddedString(this.d_namelen, 'utf8'),
)
dirent64 = Struct(
    'd_ino' / ino64_t,
    'd_offset' / Int64ul,
    'd_reclen' / Int16ul,
    'd_namelen' / Int16ul,
    'd_type' / Int8ul,
    'd_name' / PaddedString(this.d_namelen, 'utf8'),
)
stat32 = Struct(
    'st_dev' / dev_t,  # device inode resides on
    'st_ino' / ino_t,  # inode's number
    'st_mode' / mode_t,  # inode protection mode
    'st_nlink' / nlink_t,  # number of hard links to the file
    'st_uid' / uid_t,  # user-id of owner
    'st_gid' / gid_t,  # group-id of owner
    'st_rdev' / dev_t,  # device type, for special file inode

    'st_atimespec' / timespec,  # time of last access
    'st_atime' / Computed(this.st_atimespec.tv_sec + (this.st_atimespec.tv_nsec / 10 ** 9)),
    'st_mtimespec' / timespec,  # time of last data modification
    'st_mtime' / Computed(this.st_mtimespec.tv_sec + (this.st_mtimespec.tv_nsec / 10 ** 9)),
    'st_ctimespec' / timespec,  # time of last file status change
    'st_ctime' / Computed(this.st_ctimespec.tv_sec + (this.st_ctimespec.tv_nsec / 10 ** 9)),
    'st_size' / off_t,  # file size, in bytes
    'st_blocks' / blkcnt_t,  # blocks allocated for file
    'st_blksize' / blksize_t,  # optimal blocksize for I/O
    'st_flags' / Int32ul,  # user defined flags for file
    'st_gen' / Int32ul,
    'st_lspare' / Int32sl,
    'st_qspare' / Array(2, Int64sl),
    Padding(24),  # Compiled size is 144
)
stat64 = Struct(
    'st_dev' / dev_t,  # device inode resides on
    'st_mode' / mode_t,  # inode protection mode
    'st_nlink' / nlink_t,  # number of hard links to the file
    'st_ino' / ino64_t,  # inode's number
    'st_uid' / uid_t,  # user-id of owner
    'st_gid' / gid_t,  # group-id of owner
    'st_rdev' / dev_t,  # device type, for special file inode
    Padding(4),

    'st_atimespec' / timespec,  # time of last access
    'st_atime' / Computed(this.st_atimespec.tv_sec + (this.st_atimespec.tv_nsec / 10 ** 9)),
    'st_mtimespec' / timespec,  # time of last data modification
    'st_mtime' / Computed(this.st_mtimespec.tv_sec + (this.st_mtimespec.tv_nsec / 10 ** 9)),
    'st_ctimespec' / timespec,  # time of last file status change
    'st_ctime' / Computed(this.st_ctimespec.tv_sec + (this.st_ctimespec.tv_nsec / 10 ** 9)),
    'st_birthtimespec' / timespec,  # time of file creation(birth)
    'st_btime' / Computed(this.st_birthtimespec.tv_sec + (this.st_birthtimespec.tv_nsec / 10 ** 9)),

    'st_size' / off_t,
    'st_blocks' / blkcnt_t,  # blocks allocated for file
    'st_blksize' / blksize_t,  # optimal blocksize for I/O
    'st_flags' / st_flags,  # blocks allocated for file
    'st_gen' / Int32ul,  # user defined flags for file
    # seems like this value doesn't really exist
    # 'st_lspare' / Int32ul,
    'st_qspare' / Array(2, Int64sl),
)

MFSNAMELEN = 15  # length of fs type name, not inc. nul
MNAMELEN = 90  # length of buffer for returned name

# when _DARWIN_FEATURE_64_BIT_INODE is NOT defined
statfs64 = Struct(
    'f_otype' / Int16sl,  # type of file system (reserved: zero)
    'f_oflags' / Int16sl,  # copy of mount flags (reserved: zero)
    Padding(4),
    'f_bsize' / Int64ul,  # fundamental file system block size
    'f_iosize' / Int64ul,  # optimal transfer block size
    'f_blocks' / Int64ul,  # total data blocks in file system
    'f_bfree' / Int64ul,  # free blocks in fs
    'f_bavail' / Int64ul,  # free blocks avail to non-superuser
    'f_files' / Int64ul,  # total file nodes in file system
    'f_ffree' / Int64ul,  # free file nodes in fs
    'f_fsid' / fsid_t,  # file system id
    'f_owner' / uid_t,  # user that mounted the file system
    Padding(4),
    'f_reserved1' / Int16sl,  # reserved for future use
    'f_type' / Int16sl,  # type of file system (reserved)
    Padding(4),
    'f_flags' / Int64ul,  # copy of mount flags
    'f_reserved2' / Int64ul,  # reserved for future use
    'f_fstypename' / PaddedString(MFSNAMELEN, 'utf8'),  # fs type name
    'f_mntonname' / PaddedString(MNAMELEN, 'utf8'),  # directory on which mounted
    'f_mntfromname' / PaddedString(MNAMELEN, 'utf8'),  # mounted file system
    'f_reserved3' / Int8ul,  # reserved for future use
    'f_reserved4' / Int64ul,  # reserved for future use
)

MFSTYPENAMELEN = 16  # length of fs type name including null
MNAMELEN = MAXPATHLEN

# when _DARWIN_FEATURE_64_BIT_INODE is defined
statfs32 = Struct(
    'f_bsize' / Int32ul,  # fundamental file system block size
    'f_iosize' / Int32sl,  # optimal transfer block size
    'f_blocks' / Int64ul,  # total data blocks in file system
    'f_bfree' / Int64ul,  # free blocks in fs
    'f_bavail' / Int64ul,  # free blocks avail to non-superuser
    'f_files' / Int64ul,  # total file nodes in file system
    'f_ffree' / Int64ul,  # free file nodes in fs
    'f_fsid' / fsid_t,  # file system id
    'f_owner' / uid_t,  # user that mounted the filesystem
    'f_type' / Int32ul,  # type of filesystem
    'f_flags' / Int32ul,  # copy of mount exported flags
    'f_fssubtype' / Int32ul,  # fs sub-type (flavor)
    'f_fstypename' / PaddedString(MFSTYPENAMELEN, 'utf8'),  # fs type name
    'f_mntonname' / PaddedString(MAXPATHLEN, 'utf8'),  # directory on which mounted
    'f_mntfromname' / PaddedString(MAXPATHLEN, 'utf8'),  # mounted filesystem
    'f_reserved' / Int32ul[8],  # For future use
)

PROC_ALL_PIDS = 1

# Flavors for proc_pidinfo()
PROC_PIDLISTFDS = 1
PROC_PIDTASKALLINFO = 2
PROC_PIDTBSDINFO = 3
PROC_PIDTASKINFO = 4
PROC_PIDTHREADINFO = 5
PROC_PIDLISTTHREADS = 6
PROC_PIDREGIONINFO = 7
PROC_PIDREGIONPATHINFO = 8
PROC_PIDVNODEPATHINFO = 9
PROC_PIDTHREADPATHINFO = 10
PROC_PIDPATHINFO = 11
PROC_PIDWORKQUEUEINFO = 12
PROC_PIDT_SHORTBSDINFO = 13
PROC_PIDLISTFILEPORTS = 14
PROC_PIDTHREADID64INFO = 15
PROC_PID_RUSAGE = 16
PROC_PIDUNIQIDENTIFIERINFO = 17
PROC_PIDT_BSDINFOWITHUNIQID = 18
PROC_PIDARCHINFO = 19
PROC_PIDCOALITIONINFO = 20
PROC_PIDNOTEEXIT = 21
PROC_PIDREGIONPATHINFO2 = 22
PROC_PIDREGIONPATHINFO3 = 23

# Flavors for proc_pidfdinfo
PROC_PIDFDVNODEINFO = 1
PROC_PIDFDVNODEPATHINFO = 2
PROC_PIDFDSOCKETINFO = 3
PROC_PIDFDPSEMINFO = 4
PROC_PIDFDPSHMINFO = 5
PROC_PIDFDPIPEINFO = 6
PROC_PIDFDKQUEUEINFO = 7
PROC_PIDFDATALKINFO = 8

# Flavors for proc_pidfileportinfo
PROC_PIDFILEPORTVNODEPATHINFO = 2  # out: vnode_fdinfowithpath
PROC_PIDFILEPORTPSHMINFO = 5  # out: pshm_fdinfo
PROC_PIDFILEPORTPIPEINFO = 6  # out: pipe_fdinfo
# used for proc_setcontrol
PROC_SELFSET_PCONTROL = 1
PROC_SELFSET_THREADNAME = 2
PROC_SELFSET_VMRSRCOWNER = 3
PROC_SELFSET_DELAYIDLESLEEP = 4
# used for proc_dirtycontrol
PROC_DIRTYCONTROL_TRACK = 1
PROC_DIRTYCONTROL_SET = 2
PROC_DIRTYCONTROL_GET = 3
PROC_DIRTYCONTROL_CLEAR = 4
# proc_track_dirty() flags
PROC_DIRTY_TRACK = 0x1
PROC_DIRTY_ALLOW_IDLE_EXIT = 0x2
PROC_DIRTY_DEFER = 0x4
PROC_DIRTY_LAUNCH_IN_PROGRESS = 0x8
# proc_get_dirty() flags
PROC_DIRTY_TRACKED = 0x1
PROC_DIRTY_ALLOWS_IDLE_EXIT = 0x2
PROC_DIRTY_IS_DIRTY = 0x4
PROC_DIRTY_LAUNCH_IS_IN_PROGRESS = 0x8

# Flavors for proc_pidoriginatorinfo
PROC_PIDORIGINATOR_UUID = 0x1
PROC_PIDORIGINATOR_BGSTATE = 0x2
# __proc_info() call numbers
PROC_INFO_CALL_LISTPIDS = 0x1
PROC_INFO_CALL_PIDINFO = 0x2
PROC_INFO_CALL_PIDFDINFO = 0x3
PROC_INFO_CALL_KERNMSGBUF = 0x4
PROC_INFO_CALL_SETCONTROL = 0x5
PROC_INFO_CALL_PIDFILEPORTINFO = 0x6
PROC_INFO_CALL_TERMINATE = 0x7
PROC_INFO_CALL_DIRTYCONTROL = 0x8
PROC_INFO_CALL_PIDRUSAGE = 0x9
PROC_INFO_CALL_PIDORIGINATORINFO = 0xa

# defns of process file desc type
PROX_FDTYPE_ATALK = 0
PROX_FDTYPE_VNODE = 1
PROX_FDTYPE_SOCKET = 2
PROX_FDTYPE_PSHM = 3
PROX_FDTYPE_PSEM = 4
PROX_FDTYPE_KQUEUE = 5
PROX_FDTYPE_PIPE = 6
PROX_FDTYPE_FSEVENTS = 7

pbi_flags_t = FlagsEnum(Int32ul,
                        # pbi_flags values
                        PROC_FLAG_SYSTEM=1,  # System process
                        PROC_FLAG_TRACED=2,  # process currently being traced, possibly by gdb
                        PROC_FLAG_INEXIT=4,  # process is working its way in exit()
                        PROC_FLAG_PPWAIT=8,
                        PROC_FLAG_LP64=0x10,  # 64bit process
                        PROC_FLAG_SLEADER=0x20,  # The process is the session leader
                        PROC_FLAG_CTTY=0x40,  # process has a control tty
                        PROC_FLAG_CONTROLT=0x80,  # Has a controlling terminal
                        PROC_FLAG_THCWD=0x100,  # process has a thread with cwd
                        # process control bits for resource starvation
                        PROC_FLAG_PC_THROTTLE=0x200,
                        # In resource starvation situations, this process is to be throttled
                        PROC_FLAG_PC_SUSP=0x400,  # In resource starvation situations, this process is to be suspended
                        PROC_FLAG_PC_KILL=0x600,  # In resource starvation situations, this process is to be terminated
                        PROC_FLAG_PC_MASK=0x600,
                        # process action bits for resource starvation
                        PROC_FLAG_PA_THROTTLE=0x800,  # The process is currently throttled due to resource starvation
                        PROC_FLAG_PA_SUSP=0x1000,  # The process is currently suspended due to resource starvation
                        PROC_FLAG_PSUGID=0x2000,  # process has set privileges since last exec
                        PROC_FLAG_EXEC=0x4000,  # process has called exec
                        PROC_FLAG_DARWINBG=0x8000,  # process in darwin background
                        PROC_FLAG_EXT_DARWINBG=0x10000,  # process in darwin background - external enforcement
                        PROC_FLAG_IOS_APPLEDAEMON=0x20000,  # Process is apple daemon
                        PROC_FLAG_DELAYIDLESLEEP=0x40000,  # Process is marked to delay idle sleep on disk IO
                        PROC_FLAG_IOS_IMPPROMOTION=0x80000,  # Process is daemon which receives importane donation
                        PROC_FLAG_ADAPTIVE=0x100000,  # Process is adaptive
                        PROC_FLAG_ADAPTIVE_IMPORTANT=0x200000,  # Process is adaptive, and is currently important
                        PROC_FLAG_IMPORTANCE_DONOR=0x400000,  # Process is marked as an importance donor
                        PROC_FLAG_SUPPRESSED=0x800000,  # Process is suppressed
                        PROC_FLAG_APPLICATION=0x1000000,  # Process is an application
                        PROC_FLAG_IOS_APPLICATION=0x1000000,  # Process is an application
                        )

MAXCOMLEN = 16

proc_bsdinfo = Struct(
    'pbi_flags' / pbi_flags_t,  # 64bit emulated etc
    'pbi_status' / Int32ul,
    'pbi_xstatus' / Int32ul,
    'pbi_pid' / Int32ul,
    'pbi_ppid' / Int32ul,
    'pbi_uid' / uid_t,
    'pbi_gid' / gid_t,
    'pbi_ruid' / uid_t,
    'pbi_rgid' / gid_t,
    'pbi_svuid' / uid_t,
    'pbi_svgid' / gid_t,
    'rfu_1' / Int32ul,  # reserved
    '_pbi_comm' / Bytes(MAXCOMLEN),
    'pbi_comm' / Computed(lambda x: x._pbi_comm.split(b'\x00', 1)[0].decode()),
    '_pbi_name' / Bytes(2 * MAXCOMLEN),  # empty if no name is registered
    'pbi_name' / Computed(lambda x: x._pbi_name.split(b'\x00', 1)[0].decode()),
    'pbi_nfiles' / Int32ul,
    'pbi_pgid' / Int32ul,
    'pbi_pjobc' / Int32ul,
    'e_tdev' / Int32ul,  # controlling tty dev
    'e_tpgid' / Int32ul,  # tty process group id
    'pbi_nice' / Int32sl,
    'pbi_start_tvsec' / Int64ul,
    'pbi_start_tvusec' / Int64ul,
)

proc_taskinfo = Struct(
    'pti_virtual_size' / Int64ul,  # virtual memory size (bytes)
    'pti_resident_size' / Int64ul,  # resident memory size (bytes)
    'pti_total_user' / Int64ul,  # total time
    'pti_total_system' / Int64ul,
    'pti_threads_user' / Int64ul,  # existing threads only
    'pti_threads_system' / Int64ul,
    'pti_policy' / Int32sl,  # default policy for new threads
    'pti_faults' / Int32sl,  # number of page faults
    'pti_pageins' / Int32sl,  # number of actual pageins
    'pti_cow_faults' / Int32sl,  # number of copy-on-write faults
    'pti_messages_sent' / Int32sl,  # number of messages sent
    'pti_messages_received' / Int32sl,  # number of messages received
    'pti_syscalls_mach' / Int32sl,  # number of mach system calls
    'pti_syscalls_unix' / Int32sl,  # number of unix system calls
    'pti_csw' / Int32sl,  # number of context switches
    'pti_threadnum' / Int32sl,  # number of threads in the task
    'pti_numrunning' / Int32sl,  # number of running threads
    'pti_priority' / Int32sl,  # task priority
)

proc_taskallinfo = Struct(
    'pbsd' / proc_bsdinfo,
    'ptinfo' / proc_taskinfo,
)

proc_regioninfo = Struct(
    'pri_protection' / Int32ul,
    'pri_max_protection' / Int32ul,
    'pri_inheritance' / Int32ul,
    'pri_flags' / Int32ul,  # shared, external pager, is submap
    'pri_offset' / Int64ul,
    'pri_behavior' / Int32ul,
    'pri_user_wired_count' / Int32ul,
    'pri_user_tag' / Int32ul,
    'pri_pages_resident' / Int32ul,
    'pri_pages_shared_now_private' / Int32ul,
    'pri_pages_swapped_out' / Int32ul,
    'pri_pages_dirtied' / Int32ul,
    'pri_ref_count' / Int32ul,
    'pri_shadow_depth' / Int32ul,
    'pri_share_mode' / Int32ul,
    'pri_private_pages_resident' / Int32ul,
    'pri_shared_pages_resident' / Int32ul,
    'pri_obj_id' / Int32ul,
    'pri_depth' / Int32ul,
    'pri_address' / Int64ul,
    'pri_size' / Int64ul,
)

proc_fdinfo = Struct(
    'proc_fd' / Int32sl,
    'proc_fdtype' / Int32ul,
)

proc_fileinfo = Struct(
    'fi_openflags' / Int32ul,
    'fi_status' / Int32ul,
    'fi_offset' / off_t,
    'fi_guardflags' / Int32ul,
)

# A copy of stat64 with static sized fields.
vinfo_stat = stat64

vnode_info = Struct(
    'vi_stat' / vinfo_stat,
    'vi_type' / Int32sl,
    'vi_pad' / Int32sl,
    'vi_fsid' / fsid_t,
)

vnode_info_path = Struct(
    'vip_vi' / vnode_info,
    '_vip_path' / Bytes(MAXPATHLEN),
    'vip_path' / Computed(lambda x: x._vip_path.split(b'\x00', 1)[0].decode()),
)

vnode_fdinfowithpath = Struct(
    'pfi' / proc_fileinfo,
    'pvip' / vnode_info_path,
)

sockbuf_info = Struct(
    'sbi_cc' / uint32_t,
    'sbi_hiwat' / uint32_t,  # SO_RCVBUF, SO_SNDBUF
    'sbi_mbcnt' / uint32_t,
    'sbi_mbmax' / uint32_t,
    'sbi_lowat' / uint32_t,
    'sbi_flags' / short,
    'sbi_timeo' / short,
)

# TCP Sockets

TSI_T_REXMT = 0  # retransmit
TSI_T_PERSIST = 1  # retransmit persistence
TSI_T_KEEP = 2  # keep alive
TSI_T_2MSL = 3  # 2*msl quiet time timer
TSI_T_NTIMERS = 4


[docs] class IpAddressAdapter(Adapter): def _decode(self, obj, context, path): return ".".join(map(str, obj)) def _encode(self, obj, context, path): return list(map(int, obj.split(".")))
in4in6_addr = Struct( 'i46a_pad32' / u_int32_t[3], 'i46a_addr4' / IpAddressAdapter(in_addr), ) in6_addr = Struct( 'i46a_pad32' / u_int32_t[3], 'i46a_addr4' / IpAddressAdapter(in_addr), ) in_sockinfo = Struct( 'insi_fport' / Int16ub, Padding(2), 'insi_lport' / Int16ub, Padding(2), 'insi_gencnt' / uint64_t, 'insi_flags' / uint32_t, 'insi_flow' / uint32_t, 'insi_vflag' / uint8_t, 'insi_ip_ttl' / uint8_t, Padding(2), 'rfu_1' / uint32_t, # protocol dependent part 'insi_faddr' / Union(None, 'ina_46' / in4in6_addr, 'ina_6' / in6_addr), 'insi_laddr' / Union(None, 'ina_46' / in4in6_addr, 'ina_6' / in6_addr), 'insi_v4' / Struct( 'in4_tos' / u_char, ), 'insi_v6' / Struct( 'in6_hlim' / uint8_t, 'in6_cksum' / Int32sl, 'in6_ifindex' / u_short, 'in6_hops' / short, ), ) tcp_sockinfo = Struct( 'tcpsi_ini' / in_sockinfo, 'in_sockinfo' / Int32sl, 'tcpsi_timer' / Int32sl[TSI_T_NTIMERS], 'tcpsi_mss' / Int32sl, 'tcpsi_flags' / uint32_t, 'rfu_1' / uint32_t, # reserved 'tcpsi_tp' / uint64_t, # opaque handle of TCP protocol control block ) SOCK_MAXADDRLEN = 255 # Unix Domain Sockets # we can't use sockaddr_un since the sun_path may contain utf8 invalid characters sockaddr_un_raw = Struct( 'sun_family' / Default(Int16sl, AF_UNIX), '_sun_path' / Bytes(UNIX_PATH_MAX), 'sun_path' / Computed(lambda x: x._sun_path.split(b'\x00', 1)[0].decode()) ) un_sockinfo = Struct( 'unsi_conn_so' / uint64_t, 'unsi_conn_pcb' / uint64_t, 'unsi_addr' / Union(None, 'ua_sun' / sockaddr_un_raw, 'ua_dummy' / Bytes(SOCK_MAXADDRLEN)), 'unsi_caddr' / Union(None, 'ua_sun' / sockaddr_un_raw, 'ua_dummy' / Bytes(SOCK_MAXADDRLEN)), ) IF_NAMESIZE = 16 # PF_NDRV Sockets ndrv_info = Struct( 'ndrvsi_if_family' / uint32_t, 'ndrvsi_if_unit' / uint32_t, 'ndrvsi_if_name' / Bytes(IF_NAMESIZE), ) # Kernel Event Sockets kern_event_info = Struct( 'kesi_vendor_code_filter' / uint32_t, 'kesi_class_filter' / uint32_t, 'kesi_subclass_filter' / uint32_t, ) # Kernel Control Sockets MAX_KCTL_NAME = 96 kern_ctl_info = Struct( 'kcsi_id' / uint32_t, 'kcsi_reg_unit' / uint32_t, 'kcsi_flags' / uint32_t, 'kcsi_recvbufsize' / uint32_t, 'kcsi_sendbufsize' / uint32_t, 'kcsi_unit' / uint32_t, 'kcsi_name' / Bytes(MAX_KCTL_NAME), ) so_kind_t = Enum(Int32ul, SOCKINFO_GENERIC=0, SOCKINFO_IN=1, SOCKINFO_TCP=2, SOCKINFO_UN=3, SOCKINFO_NDRV=4, SOCKINFO_KERN_EVENT=5, SOCKINFO_KERN_CTL=6 ) so_family_t = Enum(Int32ul, AF_INET=AF_INET, AF_INET6=AF_INET6, ) socket_info = Struct( 'soi_stat' / vinfo_stat, 'soi_so' / uint64_t, # opaque handle of socket 'soi_pcb' / uint64_t, # opaque handle of protocol control block 'soi_type' / Int32sl, 'soi_protocol' / Int32sl, 'soi_family' / so_family_t, 'soi_options' / short, 'soi_linger' / short, 'soi_state' / short, 'soi_qlen' / short, 'soi_incqlen' / short, 'soi_qlimit' / short, 'soi_timeo' / short, 'soi_error' / u_short, 'soi_oobmark' / uint32_t, 'soi_rcv' / sockbuf_info, 'soi_snd' / sockbuf_info, 'soi_kind' / so_kind_t, 'rfu_1' / uint32_t, # reserved 'soi_proto' / Switch(this.soi_kind, { so_kind_t.SOCKINFO_IN: Struct('pri_in' / in_sockinfo), so_kind_t.SOCKINFO_TCP: Struct('pri_tcp' / tcp_sockinfo), so_kind_t.SOCKINFO_UN: Struct('pri_un' / un_sockinfo), so_kind_t.SOCKINFO_NDRV: Struct('pri_ndrv' / ndrv_info), so_kind_t.SOCKINFO_KERN_EVENT: Struct('pri_kern_event' / kern_event_info), so_kind_t.SOCKINFO_KERN_CTL: Struct('pri_kern_ctl' / kern_ctl_info), }), ) socket_fdinfo = Struct( 'pfi' / proc_fileinfo, 'psi' / socket_info, ) pipe_info = Struct( 'pipe_stat' / vinfo_stat, 'pipe_handle' / uint64_t, 'pipe_peerhandle' / uint64_t, 'pipe_status' / Int32sl, 'rfu_1' / Int32sl # reserved ) pipe_fdinfo = Struct( 'pfi' / proc_fileinfo, 'pipeinfo' / pipe_info, ) vm_region_basic_info = Struct( 'protection' / vm_prot_t, 'max_protection' / vm_prot_t, 'inheritance' / vm_inherit_t, 'shared' / boolean_t, 'reserved' / boolean_t, Padding(4), 'offset' / memory_object_offset_t, 'behavior' / vm_behavior_t, 'user_wired_count' / Int16ul, ) vm_region_basic_info_64 = Struct( 'protection' / vm_prot_t, 'max_protection' / vm_prot_t, 'inheritance' / vm_inherit_t, 'shared' / boolean_t, 'reserved' / boolean_t, Padding(4), 'offset' / memory_object_offset_t, 'behavior' / vm_behavior_t, 'user_wired_count' / Int16ul, ) VM_REGION_BASIC_INFO_COUNT_64 = vm_region_basic_info_64.sizeof() // 4 vm_region_basic_info_data_t = vm_region_basic_info natural_t = Int32ul task_dyld_info = Struct( 'all_image_info_addr' / mach_vm_address_t, 'all_image_info_size' / mach_vm_size_t, 'all_image_info_format' / integer_t, ) uuid_t = Struct( 'time_low' / Int64ul, 'time_mid' / Int32ul, 'time_hi_and_version' / Int32ul, 'clock_seq_hi_and_reserved' / Int8ul, 'clock_seq_low' / Int8ul, 'node' / Array(6, Int8ul) ) dyld_image_info_t = Struct( 'imageLoadAddress' / Int64ul, 'imageFilePath' / Int64ul, 'imageFileModDate' / Int64ul ) all_image_infos_t = Struct( 'version' / Int32ul, 'infoArrayCount' / Int32ul, 'infoArray' / Int64ul, ) task_dyld_info_data_t = task_dyld_info TASK_DYLD_INFO_COUNT = task_dyld_info_data_t.sizeof() / natural_t.sizeof() STRUCT_ARM_THREAD_STATE64 = Struct( 'x' / Array(29, uint64_t), 'fp' / Default(uint64_t, 0), 'lr' / Default(uint64_t, 0), 'sp' / Default(uint64_t, 0), 'pc' / Default(uint64_t, 0), 'cpsr' / Default(uint32_t, 0), Padding(4), ) arm_thread_state64_t = STRUCT_ARM_THREAD_STATE64 ARM_THREAD_STATE64_COUNT = arm_thread_state64_t.sizeof() // uint32_t.sizeof() STRUCT_X86_THREAD_STATE32 = Struct( 'eax' / Int32sl, 'ebx' / Int32sl, 'ecx' / Int32sl, 'edx' / Int32sl, 'edi' / Int32sl, 'esi' / Int32sl, 'ebp' / Int32sl, 'esp' / Int32sl, 'ss' / Int32sl, 'eflags' / Int32sl, 'eip' / Int32sl, 'cs' / Int32sl, 'ds' / Int32sl, 'es' / Int32sl, 'fs' / Int32sl, 'gs' / Int32sl, ) x86_thread_state32_t = STRUCT_X86_THREAD_STATE32 STRUCT_X86_THREAD_STATE64 = Struct( 'rax' / uint64_t, 'rbx' / uint64_t, 'rcx' / uint64_t, 'rdx' / uint64_t, 'rdi' / uint64_t, 'rsi' / uint64_t, 'rbp' / uint64_t, 'rsp' / uint64_t, 'r8' / uint64_t, 'r9' / uint64_t, 'r10' / uint64_t, 'r11' / uint64_t, 'r12' / uint64_t, 'r13' / uint64_t, 'r14' / uint64_t, 'r15' / uint64_t, 'rip' / uint64_t, 'rflags' / uint64_t, 'cs' / uint64_t, 'fs' / uint64_t, 'gs' / uint64_t, ) x86_thread_state64_t = STRUCT_X86_THREAD_STATE64 suseconds_t = uint32_t timeval = Struct( 'tv_sec' / time_t, Padding(4), 'tv_usec' / suseconds_t, Padding(4), ) procargs2_t = Struct( 'argc' / Int32ul, 'executable' / Aligned(4, CString('utf8')), 'argv' / Array(this.argc, CString('utf8')), '_environ_apple' / GreedyRange(CString('utf8')), 'environ_apple' / Computed(lambda ctx: [s for s in ctx._environ_apple if s]), ) # See: https://opensource.apple.com/source/xnu/xnu-7195.81.3/EXTERNAL_HEADERS/mach-o/loader.h LC_REQ_DYLD = 0x80000000 LOAD_COMMAND_TYPE = Enum(Int32ul, LC_SEGMENT=0x1, LC_SYMTAB=0x2, LC_SYMSEG=0x3, LC_THREAD=0x4, LC_UNIXTHREAD=0x5, LC_LOADFVMLIB=0x6, LC_IDFVMLIB=0x7, LC_IDENT=0x8, LC_FVMFILE=0x9, LC_PREPAGE=0xa, LC_DYSYMTAB=0xb, LC_LOAD_DYLIB=0xc, LC_ID_DYLIB=0xd, LC_LOAD_DYLINKER=0xe, LC_ID_DYLINKER=0xf, LC_PREBOUND_DYLIB=0x10, LC_ROUTINES=0x11, LC_SUB_FRAMEWORK=0x12, LC_SUB_UMBRELLA=0x13, LC_SUB_CLIENT=0x14, LC_SUB_LIBRARY=0x15, LC_TWOLEVEL_HINTS=0x16, LC_PREBIND_CKSUM=0x17, LC_LOAD_WEAK_DYLIB=(0x18 | LC_REQ_DYLD), LC_SEGMENT_64=0x19, LC_ROUTINES_64=0x1a, LC_UUID=0x1b, LC_RPATH=(0x1c | LC_REQ_DYLD), LC_CODE_SIGNATURE=0x1d, LC_SEGMENT_SPLIT_INFO=0x1e, LC_REEXPORT_DYLIB=0x1f | LC_REQ_DYLD, LC_LAZY_LOAD_DYLIB=0x20, LC_ENCRYPTION_INFO=0x21, LC_DYLD_INFO=0x22, LC_DYLD_INFO_ONLY=(0x22 | LC_REQ_DYLD), LC_LOAD_UPWARD_DYLIB=(0x23 | LC_REQ_DYLD), LC_VERSION_MIN_MACOSX=0x24, LC_VERSION_MIN_IPHONEOS=0x25, LC_FUNCTION_STARTS=0x26, LC_DYLD_ENVIRONMENT=0x27, LC_MAIN=(0x28 | LC_REQ_DYLD), LC_DATA_IN_CODE=0x29, LC_SOURCE_VERSION=0x2A, LC_DYLIB_CODE_SIGN_DRS=0x2B, LC_ENCRYPTION_INFO_64=0x2C, LC_LINKER_OPTION=0x2D, LC_LINKER_OPTIMIZATION_HINT=0x2E, LC_VERSION_MIN_TVOS=0x2F, LC_VERSION_MIN_WATCHOS=0x30, LC_NOTE=0x31, LC_BUILD_VERSION=0x32, LC_DYLD_EXPORTS_TRIE=(0x33 | LC_REQ_DYLD), LC_DYLD_CHAINED_FIXUPS=(0x34 | LC_REQ_DYLD), LC_FILESET_ENTRY=(0x35 | LC_REQ_DYLD) ) # Load commands: # reference - https://opensource.apple.com/source/xnu/xnu-2050.18.24/EXTERNAL_HEADERS/mach-o/loader.h FAT_MAGIC = 0xcafebabe FAT_CIGAM = 0xbebafeca cpu_type_t = Int32ul cpu_subtype_t = Int32ul version_t = BitStruct( 'major' / BitsInteger(16), 'minor' / Octet, 'bug' / Octet ) segment_command_t = Struct( 'segname' / PaddedString(16, 'utf8'), 'vmaddr' / Int64ul, 'vmsize' / Int64ul, 'fileoff' / Int64ul, 'filesize' / Int64ul, 'maxprot' / Int32ul, 'initprot' / Int32ul, 'nsects' / Int32ul, 'flags' / Int32ul, ) uuid_command_t = Struct( 'uuid' / Array(16, Int8ul) ) build_tool_version = Struct( 'tool' / Int32ul, 'version' / Int32ul ) build_version_command_t = Struct( 'platform' / Int32ul, 'minos' / version_t, 'sdk' / version_t, 'ntools' / Int32ul, ) encryption_info_command = Struct( 'cryptoff' / Int32ul, # file offset of encrypted range 'cryptsize' / Int32ul, # file size of encrypted range 'cryptid' / Int32ul, # which encryption system, 0 means not-encrypted yet ) encryption_info_command_64 = Struct( 'cryptoff' / Int32ul, # file offset of encrypted range 'cryptsize' / Int32ul, # file size of encrypted range 'cryptid_offset' / Tell, 'cryptid' / Int32ul, # which encryption system, 0 means not-encrypted yet '_pad' / Int32ul, ) load_command_t = Struct( '_start' / Tell, 'cmd' / LOAD_COMMAND_TYPE, 'cmdsize' / Int32ul, '_data_offset' / Tell, 'data' / Switch(this.cmd, { LOAD_COMMAND_TYPE.LC_BUILD_VERSION: build_version_command_t, LOAD_COMMAND_TYPE.LC_UUID: uuid_command_t, LOAD_COMMAND_TYPE.LC_SEGMENT_64: segment_command_t, LOAD_COMMAND_TYPE.LC_ENCRYPTION_INFO_64: encryption_info_command_64, LOAD_COMMAND_TYPE.LC_ENCRYPTION_INFO: encryption_info_command, }, Bytes(this.cmdsize - (this._data_offset - this._start))), Seek(this._start + this.cmdsize), ) mach_header_t = Struct( 'load_address' / Tell, 'magic' / Hex(Int32ul), 'cputype' / Hex(cpu_type_t), 'cpusubtype' / Hex(cpu_subtype_t), 'filetype' / Hex(Int32ul), 'ncmds' / Hex(Int32ul), 'sizeofcmds' / Hex(Int32ul), 'flags' / Hex(Int32ul), 'reserved' / Hex(Int32ul), 'load_commands' / LazyArray(this.ncmds, load_command_t), ) fat_arch = Struct( 'cputype' / Hex(Int32ub), 'cpusubtype' / Hex(Int32ub), 'offset' / Hex(Int32ub), 'size' / Hex(Int32ub), 'align' / Hex(Int32ub), ) fat_header = Struct( 'magic' / Hex(Int32ul), 'nfat_arch' / Hex(Int32ub), 'archs' / Array(this.nfat_arch, fat_arch) )