首页 > 其他分享 >基于修改iOS内核绕过iOS 基于svc 0x80的ptrace反调试

基于修改iOS内核绕过iOS 基于svc 0x80的ptrace反调试

时间:2024-06-06 18:12:48浏览次数:18  
标签:基于 struct memstat int iOS svc process proc PL


yuzhouheike  

看到一个帖子:[原创]绕过iOS 基于svc 0x80的ptrace反调试
24
.跟着操作了下.这篇文章的核心思想来源于[原创]iOS内核修改之过某音等PT_DENY_ATTACH反动态ptrace调试

我的设备是:iphone7 iOS 14.1 , Darwin Kernel Version 20.0.0: Wed Sep 30 03:24:41 PDT 2020; root:xnu-7195.0.46~41/RELEASE_ARM64_T8010

iOSFuckDenyAttach-iPhone7-14.1 15

执行后失败

 

2221717485185_.pic_hd 2221717485185_.pic_hd1920×1353 251 KB

 

怀疑proc结构体不同版本不一样所以按照自己的手机xnu相近版本修改了proc结构体

 
struct  proc {
LIST_ENTRY(proc) p_list;                /* List of all processes. */

void *          XNU_PTRAUTH_SIGNED_PTR("proc.task") task;       /* corresponding task (static)*/
struct  proc *  XNU_PTRAUTH_SIGNED_PTR("proc.p_pptr") p_pptr;   /* Pointer to parent process.(LL) */
pid_t           p_ppid;                 /* process's parent pid number */
pid_t           p_original_ppid;        /* process's original parent pid number, doesn't change if reparented */
pid_t           p_pgrpid;               /* process group id of the process (LL)*/
uid_t           p_uid;
gid_t           p_gid;
uid_t           p_ruid;
gid_t           p_rgid;
uid_t           p_svuid;
gid_t           p_svgid;
uint64_t        p_uniqueid;             /* process unique ID - incremented on fork/spawn/vfork, remains same across exec. */
uint64_t        p_puniqueid;            /* parent's unique ID - set on fork/spawn/vfork, doesn't change if reparented. */

lck_mtx_t       p_mlock;                /* mutex lock for proc */
pid_t           p_pid;                  /* Process identifier. (static)*/
char            p_stat;                 /* S* process status. (PL)*/
char            p_shutdownstate;
char            p_kdebug;               /* P_KDEBUG eq (CC)*/
char            p_btrace;               /* P_BTRACE eq (CC)*/

LIST_ENTRY(proc) p_pglist;              /* List of processes in pgrp.(PGL) */
LIST_ENTRY(proc) p_sibling;             /* List of sibling processes. (LL)*/
LIST_HEAD(, proc) p_children;           /* Pointer to list of children. (LL)*/
TAILQ_HEAD(, uthread) p_uthlist;        /* List of uthreads  (PL) */

LIST_ENTRY(proc) p_hash;                /* Hash chain. (LL)*/

#if CONFIG_PERSONAS
struct persona  *p_persona;
LIST_ENTRY(proc) p_persona_list;
#endif

lck_mtx_t       p_fdmlock;              /* proc lock to protect fdesc */
lck_mtx_t       p_ucred_mlock;          /* mutex lock to protect p_ucred */

    /* substructures: */
kauth_cred_t    XNU_PTRAUTH_SIGNED_PTR("proc.p_ucred") p_ucred; /* Process owner's identity. (PUCL) */
struct  filedesc *p_fd;                 /* Ptr to open files structure. (PFDL) */
struct  pstats *p_stats;                /* Accounting/statistics (PL). */
struct  plimit *p_limit;                /* Process limits.(PL) */

struct  sigacts *p_sigacts;             /* Signal actions, state (PL) */
lck_spin_t      p_slock;                /* spin lock for itimer/profil protection */

int             p_siglist;              /* signals captured back from threads */
unsigned int    p_flag;                 /* P_* flags. (atomic bit ops) */
unsigned int    p_lflag;                /* local flags  (PL) */
unsigned int    p_listflag;             /* list flags (LL) */
unsigned int    p_ladvflag;             /* local adv flags (atomic) */
int             p_refcount;             /* number of outstanding users(LL) */
int             p_childrencnt;          /* children holding ref on parent (LL) */
int             p_parentref;            /* children lookup ref on parent (LL) */
pid_t           p_oppid;                /* Save parent pid during ptrace. XXX */
u_int           p_xstat;                /* Exit status for wait; also stop signal. */

#ifdef _PROC_HAS_SCHEDINFO_
    /* may need cleanup, not used */
u_int           p_estcpu;               /* Time averaged value of p_cpticks.(used by aio and proc_comapre) */
fixpt_t         p_pctcpu;               /* %cpu for this process during p_swtime (used by aio)*/
u_int           p_slptime;              /* used by proc_compare */
#endif /* _PROC_HAS_SCHEDINFO_ */

struct  itimerval p_realtimer;          /* Alarm timer. (PSL) */
struct  timeval p_rtime;                /* Real time.(PSL)  */
struct  itimerval p_vtimer_user;        /* Virtual timers.(PSL)  */
struct  itimerval p_vtimer_prof;        /* (PSL) */

struct  timeval p_rlim_cpu;             /* Remaining rlim cpu value.(PSL) */
int             p_debugger;             /*  NU 1: can exec set-bit programs if suser */
boolean_t       sigwait;        /* indication to suspend (PL) */
void    *sigwait_thread;        /* 'thread' holding sigwait(PL)  */
void    *exit_thread;           /* Which thread is exiting(PL)  */
void *  p_vforkact;             /* activation running this vfork proc)(static)  */
int     p_vforkcnt;             /* number of outstanding vforks(PL)  */
int     p_fpdrainwait;          /* (PFDL) */
    /* Following fields are info from SIGCHLD (PL) */
pid_t   si_pid;                 /* (PL) */
u_int   si_status;              /* (PL) */
u_int   si_code;                /* (PL) */
uid_t   si_uid;                 /* (PL) */

void * vm_shm;                  /* (SYSV SHM Lock) for sysV shared memory */

#if CONFIG_DTRACE
user_addr_t                     p_dtrace_argv;                  /* (write once, read only after that) */
user_addr_t                     p_dtrace_envp;                  /* (write once, read only after that) */
lck_mtx_t                       p_dtrace_sprlock;               /* sun proc lock emulation */
uint8_t                         p_dtrace_stop;                  /* indicates a DTrace-desired stop */
int                             p_dtrace_probes;                /* (PL) are there probes for this proc? */
u_int                           p_dtrace_count;                 /* (sprlock) number of DTrace tracepoints */
struct dtrace_ptss_page*        p_dtrace_ptss_pages;            /* (sprlock) list of user ptss pages */
struct dtrace_ptss_page_entry*  p_dtrace_ptss_free_list;        /* (atomic) list of individual ptss entries */
struct dtrace_helpers*          p_dtrace_helpers;               /* (dtrace_lock) DTrace per-proc private */
struct dof_ioctl_data*          p_dtrace_lazy_dofs;             /* (sprlock) unloaded dof_helper_t's */
#endif /* CONFIG_DTRACE */

/* XXXXXXXXXXXXX BCOPY'ed on fork XXXXXXXXXXXXXXXX */
/* The following fields are all copied upon creation in fork. */
#define p_startcopy     p_argslen

u_int   p_argslen;       /* Length of process arguments. */
int     p_argc;                 /* saved argc for sysctl_procargs() */
user_addr_t user_stack;         /* where user stack was allocated */
struct  vnode * XNU_PTRAUTH_SIGNED_PTR("proc.p_textvp") p_textvp;       /* Vnode of executable. */
off_t   p_textoff;              /* offset in executable vnode */

sigset_t p_sigmask;             /* DEPRECATED */
sigset_t p_sigignore;   /* Signals being ignored. (PL) */
sigset_t p_sigcatch;    /* Signals being caught by user.(PL)  */

u_char  p_priority;     /* (NU) Process priority. */
u_char  p_resv0;        /* (NU) User-priority based on p_cpu and p_nice. */
char    p_nice;         /* Process "nice" value.(PL) */
u_char  p_resv1;        /* (NU) User-priority based on p_cpu and p_nice. */

// types currently in sys/param.h
command_t   p_comm;
proc_name_t p_name;     /* can be changed by the process */
uint8_t p_xhighbits;    /* Stores the top byte of exit status to avoid truncation*/
pid_t   p_contproc;     /* last PID to send us a SIGCONT (PL) */

struct  pgrp *  XNU_PTRAUTH_SIGNED_PTR("proc.p_pgrp") p_pgrp; /* Pointer to process group. (LL) */
uint32_t        p_csflags;      /* flags for codesign (PL) */
uint32_t        p_pcaction;     /* action  for process control on starvation */
uint8_t p_uuid[16];             /* from LC_UUID load command */

    /*
     * CPU type and subtype of binary slice executed in
     * this process.  Protected by proc lock.
     */
cpu_type_t      p_cputype;
cpu_subtype_t   p_cpusubtype;

uint8_t  *syscall_filter_mask;          /* syscall filter bitmask (length: nsysent bits) */
uint32_t        p_platform;
uint32_t        p_min_sdk;
uint32_t        p_sdk;

/* End area that is copied on creation. */
/* XXXXXXXXXXXXX End of BCOPY'ed on fork (AIOLOCK)XXXXXXXXXXXXXXXX */
#define p_endcopy       p_aio_total_count
int             p_aio_total_count;              /* all allocated AIO requests for this proc */
TAILQ_HEAD(, aio_workq_entry ) p_aio_activeq;   /* active async IO requests */
TAILQ_HEAD(, aio_workq_entry ) p_aio_doneq;     /* completed async IO requests */

struct klist p_klist;  /* knote list (PL ?)*/

struct  rusage_superset *p_ru;  /* Exit information. (PL) */
thread_t        p_signalholder;
thread_t        p_transholder;
int             p_sigwaitcnt;
    /* DEPRECATE following field  */
u_short p_acflag;       /* Accounting flags. */
volatile u_short p_vfs_iopolicy;        /* VFS iopolicy flags. (atomic bit ops) */

user_addr_t     p_threadstart;          /* pthread start fn */
user_addr_t     p_wqthread;             /* pthread workqueue fn */
int     p_pthsize;                      /* pthread size */
uint32_t        p_pth_tsd_offset;       /* offset from pthread_t to TSD for new threads */
user_addr_t     p_stack_addr_hint;      /* stack allocation hint for wq threads */
struct workqueue *_Atomic p_wqptr;                      /* workq ptr */

struct  timeval p_start;                /* starting time */
void *  p_rcall;
int             p_ractive;
int     p_idversion;            /* version of process identity */
void *  p_pthhash;                      /* pthread waitqueue hash */
volatile uint64_t was_throttled __attribute__((aligned(8))); /* Counter for number of throttled I/Os */
volatile uint64_t did_throttle __attribute__((aligned(8)));  /* Counter for number of I/Os this proc throttled */

#if DIAGNOSTIC
unsigned int p_fdlock_pc[4];
unsigned int p_fdunlock_pc[4];
#if SIGNAL_DEBUG
unsigned int lockpc[8];
unsigned int unlockpc[8];
#endif /* SIGNAL_DEBUG */
#endif /* DIAGNOSTIC */
uint64_t        p_dispatchqueue_offset;
uint64_t        p_dispatchqueue_serialno_offset;
uint64_t        p_dispatchqueue_label_offset;
uint64_t        p_return_to_kernel_offset;
uint64_t        p_mach_thread_self_offset;
#if VM_PRESSURE_EVENTS
struct timeval  vm_pressure_last_notify_tstamp;
#endif

#if CONFIG_MEMORYSTATUS
    /* Fields protected by proc list lock */
TAILQ_ENTRY(proc) p_memstat_list;               /* priority bucket link */
uint32_t          p_memstat_state;              /* state. Also used as a wakeup channel when the memstat's LOCKED bit changes */
int32_t           p_memstat_effectivepriority;  /* priority after transaction state accounted for */
int32_t           p_memstat_requestedpriority;  /* active priority */
int32_t           p_memstat_assertionpriority;  /* assertion driven priority */
uint32_t          p_memstat_dirty;              /* dirty state */
uint64_t          p_memstat_userdata;           /* user state */
uint64_t          p_memstat_idledeadline;       /* time at which process became clean */
uint64_t          p_memstat_idle_start;         /* abstime process transitions into the idle band */
uint64_t          p_memstat_idle_delta;         /* abstime delta spent in idle band */
int32_t           p_memstat_memlimit;           /* cached memory limit, toggles between active and inactive limits */
int32_t           p_memstat_memlimit_active;    /* memory limit enforced when process is in active jetsam state */
int32_t           p_memstat_memlimit_inactive;  /* memory limit enforced when process is in inactive jetsam state */
int32_t           p_memstat_relaunch_flags;     /* flags indicating relaunch behavior for the process */
#if CONFIG_FREEZE
uint32_t          p_memstat_freeze_sharedanon_pages; /* shared pages left behind after freeze */
uint32_t          p_memstat_frozen_count;
uint32_t          p_memstat_thaw_count;
#endif /* CONFIG_FREEZE */
#endif /* CONFIG_MEMORYSTATUS */

    /* cached proc-specific data required for corpse inspection */
pid_t             p_responsible_pid;    /* pid resonsible for this process */
_Atomic uint32_t  p_user_faults; /* count the number of user faults generated */

uint32_t          p_memlimit_increase; /* byte increase for memory limit for dyld SPI rdar://problem/49950264, structure packing 32-bit and 64-bit */

struct os_reason     *p_exit_reason;

#if CONFIG_PROC_UDATA_STORAGE
uint64_t        p_user_data;                    /* general-purpose storage for userland-provided data */
#endif /* CONFIG_PROC_UDATA_STORAGE */

char * p_subsystem_root_path;
lck_rw_t        p_dirs_lock;                    /* keeps fd_cdir and fd_rdir stable across a lookup */
pid_t           p_sessionid;
};

修改后的代码如下

 
//main.c

#include <assert.h>
#include <mach/mach.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#include "find_kernel_base_under_checkra1n.h"

#include <sys/proc.h>
#include <sys/param.h>


//#define CONFIG_DTRACE 1

//#define CONFIG_PERSONAS 1
//#define _PROC_HAS_SCHEDINFO_ 1

typedef char command_t[MAXCOMLEN + 1];
typedef char proc_name_t[2*MAXCOMLEN + 1];
typedef void * lck_mtx_t;
typedef void * kauth_cred_t;
typedef void * lck_spin_t;
/*
 * Description of a process.
 *
 * This structure contains the information needed to manage a thread of
 * control, known in UN*X as a process; it has references to substructures
 * containing descriptions of things that the process uses, but may share
 * with related processes.  The process structure and the substructures
 * are always addressible except for those marked "(PROC ONLY)" below,
 * which might be addressible only on a processor on which the process
 * is running.
 */

// struct  proc {
// 	LIST_ENTRY(proc) p_list;                /* List of all processes. */

// 	void *           task;       /* corresponding task (static)*/
// 	struct  proc *  p_pptr;   /* Pointer to parent process.(LL) */
// 	pid_t           p_ppid;                 /* process's parent pid number */
// 	pid_t           p_original_ppid;        /* process's original parent pid number, doesn't change if reparented */
// 	pid_t           p_pgrpid;               /* process group id of the process (LL)*/
// 	uid_t           p_uid;
// 	gid_t           p_gid;
// 	uid_t           p_ruid;
// 	gid_t           p_rgid;
// 	uid_t           p_svuid;
// 	gid_t           p_svgid;
// 	uint64_t        p_uniqueid;             /* process unique ID - incremented on fork/spawn/vfork, remains same across exec. */
// 	uint64_t        p_puniqueid;            /* parent's unique ID - set on fork/spawn/vfork, doesn't change if reparented. */

// 	lck_mtx_t       p_mlock;                /* mutex lock for proc */
// 	pid_t           p_pid;                  /* Process identifier. (static)*/
// 	char            p_stat;                 /* S* process status. (PL)*/
// 	char            p_shutdownstate;
// 	char            p_kdebug;               /* P_KDEBUG eq (CC)*/
// 	char            p_btrace;               /* P_BTRACE eq (CC)*/

// 	LIST_ENTRY(proc) p_pglist;              /* List of processes in pgrp.(PGL) */
// 	LIST_ENTRY(proc) p_sibling;             /* List of sibling processes. (LL)*/
// 	LIST_HEAD(, proc) p_children;           /* Pointer to list of children. (LL)*/
// 	TAILQ_HEAD(, uthread) p_uthlist;        /* List of uthreads  (PL) */

// 	LIST_ENTRY(proc) p_hash;                /* Hash chain. (LL)*/

// #if CONFIG_PERSONAS
// 	struct persona  *p_persona;
// 	LIST_ENTRY(proc) p_persona_list;
// #endif

// 	lck_mtx_t       p_fdmlock;              /* proc lock to protect fdesc */
// 	lck_mtx_t       p_ucred_mlock;          /* mutex lock to protect p_ucred */

// 	/* substructures: */
// 	kauth_cred_t    p_ucred; /* Process owner's identity. (PUCL) */
// 	struct  filedesc *p_fd;                 /* Ptr to open files structure. (PFDL) */
// 	struct  pstats *p_stats;                /* Accounting/statistics (PL). */
// 	struct  plimit *p_limit;                /* Process limits.(PL) */

// 	struct  sigacts *p_sigacts;             /* Signal actions, state (PL) */
// 	lck_spin_t      p_slock;                /* spin lock for itimer/profil protection */

// 	int             p_siglist;              /* signals captured back from threads */
// 	unsigned int    p_flag;                 /* P_* flags. (atomic bit ops) */
// 	unsigned int    p_lflag;                /* local flags  (PL) */
// 	unsigned int    p_listflag;             /* list flags (LL) */
// 	unsigned int    p_ladvflag;             /* local adv flags (atomic) */
// 	int             p_refcount;             /* number of outstanding users(LL) */
// 	int             p_childrencnt;          /* children holding ref on parent (LL) */
// 	int             p_parentref;            /* children lookup ref on parent (LL) */
// 	pid_t           p_oppid;                /* Save parent pid during ptrace. XXX */
// 	u_int           p_xstat;                /* Exit status for wait; also stop signal. */

// #ifdef _PROC_HAS_SCHEDINFO_
// 	/* may need cleanup, not used */
// 	u_int           p_estcpu;               /* Time averaged value of p_cpticks.(used by aio and proc_comapre) */
// 	fixpt_t         p_pctcpu;               /* %cpu for this process during p_swtime (used by aio)*/
// 	u_int           p_slptime;              /* used by proc_compare */
// #endif /* _PROC_HAS_SCHEDINFO_ */

// 	struct  itimerval p_realtimer;          /* Alarm timer. (PSL) */
// 	struct  timeval p_rtime;                /* Real time.(PSL)  */
// 	struct  itimerval p_vtimer_user;        /* Virtual timers.(PSL)  */
// 	struct  itimerval p_vtimer_prof;        /* (PSL) */

// 	struct  timeval p_rlim_cpu;             /* Remaining rlim cpu value.(PSL) */
// 	int             p_debugger;             /*  NU 1: can exec set-bit programs if suser */
// 	boolean_t       sigwait;        /* indication to suspend (PL) */
// 	void    *sigwait_thread;        /* 'thread' holding sigwait(PL)  */
// 	void    *exit_thread;           /* Which thread is exiting(PL)  */
// 	void *  p_vforkact;             /* activation running this vfork proc)(static)  */
// 	int     p_vforkcnt;             /* number of outstanding vforks(PL)  */
// 	int     p_fpdrainwait;          /* (PFDL) */
// 	/* Following fields are info from SIGCHLD (PL) */
// 	pid_t   si_pid;                 /* (PL) */
// 	u_int   si_status;              /* (PL) */
// 	u_int   si_code;                /* (PL) */
// 	uid_t   si_uid;                 /* (PL) */

// 	void * vm_shm;                  /* (SYSV SHM Lock) for sysV shared memory */

// #if CONFIG_DTRACE
// 	user_addr_t                     p_dtrace_argv;                  /* (write once, read only after that) */
// 	user_addr_t                     p_dtrace_envp;                  /* (write once, read only after that) */
// 	lck_mtx_t                       p_dtrace_sprlock;               /* sun proc lock emulation */
// 	uint8_t                         p_dtrace_stop;                  /* indicates a DTrace-desired stop */
// 	int                             p_dtrace_probes;                /* (PL) are there probes for this proc? */
// 	u_int                           p_dtrace_count;                 /* (sprlock) number of DTrace tracepoints */
// 	struct dtrace_ptss_page*        p_dtrace_ptss_pages;            /* (sprlock) list of user ptss pages */
// 	struct dtrace_ptss_page_entry*  p_dtrace_ptss_free_list;        /* (atomic) list of individual ptss entries */
// 	struct dtrace_helpers*          p_dtrace_helpers;               /* (dtrace_lock) DTrace per-proc private */
// 	struct dof_ioctl_data*          p_dtrace_lazy_dofs;             /* (sprlock) unloaded dof_helper_t's */
// #endif /* CONFIG_DTRACE */

// /* XXXXXXXXXXXXX BCOPY'ed on fork XXXXXXXXXXXXXXXX */
// /* The following fields are all copied upon creation in fork. */
// #define p_startcopy     p_argslen

// 	u_int   p_argslen;       /* Length of process arguments. */
// 	int     p_argc;                 /* saved argc for sysctl_procargs() */
// 	user_addr_t user_stack;         /* where user stack was allocated */
// 	struct  vnode *  p_textvp;       /* Vnode of executable. */
// 	off_t   p_textoff;              /* offset in executable vnode */

// 	sigset_t p_sigmask;             /* DEPRECATED */
// 	sigset_t p_sigignore;   /* Signals being ignored. (PL) */
// 	sigset_t p_sigcatch;    /* Signals being caught by user.(PL)  */

// 	u_char  p_priority;     /* (NU) Process priority. */
// 	u_char  p_resv0;        /* (NU) User-priority based on p_cpu and p_nice. */
// 	char    p_nice;         /* Process "nice" value.(PL) */
// 	u_char  p_resv1;        /* (NU) User-priority based on p_cpu and p_nice. */

// 	// types currently in sys/param.h
// 	command_t   p_comm;
// 	proc_name_t p_name;     /* can be changed by the process */
// 	uint8_t p_xhighbits;    /* Stores the top byte of exit status to avoid truncation*/
// 	pid_t   p_contproc;     /* last PID to send us a SIGCONT (PL) */

// 	struct  pgrp *   p_pgrp; /* Pointer to process group. (LL) */
// 	uint32_t        p_csflags;      /* flags for codesign (PL) */
// 	uint32_t        p_pcaction;     /* action  for process control on starvation */
// 	uint8_t p_uuid[16];             /* from LC_UUID load command */

// 	/*
// 	 * CPU type and subtype of binary slice executed in
// 	 * this process.  Protected by proc lock.
// 	 */
// 	cpu_type_t      p_cputype;
// 	cpu_subtype_t   p_cpusubtype;

// 	uint8_t  *syscall_filter_mask;          /* syscall filter bitmask (length: nsysent bits) */
// 	uint32_t        p_platform;
// 	uint32_t        p_min_sdk;
// 	uint32_t        p_sdk;

// /* End area that is copied on creation. */
// /* XXXXXXXXXXXXX End of BCOPY'ed on fork (AIOLOCK)XXXXXXXXXXXXXXXX */
// #define p_endcopy       p_aio_total_count
// 	int             p_aio_total_count;              /* all allocated AIO requests for this proc */
// 	TAILQ_HEAD(, aio_workq_entry ) p_aio_activeq;   /* active async IO requests */
// 	TAILQ_HEAD(, aio_workq_entry ) p_aio_doneq;     /* completed async IO requests */

// 	struct klist p_klist;  /* knote list (PL ?)*/

// 	struct  rusage_superset *p_ru;  /* Exit information. (PL) */
// 	thread_t        p_signalholder;
// 	thread_t        p_transholder;
// 	int             p_sigwaitcnt;
// 	/* DEPRECATE following field  */
// 	u_short p_acflag;       /* Accounting flags. */
// 	volatile u_short p_vfs_iopolicy;        /* VFS iopolicy flags. (atomic bit ops) */

// 	user_addr_t     p_threadstart;          /* pthread start fn */
// 	user_addr_t     p_wqthread;             /* pthread workqueue fn */
// 	int     p_pthsize;                      /* pthread size */
// 	uint32_t        p_pth_tsd_offset;       /* offset from pthread_t to TSD for new threads */
// 	user_addr_t     p_stack_addr_hint;      /* stack allocation hint for wq threads */
// 	struct workqueue *_Atomic p_wqptr;                      /* workq ptr */

// 	struct  timeval p_start;                /* starting time */
// 	void *  p_rcall;
// 	int             p_ractive;
// 	int     p_idversion;            /* version of process identity */
// 	void *  p_pthhash;                      /* pthread waitqueue hash */
// 	volatile uint64_t was_throttled __attribute__((aligned(8))); /* Counter for number of throttled I/Os */
// 	volatile uint64_t did_throttle __attribute__((aligned(8)));  /* Counter for number of I/Os this proc throttled */

// #if DIAGNOSTIC
// 	unsigned int p_fdlock_pc[4];
// 	unsigned int p_fdunlock_pc[4];
// #if SIGNAL_DEBUG
// 	unsigned int lockpc[8];
// 	unsigned int unlockpc[8];
// #endif /* SIGNAL_DEBUG */
// #endif /* DIAGNOSTIC */
// 	uint64_t        p_dispatchqueue_offset;
// 	uint64_t        p_dispatchqueue_serialno_offset;
// 	uint64_t        p_dispatchqueue_label_offset;
// 	uint64_t        p_return_to_kernel_offset;
// 	uint64_t        p_mach_thread_self_offset;
// #if VM_PRESSURE_EVENTS
// 	struct timeval  vm_pressure_last_notify_tstamp;
// #endif

// #if CONFIG_MEMORYSTATUS
// 	/* Fields protected by proc list lock */
// 	TAILQ_ENTRY(proc) p_memstat_list;               /* priority bucket link */
// 	uint32_t          p_memstat_state;              /* state. Also used as a wakeup channel when the memstat's LOCKED bit changes */
// 	int32_t           p_memstat_effectivepriority;  /* priority after transaction state accounted for */
// 	int32_t           p_memstat_requestedpriority;  /* active priority */
// 	int32_t           p_memstat_assertionpriority;  /* assertion driven priority */
// 	uint32_t          p_memstat_dirty;              /* dirty state */
// 	uint64_t          p_memstat_userdata;           /* user state */
// 	uint64_t          p_memstat_idledeadline;       /* time at which process became clean */
// 	uint64_t          p_memstat_idle_start;         /* abstime process transitions into the idle band */
// 	uint64_t          p_memstat_idle_delta;         /* abstime delta spent in idle band */
// 	int32_t           p_memstat_memlimit;           /* cached memory limit, toggles between active and inactive limits */
// 	int32_t           p_memstat_memlimit_active;    /* memory limit enforced when process is in active jetsam state */
// 	int32_t           p_memstat_memlimit_inactive;  /* memory limit enforced when process is in inactive jetsam state */
// 	int32_t           p_memstat_relaunch_flags;     /* flags indicating relaunch behavior for the process */
// #if CONFIG_FREEZE
// 	uint32_t          p_memstat_freeze_sharedanon_pages; /* shared pages left behind after freeze */
// 	uint32_t          p_memstat_frozen_count;
// 	uint32_t          p_memstat_thaw_count;
// #endif /* CONFIG_FREEZE */
// #endif /* CONFIG_MEMORYSTATUS */

// 	/* cached proc-specific data required for corpse inspection */
// 	pid_t             p_responsible_pid;    /* pid resonsible for this process */
// 	_Atomic uint32_t  p_user_faults; /* count the number of user faults generated */

// 	uint32_t          p_memlimit_increase; /* byte increase for memory limit for dyld SPI rdar://problem/49950264, structure packing 32-bit and 64-bit */

// 	struct os_reason     *p_exit_reason;

// #if CONFIG_PROC_UDATA_STORAGE
// 	uint64_t        p_user_data;                    /* general-purpose storage for userland-provided data */
// #endif /* CONFIG_PROC_UDATA_STORAGE */

// 	char * p_subsystem_root_path;
// 	// lck_rw_t        p_dirs_lock;                    /* keeps fd_cdir and fd_rdir stable across a lookup */
// 	pid_t           p_sessionid;
// };

struct  proc {
    LIST_ENTRY(proc) p_list;                /* List of all processes. */

    void *          task;       /* corresponding task (static)*/
    struct  proc *  p_pptr;   /* Pointer to parent process.(LL) */
    pid_t           p_ppid;                 /* process's parent pid number */
    pid_t           p_original_ppid;        /* process's original parent pid number, doesn't change if reparented */
    pid_t           p_pgrpid;               /* process group id of the process (LL)*/
    uid_t           p_uid;
    gid_t           p_gid;
    uid_t           p_ruid;
    gid_t           p_rgid;
    uid_t           p_svuid;
    gid_t           p_svgid;
    uint64_t        p_uniqueid;             /* process unique ID - incremented on fork/spawn/vfork, remains same across exec. */
    uint64_t        p_puniqueid;            /* parent's unique ID - set on fork/spawn/vfork, doesn't change if reparented. */

    lck_mtx_t       p_mlock;                /* mutex lock for proc */
    pid_t           p_pid;                  /* Process identifier. (static)*/
    char            p_stat;                 /* S* process status. (PL)*/
    char            p_shutdownstate;
    char            p_kdebug;               /* P_KDEBUG eq (CC)*/
    char            p_btrace;               /* P_BTRACE eq (CC)*/

    LIST_ENTRY(proc) p_pglist;              /* List of processes in pgrp.(PGL) */
    LIST_ENTRY(proc) p_sibling;             /* List of sibling processes. (LL)*/
    LIST_HEAD(, proc) p_children;           /* Pointer to list of children. (LL)*/
    TAILQ_HEAD(, uthread) p_uthlist;        /* List of uthreads  (PL) */

    LIST_ENTRY(proc) p_hash;                /* Hash chain. (LL)*/

#if CONFIG_PERSONAS
    struct persona  *p_persona;
    LIST_ENTRY(proc) p_persona_list;
#endif

    lck_mtx_t       p_fdmlock;              /* proc lock to protect fdesc */
    lck_mtx_t       p_ucred_mlock;          /* mutex lock to protect p_ucred */

    /* substructures: */
    kauth_cred_t    p_ucred; /* Process owner's identity. (PUCL) */
    struct  filedesc *p_fd;                 /* Ptr to open files structure. (PFDL) */
    struct  pstats *p_stats;                /* Accounting/statistics (PL). */
    struct  plimit *p_limit;                /* Process limits.(PL) */

    struct  sigacts *p_sigacts;             /* Signal actions, state (PL) */
    lck_spin_t      p_slock;                /* spin lock for itimer/profil protection */

    int             p_siglist;              /* signals captured back from threads */
    unsigned int    p_flag;                 /* P_* flags. (atomic bit ops) */
    unsigned int    p_lflag;                /* local flags  (PL) */
    unsigned int    p_listflag;             /* list flags (LL) */
    unsigned int    p_ladvflag;             /* local adv flags (atomic) */
    int             p_refcount;             /* number of outstanding users(LL) */
    int             p_childrencnt;          /* children holding ref on parent (LL) */
    int             p_parentref;            /* children lookup ref on parent (LL) */
    pid_t           p_oppid;                /* Save parent pid during ptrace. XXX */
    u_int           p_xstat;                /* Exit status for wait; also stop signal. */

#ifdef _PROC_HAS_SCHEDINFO_
    /* may need cleanup, not used */
    u_int           p_estcpu;               /* Time averaged value of p_cpticks.(used by aio and proc_comapre) */
    fixpt_t         p_pctcpu;               /* %cpu for this process during p_swtime (used by aio)*/
    u_int           p_slptime;              /* used by proc_compare */
#endif /* _PROC_HAS_SCHEDINFO_ */

    struct  itimerval p_realtimer;          /* Alarm timer. (PSL) */
    struct  timeval p_rtime;                /* Real time.(PSL)  */
    struct  itimerval p_vtimer_user;        /* Virtual timers.(PSL)  */
    struct  itimerval p_vtimer_prof;        /* (PSL) */

    struct  timeval p_rlim_cpu;             /* Remaining rlim cpu value.(PSL) */
    int             p_debugger;             /*  NU 1: can exec set-bit programs if suser */
    boolean_t       sigwait;        /* indication to suspend (PL) */
    void    *sigwait_thread;        /* 'thread' holding sigwait(PL)  */
    void    *exit_thread;           /* Which thread is exiting(PL)  */
    void *  p_vforkact;             /* activation running this vfork proc)(static)  */
    int     p_vforkcnt;             /* number of outstanding vforks(PL)  */
    int     p_fpdrainwait;          /* (PFDL) */
    /* Following fields are info from SIGCHLD (PL) */
    pid_t   si_pid;                 /* (PL) */
    u_int   si_status;              /* (PL) */
    u_int   si_code;                /* (PL) */
    uid_t   si_uid;                 /* (PL) */

    void * vm_shm;                  /* (SYSV SHM Lock) for sysV shared memory */

#if CONFIG_DTRACE
    user_addr_t                     p_dtrace_argv;                  /* (write once, read only after that) */
    user_addr_t                     p_dtrace_envp;                  /* (write once, read only after that) */
    lck_mtx_t                       p_dtrace_sprlock;               /* sun proc lock emulation */
    uint8_t                         p_dtrace_stop;                  /* indicates a DTrace-desired stop */
    int                             p_dtrace_probes;                /* (PL) are there probes for this proc? */
    u_int                           p_dtrace_count;                 /* (sprlock) number of DTrace tracepoints */
    struct dtrace_ptss_page*        p_dtrace_ptss_pages;            /* (sprlock) list of user ptss pages */
    struct dtrace_ptss_page_entry*  p_dtrace_ptss_free_list;        /* (atomic) list of individual ptss entries */
    struct dtrace_helpers*          p_dtrace_helpers;               /* (dtrace_lock) DTrace per-proc private */
    struct dof_ioctl_data*          p_dtrace_lazy_dofs;             /* (sprlock) unloaded dof_helper_t's */
#endif /* CONFIG_DTRACE */

/* XXXXXXXXXXXXX BCOPY'ed on fork XXXXXXXXXXXXXXXX */
/* The following fields are all copied upon creation in fork. */
#define p_startcopy     p_argslen

    u_int   p_argslen;       /* Length of process arguments. */
    int     p_argc;                 /* saved argc for sysctl_procargs() */
    user_addr_t user_stack;         /* where user stack was allocated */
    struct  vnode * p_textvp;       /* Vnode of executable. */
    off_t   p_textoff;              /* offset in executable vnode */

    sigset_t p_sigmask;             /* DEPRECATED */
    sigset_t p_sigignore;   /* Signals being ignored. (PL) */
    sigset_t p_sigcatch;    /* Signals being caught by user.(PL)  */

    u_char  p_priority;     /* (NU) Process priority. */
    u_char  p_resv0;        /* (NU) User-priority based on p_cpu and p_nice. */
    char    p_nice;         /* Process "nice" value.(PL) */
    u_char  p_resv1;        /* (NU) User-priority based on p_cpu and p_nice. */

    // types currently in sys/param.h
    command_t   p_comm;
    proc_name_t p_name;     /* can be changed by the process */
    uint8_t p_xhighbits;    /* Stores the top byte of exit status to avoid truncation*/
    pid_t   p_contproc;     /* last PID to send us a SIGCONT (PL) */

    struct  pgrp *  p_pgrp; /* Pointer to process group. (LL) */
    uint32_t        p_csflags;      /* flags for codesign (PL) */
    uint32_t        p_pcaction;     /* action  for process control on starvation */
    uint8_t p_uuid[16];             /* from LC_UUID load command */

    /*
     * CPU type and subtype of binary slice executed in
     * this process.  Protected by proc lock.
     */
    cpu_type_t      p_cputype;
    cpu_subtype_t   p_cpusubtype;

    uint8_t  *syscall_filter_mask;          /* syscall filter bitmask (length: nsysent bits) */
    uint32_t        p_platform;
    uint32_t        p_min_sdk;
    uint32_t        p_sdk;

/* End area that is copied on creation. */
/* XXXXXXXXXXXXX End of BCOPY'ed on fork (AIOLOCK)XXXXXXXXXXXXXXXX */
#define p_endcopy       p_aio_total_count
    int             p_aio_total_count;              /* all allocated AIO requests for this proc */
    TAILQ_HEAD(, aio_workq_entry ) p_aio_activeq;   /* active async IO requests */
    TAILQ_HEAD(, aio_workq_entry ) p_aio_doneq;     /* completed async IO requests */

    struct klist p_klist;  /* knote list (PL ?)*/

    struct  rusage_superset *p_ru;  /* Exit information. (PL) */
    thread_t        p_signalholder;
    thread_t        p_transholder;
    int             p_sigwaitcnt;
    /* DEPRECATE following field  */
    u_short p_acflag;       /* Accounting flags. */
    volatile u_short p_vfs_iopolicy;        /* VFS iopolicy flags. (atomic bit ops) */

    user_addr_t     p_threadstart;          /* pthread start fn */
    user_addr_t     p_wqthread;             /* pthread workqueue fn */
    int     p_pthsize;                      /* pthread size */
    uint32_t        p_pth_tsd_offset;       /* offset from pthread_t to TSD for new threads */
    user_addr_t     p_stack_addr_hint;      /* stack allocation hint for wq threads */
    struct workqueue *_Atomic p_wqptr;                      /* workq ptr */

    struct  timeval p_start;                /* starting time */
    void *  p_rcall;
    int             p_ractive;
    int     p_idversion;            /* version of process identity */
    void *  p_pthhash;                      /* pthread waitqueue hash */
    volatile uint64_t was_throttled __attribute__((aligned(8))); /* Counter for number of throttled I/Os */
    volatile uint64_t did_throttle __attribute__((aligned(8)));  /* Counter for number of I/Os this proc throttled */

#if DIAGNOSTIC
    unsigned int p_fdlock_pc[4];
    unsigned int p_fdunlock_pc[4];
#if SIGNAL_DEBUG
    unsigned int lockpc[8];
    unsigned int unlockpc[8];
#endif /* SIGNAL_DEBUG */
#endif /* DIAGNOSTIC */
    uint64_t        p_dispatchqueue_offset;
    uint64_t        p_dispatchqueue_serialno_offset;
    uint64_t        p_dispatchqueue_label_offset;
    uint64_t        p_return_to_kernel_offset;
    uint64_t        p_mach_thread_self_offset;
#if VM_PRESSURE_EVENTS
    struct timeval  vm_pressure_last_notify_tstamp;
#endif

#if CONFIG_MEMORYSTATUS
    /* Fields protected by proc list lock */
    TAILQ_ENTRY(proc) p_memstat_list;               /* priority bucket link */
    uint32_t          p_memstat_state;              /* state. Also used as a wakeup channel when the memstat's LOCKED bit changes */
    int32_t           p_memstat_effectivepriority;  /* priority after transaction state accounted for */
    int32_t           p_memstat_requestedpriority;  /* active priority */
    int32_t           p_memstat_assertionpriority;  /* assertion driven priority */
    uint32_t          p_memstat_dirty;              /* dirty state */
#if CONFIG_FREEZE
    uint8_t           p_memstat_freeze_skip_reason; /* memorystaus_freeze_skipped_reason_t. Protected by the freezer mutex. */
#endif
    uint64_t          p_memstat_userdata;           /* user state */
    uint64_t          p_memstat_idledeadline;       /* time at which process became clean */
    uint64_t          p_memstat_idle_start;         /* abstime process transitions into the idle band */
    uint64_t          p_memstat_idle_delta;         /* abstime delta spent in idle band */
    int32_t           p_memstat_memlimit;           /* cached memory limit, toggles between active and inactive limits */
    int32_t           p_memstat_memlimit_active;    /* memory limit enforced when process is in active jetsam state */
    int32_t           p_memstat_memlimit_inactive;  /* memory limit enforced when process is in inactive jetsam state */
    int32_t           p_memstat_relaunch_flags;     /* flags indicating relaunch behavior for the process */
#if CONFIG_FREEZE
    uint32_t          p_memstat_freeze_sharedanon_pages; /* shared pages left behind after freeze */
    uint32_t          p_memstat_frozen_count;
    uint32_t          p_memstat_thaw_count;
    uint32_t          p_memstat_last_thaw_interval; /* In which freezer interval was this last thawed? */
#endif /* CONFIG_FREEZE */
#endif /* CONFIG_MEMORYSTATUS */

    /* cached proc-specific data required for corpse inspection */
    pid_t             p_responsible_pid;    /* pid resonsible for this process */
    _Atomic uint32_t  p_user_faults; /* count the number of user faults generated */

    uint32_t          p_memlimit_increase; /* byte increase for memory limit for dyld SPI rdar://problem/49950264, structure packing 32-bit and 64-bit */

    struct os_reason     *p_exit_reason;

#if CONFIG_PROC_UDATA_STORAGE
    uint64_t        p_user_data;                    /* general-purpose storage for userland-provided data */
#endif /* CONFIG_PROC_UDATA_STORAGE */

    char * p_subsystem_root_path;
    void*        p_dirs_lock;                    /* keeps fd_cdir and fd_rdir stable across a lookup */
    pid_t           p_sessionid;
};


#define P_LNOATTACH     0x00001000      /* */

/* Macros to clear/set/test flags. */
#define SET(t, f)       (t) |= (f)
#define CLR(t, f)       (t) &= ~(f)
#define ISSET(t, f)     ((t) & (f))

// ---- Main --------------------------------------------------------------------------------------

//iPhone7 iOS14.1  kernel
// #define TARGET_KERNELCACHE_VERSION_STRING "@(#)VERSION: Darwin Kernel Version 19.4.0: Mon Feb 24 22:04:29 PST 2020; root:xnu-6153.102.3~1/RELEASE_ARM64_T8015"
//										   Darwin Kernel Version 20.0.0: Wed Sep 30 03:24:41 PDT 2020; root:xnu-7195.0.46~41/RELEASE_ARM64_T8010
#define TARGET_KERNELCACHE_VERSION_STRING "Darwin Kernel Version 20.0.0: Wed Sep 30 03:24:41 PDT 2020; root:xnu-7195.0.46~41/RELEASE_ARM64_T8010"

uint64_t get_kslide(void)
{
    task_t tfp0;
    kern_return_t ret = task_for_pid(mach_task_self(), 0, &tfp0);
    if(ret != KERN_SUCCESS) return 0;
    task_dyld_info_data_t info;
    uint32_t count = TASK_DYLD_INFO_COUNT;
    ret = task_info(tfp0, TASK_DYLD_INFO, (task_info_t)&info, &count);
    if(ret != KERN_SUCCESS) return 0;
    return info.all_image_info_size;
}

int main() {
	kernel_task_init();
	uint64_t kb = get_kslide() + 0xFFFFFFF007004000;
	printf("kbase: 0x%llx\n" , kb);
	printf("kslide: 0x%llx\n" , get_kslide());
	for (size_t i = 0; i < 8; i++) {
		printf("%016llx\n", kernel_read64(kb + 8 * i));
	}
	//iPhone7 iOS14.1  kernel
 
	uint64_t versionstraddr = kb + 0x3670f;
    char versionstr[256];
    if(kernel_read(versionstraddr, (void *)&versionstr, sizeof(versionstr)))
    {
        printf("versionstr %s\n", versionstr);
        if(strcmp(TARGET_KERNELCACHE_VERSION_STRING,versionstr) == 0)
        {
            printf("kernel cache hit\n");
            //iPhone7 iOS14.1  kernproc 

			uint64_t kernel_proc0 = kernel_read64(kb + 0x104240);

            struct proc * proc0 =  (void *)malloc(sizeof(struct proc));

            if(!kernel_read(kernel_proc0, (void *)proc0, sizeof(struct proc)))
            {
                printf("proc0 read failed\n");
                return -1;
            }
             printf("uniqueid offset 0x%llx  comm offset 0x%llx \n",(int64_t)&(proc0->p_uniqueid) - (int64_t)proc0, (int64_t)&(proc0->p_comm)- (int64_t)proc0);

            struct proc * proc1 =  (struct proc *)malloc(sizeof(struct proc));
            uint64_t preptr = (uint64_t)(proc0->p_list.le_prev);
            while(preptr){
                if(!kernel_read(preptr, (void *)proc1, sizeof(struct proc)))
                {
                    printf("procnext read failed\n");
                    return -1;
                }else{
                    if(proc1->p_list.le_prev == 0)
                    {
                        printf("proc1->p_list.le_prev == 0\n");
                        break;
                    }
                    int64_t lflagoffset = (int64_t)&(proc1->p_lflag) - (int64_t)proc1;
                    int lflagvalue = proc1->p_lflag;
                    printf("(%llu)%s  proc = 0x%llx   lflag = 0x%x  lflag offset = 0x%llx"
                        ,proc1->p_uniqueid, 
                        proc1->p_comm,//(char *)((int64_t)proc1 + 0x258),
                        preptr,lflagvalue,lflagoffset);

                        if( ISSET(lflagvalue, P_LNOATTACH))
                        {

						// change 630 to your target pid
							if(proc1->p_uniqueid == 630 ){
                  			printf(" !!!P_LNOATTACH set");
                            CLR(lflagvalue, P_LNOATTACH);
                            KERNEL_WRITE32(preptr + lflagoffset, lflagvalue);
							}
          
                        }
                        printf("\n");

                    preptr = (uint64_t)(proc1->p_list.le_prev);
                }
            }

            printf("end\n");
            free(proc0);
            free(proc1);
        }else{
            printf("kernel cache version mismatch\n");
        }
    }else{
        printf("failed to read kernel version string\n");
    }
	return 0;
}

debugserver附加目标app后手机重启了

 

2241717493971_.pic 2241717493971_.pic2322×1130 95.1 KB

 

在大佬的帮助下成功了

  • 每个版本的结构体有微小的差异.可以多看看别人的代码
    image image1220×196 13.5 KB

用抖音做个实验看看

绕过前

 

image image1998×320 26.3 KB

 

绕过后

 

image image2400×588 103 KB

标签:基于,struct,memstat,int,iOS,svc,process,proc,PL
From: https://www.cnblogs.com/macanpsc/p/18235759

相关文章

  • IOS网络模型
    IOS网络模型应用层: 内核缓冲区内封包(man3setsocketopt)表示层:会话层:传输层: TCP头+有效数据网络层: IP头+TCP头+有效数据数据链路层: MAC头+IP头+TCP头+有效数据物理层: 集中器,中继器ps:TCP支持紧急数据,可以使用send+标记MSG_OOB,可以忽略内核缓冲区的最小值限制......
  • 【忻州师范学院毕业论文】基于Java的家政公司网站的设计与实现
    注:仅展示部分文档内容和系统截图,需要完整的视频、代码、文章和安装调试环境请私信up主。1.1 开发背景及研究意义随着我国人口的增长、人们生活水平的提高,居民社会需求也随之增多,市场经济的快速发展和信息化水平的不断提高,人们的工作节奏也不断加快,许多人们没有闲暇的时间和......
  • 实战:干掉高德地图7.2.0版iOS客户端的反动态调试保护
    沙梓社snakeninny315年2月 高德是中国领先的数字地图内容、导航和位置服务解决方案提供商。苹果自带的地图采用的就是高德的数据,足见高德之权威 昨天突发奇想,对高德地图上中一个官方不提供的功能产生了浓厚的兴趣,试图通过hack的方式来实现这个功能。谁知刚架上LLDB......
  • 高速信号处理卡:523-基于 XCZU15EG的双 FMC通用信号处理板 高速信号处理
    (ZCU102E的pin兼容替代卡)基于XCZU15EG的双FMC通用信号处理板一、板卡概述   本板卡基于XilinxZynqUltrascale+MPSOC系列SOCXCZU15EG-FFVB1156架构,PS端搭载一组64-bitDDR4,容量32Gb,最高可稳定运行在2400MT/s,1路USB3.0接口、1路千兆网络接口、1路DP接口......
  • 基于web露营地场地预约管理系统系统设计与实现
     博主介绍:黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。所有项目都配有从入门到精通的基础知识视频课程,学习后应对毕业设计答辩。项目配有对应开发文档、开题报告、任务书、P......
  • 【毕业设计】基于SpringBoot星之语明星周边产品销售网站的设计与实现.zip
    1.项目概述随着信息互联网信息的飞速发展,无纸化作业变成了一种趋势,针对这个问题开发一个专门适应洗衣店业务新的交流形式的网站。本文介绍了星之语明星周边产品销售网站的开发全过程。通过分析企业对于星之语明星周边产品销售网站的需求,创建了一个计算机管理星之语明星周边产......
  • JAVA计算机毕业设计基于的儿童疫苗预约系统(附源码+springboot+开题+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着科技的进步和人们健康意识的增强,儿童疫苗接种已成为保障儿童健康成长的重要措施。然而,传统的疫苗预约方式往往存在诸多不便,如预约流程繁琐、信息......
  • JAVA计算机毕业设计基于的高校党务管理系统(附源码+springboot+开题+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着高校党建工作的不断深入和发展,党务管理面临着越来越多的挑战。传统的党务管理方式往往依赖于纸质记录和人工操作,效率低下且容易出错。为了提高党......
  • JAVA计算机毕业设计基于的畅游旅游网(附源码+springboot+开题+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在信息化和全球化的大背景下,旅游业作为现代服务业的重要组成部分,正在经历着前所未有的变革。畅游旅游网作为一个集旅游信息、服务、交易于一体的综合......
  • JAVA计算机毕业设计基于的仓库管理系统(附源码+springboot+开题+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着信息技术的迅猛发展和企业规模的不断扩大,仓库管理作为企业运营中不可或缺的一环,面临着日益复杂和多样化的挑战。传统的仓库管理模式依赖于人工操......