āĻšā§āĻ¯āĻžāĻ˛ā§, āĻšāĻžāĻŦāĻ°! āĻāĻ āĻāĻŽāĻŋ āĻāĻŋāĻāĻžāĻŦā§ macOS āĻ āĻāĻā§āĻ°āĻŽāĻŖāĻāĻžāĻ°ā§āĻĻā§āĻ° āĻāĻā§āĻ°āĻŽāĻŖ āĻĨā§āĻā§ āĻāĻĒāĻ¨āĻŋ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻā§āĻ˛āĻŋāĻā§ āĻ°āĻā§āĻˇāĻž āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ āĻ¸ā§ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻāĻĨāĻž āĻŦāĻ˛āĻ¤ā§ āĻāĻžāĻāĨ¤ āĻāĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§āĻĒ, āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻ ā§āĻ¯āĻžāĻ¨ā§āĻāĻŋāĻāĻžāĻāĻ°āĻžāĻ¸ āĻŦāĻž āĻŦā§āĻ¯āĻžāĻāĻāĻĒ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻĒāĻ¯ā§āĻā§, āĻŦāĻŋāĻļā§āĻˇ āĻāĻ°ā§ āĻ¯ā§āĻšā§āĻ¤ā§ macOS āĻāĻ° āĻ āĻ§ā§āĻ¨ā§ āĻāĻāĻāĻŋ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻā§ "āĻšāĻ¤ā§āĻ¯āĻž" āĻāĻ°āĻžāĻ° āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻāĻĒāĻžāĻ¯āĻŧ āĻ°āĻ¯āĻŧā§āĻā§āĨ¤ āĻāĻžāĻāĻž āĻ āĻ§ā§āĻ¨ā§ āĻāĻ āĻāĻŦāĻ āĻ¸ā§āĻ°āĻā§āĻˇāĻž āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻĒāĻĄāĻŧā§āĻ¨.
āĻāĻāĻāĻŋ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž "āĻšāĻ¤ā§āĻ¯āĻž" āĻāĻ°āĻžāĻ° āĻā§āĻ˛āĻžāĻ¸āĻŋāĻ āĻāĻĒāĻžāĻ¯āĻŧ
āĻāĻāĻāĻŋ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻā§ "āĻšāĻ¤ā§āĻ¯āĻž" āĻāĻ°āĻžāĻ° āĻāĻāĻāĻŋ āĻ¸ā§āĻĒāĻ°āĻŋāĻāĻŋāĻ¤ āĻāĻĒāĻžāĻ¯āĻŧ āĻšāĻ˛ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻŋāĻ¤ā§ āĻāĻāĻāĻŋ āĻ¸āĻŋāĻāĻāĻŋāĻ˛ āĻ¸āĻāĻā§āĻ¤ āĻĒāĻžāĻ āĻžāĻ¨ā§āĨ¤ āĻŦā§āĻ¯āĻžāĻļā§āĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻāĻĒāĻ¨āĻŋ āĻŽāĻžāĻ°āĻ¤ā§ āĻ¸ā§āĻā§āĻ¯āĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ "āĻāĻŋāĻ˛ -āĻ¸āĻŋāĻāĻāĻŋāĻ˛ āĻĒāĻŋāĻāĻāĻĄāĻŋ" āĻŦāĻž "āĻĒāĻŋāĻāĻŋāĻ˛ -9 āĻ¨āĻžāĻŽ" āĻāĻ˛ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨āĨ¤ "āĻāĻŋāĻ˛" āĻāĻŽāĻžāĻ¨ā§āĻĄāĻāĻŋ UNIX-āĻāĻ° āĻĻāĻŋāĻ¨ āĻĨā§āĻā§ āĻĒāĻ°āĻŋāĻāĻŋāĻ¤ āĻāĻŦāĻ āĻāĻāĻŋ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° macOS-āĻ āĻ¨āĻ¯āĻŧ, āĻ āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ UNIX-āĻāĻ° āĻŽāĻ¤ā§ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽā§āĻ āĻāĻĒāĻ˛āĻŦā§āĻ§āĨ¤
UNIX-āĻāĻ° āĻŽāĻ¤ā§ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽā§āĻ° āĻŽāĻ¤ā§, macOS āĻāĻĒāĻ¨āĻžāĻā§ āĻĻā§āĻāĻŋ āĻāĻžāĻĄāĻŧāĻž āĻāĻāĻāĻŋ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ° āĻ¯ā§āĻā§āĻ¨ā§ āĻ¸āĻāĻā§āĻ¤ āĻāĻāĻāĻžāĻ¤ā§ āĻĻā§āĻ¯āĻŧ - SIGKILL āĻāĻŦāĻ SIGSTOPāĨ¤ āĻāĻ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĻāĻŋ āĻĒā§āĻ°āĻžāĻĨāĻŽāĻŋāĻāĻāĻžāĻŦā§ āĻ¸āĻŋāĻāĻāĻŋāĻ˛ āĻ¸āĻāĻā§āĻ¤āĻā§ āĻāĻāĻāĻŋ āĻ¸āĻāĻā§āĻ¤ āĻšāĻŋāĻ¸āĻžāĻŦā§ āĻĢā§āĻāĻžāĻ¸ āĻāĻ°āĻŦā§ āĻ¯āĻž āĻāĻāĻāĻŋ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻā§ āĻšāĻ¤ā§āĻ¯āĻž āĻāĻ°ā§āĨ¤
macOS āĻ¸ā§āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ
macOS-āĻ, XNU āĻāĻžāĻ°ā§āĻ¨ā§āĻ˛ā§ āĻāĻŋāĻ˛ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽ āĻāĻ˛ psignal(SIGKILL,...) āĻĢāĻžāĻāĻļāĻ¨āĻā§ āĻāĻ˛ āĻāĻ°ā§āĨ¤ āĻāĻāĻāĻžāĻ°āĻ¸ā§āĻĒā§āĻ¸ā§ āĻ āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻāĻžāĻ°ā§āĻ° āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻā§āĻ˛āĻŋāĻā§ āĻ¸āĻŋāĻāĻ¨ā§āĻ¯āĻžāĻ˛ āĻĢāĻžāĻāĻļāĻ¨ āĻĻā§āĻŦāĻžāĻ°āĻž āĻŦāĻ˛āĻž āĻ¯ā§āĻ¤ā§ āĻĒāĻžāĻ°ā§ āĻ¤āĻž āĻĻā§āĻāĻžāĻ° āĻā§āĻˇā§āĻāĻž āĻāĻ°āĻž āĻ¯āĻžāĻāĨ¤ āĻāĻ¸ā§āĻ¨ āĻāĻžāĻ°ā§āĻ¨ā§āĻ˛ā§āĻ° āĻ āĻā§āĻ¯āĻ¨ā§āĻ¤āĻ°ā§āĻŖ āĻŽā§āĻāĻžāĻ¨āĻŋāĻāĻŽā§āĻ° āĻ¸āĻŋāĻāĻ¨ā§āĻ¯āĻžāĻ˛ āĻĢāĻžāĻāĻļāĻ¨ā§āĻ° āĻāĻ˛āĻā§āĻ˛āĻŋāĻā§ āĻŦāĻžāĻĻ āĻĻā§āĻ (āĻ¯āĻĻāĻŋāĻ āĻ¸ā§āĻā§āĻ˛āĻŋ āĻ -āĻ¤ā§āĻā§āĻ āĻšāĻ¤ā§ āĻĒāĻžāĻ°ā§, āĻāĻŽāĻ°āĻž āĻ¸ā§āĻā§āĻ˛āĻŋāĻā§ āĻ āĻ¨ā§āĻ¯ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻā§āĻĄāĻŧā§ āĻĻā§āĻŦ đ - āĻ¸ā§āĻŦāĻžāĻā§āĻˇāĻ° āĻ¯āĻžāĻāĻžāĻāĻāĻ°āĻŖ, āĻŽā§āĻŽāĻ°āĻŋ āĻ¤ā§āĻ°ā§āĻāĻŋ, āĻĒā§āĻ°āĻ¸ā§āĻĨāĻžāĻ¨/āĻŦāĻ¨ā§āĻ§ āĻšā§āĻ¯āĻžāĻ¨ā§āĻĄāĻ˛āĻŋāĻ, āĻĢāĻžāĻāĻ˛ āĻ¸ā§āĻ°āĻā§āĻˇāĻž āĻ˛āĻā§āĻāĻ¨ āĻāĻ¤ā§āĻ¯āĻžāĻĻāĻŋ .
āĻāĻ° āĻĢāĻžāĻāĻļāĻ¨ āĻāĻŦāĻ āĻ¸āĻāĻļā§āĻ˛āĻŋāĻˇā§āĻ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽ āĻāĻ˛ āĻĻāĻŋāĻ¯āĻŧā§ āĻĒāĻ°ā§āĻ¯āĻžāĻ˛ā§āĻāĻ¨āĻž āĻļā§āĻ°ā§ āĻāĻ°āĻž āĻ¯āĻžāĻ
static int
terminate_with_payload_internal(struct proc *cur_proc, int target_pid, uint32_t reason_namespace,
uint64_t reason_code, user_addr_t payload, uint32_t payload_size,
user_addr_t reason_string, uint64_t reason_flags)
{
...
target_proc = proc_find(target_pid);
...
if (!cansignal(cur_proc, cur_cred, target_proc, SIGKILL)) {
proc_rele(target_proc);
return EPERM;
}
...
if (target_pid == cur_proc->p_pid) {
/*
* psignal_thread_with_reason() will pend a SIGKILL on the specified thread or
* return if the thread and/or task are already terminating. Either way, the
* current thread won't return to userspace.
*/
psignal_thread_with_reason(target_proc, current_thread(), SIGKILL, signal_reason);
} else {
psignal_with_reason(target_proc, SIGKILL, signal_reason);
}
...
}
āĻāĻžāĻ˛ā§
āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽ āĻ¸ā§āĻāĻžāĻ°ā§āĻāĻāĻĒā§ āĻĄā§āĻŽāĻ¨ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻžāĻ° āĻāĻŦāĻ āĻ¤āĻžāĻĻā§āĻ° āĻā§āĻŦāĻ¨āĻāĻžāĻ˛ āĻ¨āĻŋāĻ¯āĻŧāĻ¨ā§āĻ¤ā§āĻ°āĻŖ āĻāĻ°āĻžāĻ° āĻāĻĻāĻ°ā§āĻļ āĻāĻĒāĻžāĻ¯āĻŧ āĻāĻžāĻ˛ā§ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§āĨ¤ āĻ āĻ¨ā§āĻā§āĻ°āĻš āĻāĻ°ā§ āĻŽāĻ¨ā§ āĻ°āĻžāĻāĻŦā§āĻ¨ āĻ¯ā§ āĻāĻ¤ā§āĻ¸āĻā§āĻ˛āĻŋ āĻŽā§āĻ¯āĻžāĻāĻāĻāĻ¸ 10.10 āĻĒāĻ°ā§āĻ¯āĻ¨ā§āĻ¤ āĻ˛āĻā§āĻāĻāĻŋāĻāĻ˛-āĻāĻ° āĻĒā§āĻ°āĻžāĻ¨ā§ āĻ¸āĻāĻ¸ā§āĻāĻ°āĻŖā§āĻ° āĻāĻ¨ā§āĻ¯, āĻā§āĻĄ āĻāĻĻāĻžāĻšāĻ°āĻŖāĻā§āĻ˛āĻŋ āĻāĻĻāĻžāĻšāĻ°āĻŖā§āĻ° āĻāĻĻā§āĻĻā§āĻļā§āĻ¯ā§ āĻĻā§āĻāĻ¯āĻŧāĻž āĻšāĻ¯āĻŧā§āĻā§āĨ¤ āĻāĻ§ā§āĻ¨āĻŋāĻ āĻ˛āĻā§āĻāĻāĻŋāĻāĻ˛ āĻāĻā§āĻ¸āĻĒāĻŋāĻ¸āĻŋāĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻ˛āĻā§āĻāĻĄ āĻ¸āĻāĻā§āĻ¤ āĻĒāĻžāĻ āĻžāĻ¯āĻŧ, āĻ˛āĻā§āĻāĻāĻŋāĻāĻ˛ āĻ˛āĻāĻŋāĻ āĻāĻāĻŋāĻ¤ā§ āĻ¸āĻ°āĻžāĻ¨ā§ āĻšāĻ¯āĻŧā§āĻā§āĨ¤
āĻāĻ˛ā§āĻ¨ āĻĻā§āĻā§ āĻ¨ā§āĻāĻ¯āĻŧāĻž āĻ¯āĻžāĻ āĻ āĻŋāĻ āĻāĻŋāĻāĻžāĻŦā§ āĻ ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨ āĻŦāĻ¨ā§āĻ§ āĻāĻ°āĻž āĻšāĻ¯āĻŧāĨ¤ SIGTERM āĻ¸āĻāĻā§āĻ¤ āĻĒāĻžāĻ āĻžāĻ¨ā§āĻ° āĻāĻā§, āĻ ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨āĻāĻŋāĻā§ "proc_terminate" āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽ āĻāĻ˛ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻŦāĻ¨ā§āĻ§ āĻāĻ°āĻžāĻ° āĻā§āĻˇā§āĻāĻž āĻāĻ°āĻž āĻšāĻ¯āĻŧāĨ¤
<launchctl src/core.c>
...
error = proc_terminate(j->p, &sig);
if (error) {
job_log(j, LOG_ERR | LOG_CONSOLE, "Could not terminate job: %d: %s", error, strerror(error));
job_log(j, LOG_NOTICE | LOG_CONSOLE, "Using fallback option to terminate job...");
error = kill2(j->p, SIGTERM);
if (error) {
job_log(j, LOG_ERR, "Could not signal job: %d: %s", error, strerror(error));
}
...
<>
āĻšā§āĻĄā§āĻ° āĻ¨āĻŋāĻā§, proc_terminate, āĻāĻ° āĻ¨āĻžāĻŽ āĻĨāĻžāĻāĻž āĻ¸āĻ¤ā§āĻ¤ā§āĻŦā§āĻ, SIGTERM āĻāĻ° āĻ¸āĻžāĻĨā§ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° psignal āĻĒāĻžāĻ āĻžāĻ¤ā§ āĻĒāĻžāĻ°ā§ āĻ¨āĻž, SIGKILLāĻ āĻĒāĻžāĻ āĻžāĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤
āĻĒāĻ°ā§āĻā§āĻˇ āĻšāĻ¤ā§āĻ¯āĻž - āĻ¸āĻŽā§āĻĒāĻĻ āĻ¸ā§āĻŽāĻž
āĻāĻāĻāĻŋ āĻāĻ°āĻ āĻāĻāĻ°ā§āĻˇāĻŖā§āĻ¯āĻŧ āĻā§āĻ¸ āĻ
āĻ¨ā§āĻ¯ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽ āĻāĻ˛ā§ āĻĻā§āĻāĻž āĻ¯āĻžāĻ¯āĻŧ
āĻ¯āĻĻāĻŋāĻ āĻāĻ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽ āĻāĻ˛āĻāĻŋ āĻ¸āĻŽā§āĻāĻžāĻŦā§āĻ¯āĻāĻžāĻŦā§ āĻāĻāĻāĻŋ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻā§ āĻŽā§āĻ°ā§ āĻĢā§āĻ˛āĻ¤ā§ āĻĒāĻžāĻ°ā§, āĻ¤āĻŦā§ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽāĻāĻŋ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽ āĻāĻ˛āĻāĻŋāĻā§ āĻāĻ˛ āĻāĻ°āĻžāĻ° āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻŋāĻ° āĻ
āĻ§āĻŋāĻāĻžāĻ°āĻā§āĻ˛āĻŋ āĻĒāĻ°ā§āĻ¯āĻžāĻĒā§āĻ¤āĻāĻžāĻŦā§ āĻĒāĻ°ā§āĻā§āĻˇāĻž āĻāĻ°ā§āĻ¨āĻŋāĨ¤ āĻāĻ¸āĻ˛ā§ āĻ¯āĻžāĻāĻžāĻ āĻāĻ°āĻž āĻšāĻā§āĻā§
āĻ āĻ¤āĻāĻŦ, āĻāĻĒāĻ¨āĻŋ āĻ¯āĻĻāĻŋ āĻ ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨āĻāĻŋāĻ° CPU āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°ā§āĻ° āĻā§āĻāĻž "āĻ¸ā§āĻŽāĻŋāĻ¤" āĻāĻ°ā§āĻ¨ (āĻāĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§āĻĒ, āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° 1 āĻāĻ¨āĻāĻ¸ āĻāĻžāĻ˛āĻžāĻ¨ā§āĻ° āĻ āĻ¨ā§āĻŽāĻ¤āĻŋ āĻĻā§āĻāĻ¯āĻŧāĻž āĻšāĻ¯āĻŧ), āĻ¤āĻžāĻšāĻ˛ā§ āĻāĻĒāĻ¨āĻŋ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽā§āĻ° āĻ¯ā§āĻā§āĻ¨ā§ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻā§ āĻŽā§āĻ°ā§ āĻĢā§āĻ˛āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨āĨ¤ āĻ¸ā§āĻ¤āĻ°āĻžāĻ, āĻŽā§āĻ¯āĻžāĻ˛āĻāĻ¯āĻŧā§āĻ¯āĻžāĻ° āĻ ā§āĻ¯āĻžāĻ¨ā§āĻāĻŋāĻāĻžāĻāĻ°āĻžāĻ¸ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻ¸āĻš āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽā§āĻ° āĻ¯ā§ āĻā§āĻ¨āĻ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻā§ āĻŽā§āĻ°ā§ āĻĢā§āĻ˛āĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤ āĻĒāĻŋāĻĄ 1 (āĻ˛āĻā§āĻāĻ¸āĻŋāĻāĻŋāĻāĻ˛) āĻĻāĻŋāĻ¯āĻŧā§ āĻāĻāĻāĻŋ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻā§ āĻšāĻ¤ā§āĻ¯āĻž āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻ¯ā§ āĻĒā§āĻ°āĻāĻžāĻŦāĻāĻŋ āĻāĻā§ āĻ¤āĻžāĻ āĻāĻāĻ°ā§āĻˇāĻŖā§āĻ¯āĻŧ - āĻ¸āĻŋāĻāĻāĻŋāĻ˛ āĻ¸āĻāĻā§āĻ¤ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻāĻ°āĻžāĻ° āĻā§āĻˇā§āĻāĻž āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻāĻžāĻ°ā§āĻ¨ā§āĻ˛ āĻĒā§āĻ¯āĻžāĻ¨āĻŋāĻ :)
āĻāĻŋāĻāĻžāĻŦā§ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨?
āĻāĻāĻāĻŋ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻā§ āĻšāĻ¤ā§āĻ¯āĻž āĻāĻ°āĻž āĻĨā§āĻā§ āĻ°āĻā§āĻˇāĻž āĻāĻ°āĻžāĻ° āĻ¸āĻŦāĻā§āĻ¯āĻŧā§ āĻ¸āĻšāĻ āĻāĻĒāĻžāĻ¯āĻŧ āĻšāĻ˛ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽ āĻāĻ˛ āĻā§āĻŦāĻŋāĻ˛ā§ āĻĢāĻžāĻāĻļāĻ¨ āĻĒāĻ¯āĻŧā§āĻ¨ā§āĻāĻžāĻ° āĻĒā§āĻ°āĻ¤āĻŋāĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻāĻ°āĻžāĨ¤ āĻĻā§āĻ°ā§āĻāĻžāĻā§āĻ¯āĻŦāĻļāĻ¤, āĻāĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻāĻŋ āĻ āĻ¨ā§āĻ āĻāĻžāĻ°āĻŖā§ āĻ āĻ¤ā§āĻā§āĻāĨ¤
āĻĒā§āĻ°āĻĨāĻŽāĻ¤, āĻ¯ā§ āĻāĻŋāĻšā§āĻ¨āĻāĻŋ sysent-āĻāĻ° āĻŽā§āĻŽāĻ°āĻŋ āĻ āĻŦāĻ¸ā§āĻĨāĻžāĻ¨ āĻ¨āĻŋāĻ¯āĻŧāĻ¨ā§āĻ¤ā§āĻ°āĻŖ āĻāĻ°ā§ āĻ¤āĻž āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° XNU āĻāĻžāĻ°ā§āĻ¨ā§āĻ˛ āĻāĻŋāĻšā§āĻ¨ā§āĻ° āĻŦā§āĻ¯āĻā§āĻ¤āĻŋāĻāĻ¤ āĻ¨āĻ¯āĻŧ, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻžāĻ°ā§āĻ¨ā§āĻ˛ āĻĒā§āĻ°āĻ¤ā§āĻāĻā§āĻ˛āĻŋāĻ¤ā§ āĻĒāĻžāĻāĻ¯āĻŧāĻž āĻ¯āĻžāĻŦā§ āĻ¨āĻžāĨ¤ āĻāĻĒāĻ¨āĻžāĻā§ āĻšāĻŋāĻāĻ°āĻŋāĻ¸ā§āĻāĻŋāĻ āĻ āĻ¨ā§āĻ¸āĻ¨ā§āĻ§āĻžāĻ¨ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻ¤ā§ āĻšāĻŦā§, āĻ¯ā§āĻŽāĻ¨ āĻĢāĻžāĻāĻļāĻ¨āĻāĻŋ āĻāĻ¤āĻŋāĻļā§āĻ˛āĻāĻžāĻŦā§ āĻŦāĻŋāĻā§āĻāĻŋāĻ¨ā§āĻ¨ āĻāĻ°āĻž āĻāĻŦāĻ āĻāĻ¤ā§ āĻāĻāĻāĻŋ āĻĒāĻ¯āĻŧā§āĻ¨ā§āĻāĻžāĻ° āĻ āĻ¨ā§āĻ¸āĻ¨ā§āĻ§āĻžāĻ¨ āĻāĻ°āĻžāĨ¤
āĻĻā§āĻŦāĻŋāĻ¤ā§āĻ¯āĻŧāĻ¤, āĻā§āĻŦāĻŋāĻ˛ā§āĻ° āĻāĻ¨ā§āĻā§āĻ°āĻŋāĻ° āĻāĻ āĻ¨ āĻ¨āĻŋāĻ°ā§āĻāĻ° āĻāĻ°ā§ āĻāĻžāĻ°ā§āĻ¨ā§āĻ˛āĻāĻŋ āĻ¯ā§ āĻĢā§āĻ˛ā§āĻ¯āĻžāĻā§āĻ° āĻ¸āĻžāĻĨā§ āĻāĻŽā§āĻĒāĻžāĻāĻ˛ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛ āĻ¤āĻžāĻ° āĻāĻĒāĻ°āĨ¤ āĻ¯āĻĻāĻŋ CONFIG_REQUIRES_U32_MUNGING āĻĒāĻ¤āĻžāĻāĻž āĻā§āĻˇāĻŖāĻž āĻāĻ°āĻž āĻšāĻ¯āĻŧ, āĻ¤āĻžāĻšāĻ˛ā§ āĻāĻžāĻ āĻžāĻŽā§āĻ° āĻāĻāĻžāĻ° āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ āĻāĻ°āĻž āĻšāĻŦā§ - āĻāĻāĻāĻŋ āĻ
āĻ¤āĻŋāĻ°āĻŋāĻā§āĻ¤ āĻā§āĻˇā§āĻ¤ā§āĻ° āĻ¯ā§āĻ āĻāĻ°āĻž āĻšāĻŦā§
struct sysent { /* system call table */
sy_call_t *sy_call; /* implementing function */
#if CONFIG_REQUIRES_U32_MUNGING || (__arm__ && (__BIGGEST_ALIGNMENT__ > 4))
sy_munge_t *sy_arg_munge32; /* system call arguments munger for 32-bit process */
#endif
int32_t sy_return_type; /* system call return types */
int16_t sy_narg; /* number of args */
uint16_t sy_arg_bytes; /* Total size of arguments in bytes for
* 32-bit system calls
*/
};
āĻ¸ā§āĻāĻžāĻā§āĻ¯āĻŦāĻļāĻ¤, macOS-āĻāĻ° āĻāĻ§ā§āĻ¨āĻŋāĻ āĻ¸āĻāĻ¸ā§āĻāĻ°āĻŖāĻā§āĻ˛āĻŋāĻ¤ā§, āĻ ā§āĻ¯āĻžāĻĒāĻ˛ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻā§āĻ˛āĻŋāĻ° āĻ¸āĻžāĻĨā§ āĻāĻžāĻ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻ¨āĻ¤ā§āĻ¨ API āĻĒā§āĻ°āĻĻāĻžāĻ¨ āĻāĻ°ā§āĨ¤ āĻāĻ¨ā§āĻĄāĻĒāĻ¯āĻŧā§āĻ¨ā§āĻ āĻ¸āĻŋāĻāĻŋāĻāĻ°āĻŋāĻāĻŋ āĻāĻĒāĻŋāĻāĻ āĻā§āĻ˛āĻžāĻ¯āĻŧā§āĻ¨ā§āĻāĻĻā§āĻ° āĻ āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻ āĻ¨ā§āĻ āĻ āĻ¨ā§āĻ°ā§āĻ§ āĻ āĻ¨ā§āĻŽā§āĻĻāĻ¨ āĻāĻ°āĻ¤ā§ āĻĻā§āĻ¯āĻŧāĨ¤ āĻāĻāĻāĻžāĻŦā§, āĻāĻĒāĻ¨āĻŋ āĻāĻĒāĻ°ā§ āĻāĻ˛ā§āĻ˛āĻŋāĻāĻŋāĻ¤ API āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ SIGKILL āĻ¸āĻāĻā§āĻ¤ āĻ¸āĻš āĻĒā§āĻ°āĻ¸ā§āĻ¸āĻā§āĻ˛āĻŋāĻ¤ā§ āĻ¯ā§āĻā§āĻ¨ āĻ¸āĻāĻā§āĻ¤ āĻŦā§āĻ˛āĻ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨āĨ¤
#include <bsm/libbsm.h>
#include <EndpointSecurity/EndpointSecurity.h>
#include <unistd.h>
int main(int argc, const char * argv[]) {
es_client_t* cli = nullptr;
{
auto res = es_new_client(&cli, ^(es_client_t * client, const es_message_t * message) {
switch (message->event_type) {
case ES_EVENT_TYPE_AUTH_SIGNAL:
{
auto& msg = message->event.signal;
auto target = msg.target;
auto& token = target->audit_token;
auto pid = audit_token_to_pid(token);
printf("signal '%d' sent to pid '%d'n", msg.sig, pid);
es_respond_auth_result(client, message, pid == getpid() ? ES_AUTH_RESULT_DENY : ES_AUTH_RESULT_ALLOW, false);
}
break;
default:
break;
}
});
}
{
es_event_type_t evs[] = { ES_EVENT_TYPE_AUTH_SIGNAL };
es_subscribe(cli, evs, sizeof(evs) / sizeof(*evs));
}
printf("%dn", getpid());
sleep(60); // could be replaced with other waiting primitive
es_unsubscribe_all(cli);
es_delete_client(cli);
return 0;
}
āĻāĻāĻāĻāĻžāĻŦā§, āĻāĻāĻāĻŋ MAC āĻ¨ā§āĻ¤āĻŋ āĻāĻžāĻ°ā§āĻ¨ā§āĻ˛ā§ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĻŋāĻ¤ āĻšāĻ¤ā§ āĻĒāĻžāĻ°ā§, āĻ¯āĻž āĻāĻāĻāĻŋ āĻ¸āĻāĻā§āĻ¤ āĻ¸ā§āĻ°āĻā§āĻˇāĻž āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻĒā§āĻ°āĻĻāĻžāĻ¨ āĻāĻ°ā§ (āĻ¨ā§āĻ¤āĻŋ proc_check_signal), āĻāĻŋāĻ¨ā§āĻ¤ā§ API āĻāĻ¨ā§āĻˇā§āĻ āĻžāĻ¨āĻŋāĻāĻāĻžāĻŦā§ āĻ¸āĻŽāĻ°ā§āĻĨāĻŋāĻ¤ āĻ¨āĻ¯āĻŧāĨ¤
āĻāĻžāĻ°ā§āĻ¨ā§āĻ˛ āĻāĻā§āĻ¸āĻā§āĻ¨āĻļāĻ¨ āĻ¸ā§āĻ°āĻā§āĻˇāĻž
āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽā§ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻā§āĻ˛āĻŋ āĻ°āĻā§āĻˇāĻž āĻāĻ°āĻžāĻ° āĻĒāĻžāĻļāĻžāĻĒāĻžāĻļāĻŋ, āĻāĻžāĻ°ā§āĻ¨ā§āĻ˛ āĻāĻā§āĻ¸āĻā§āĻ¨āĻļāĻ¨ āĻ¨āĻŋāĻā§āĻ (āĻā§āĻā§āĻ¸āĻ) āĻ°āĻā§āĻˇāĻž āĻāĻ°āĻžāĻ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧāĨ¤ macOS āĻĄā§āĻā§āĻ˛āĻĒāĻžāĻ°āĻĻā§āĻ° āĻ¸āĻšāĻā§ IOKit āĻĄāĻŋāĻāĻžāĻāĻ¸ āĻĄā§āĻ°āĻžāĻāĻāĻžāĻ° āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻāĻžāĻ āĻžāĻŽā§ āĻĒā§āĻ°āĻĻāĻžāĻ¨ āĻāĻ°ā§āĨ¤ āĻĄāĻŋāĻāĻžāĻāĻ¸āĻā§āĻ˛āĻŋāĻ° āĻ¸āĻžāĻĨā§ āĻāĻžāĻ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻ¸āĻ°āĻā§āĻāĻžāĻŽāĻā§āĻ˛āĻŋ āĻ¸āĻ°āĻŦāĻ°āĻžāĻš āĻāĻ°āĻžāĻ° āĻĒāĻžāĻļāĻžāĻĒāĻžāĻļāĻŋ, IOKit C++ āĻā§āĻ˛āĻžāĻ¸ā§āĻ° āĻāĻĻāĻžāĻšāĻ°āĻŖ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻĄā§āĻ°āĻžāĻāĻāĻžāĻ° āĻ¸ā§āĻā§āĻ¯āĻžāĻāĻŋāĻāĻ¯āĻŧā§āĻ° āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻ¸āĻ°āĻŦāĻ°āĻžāĻš āĻāĻ°ā§āĨ¤ āĻāĻāĻāĻžāĻ°āĻ¸ā§āĻĒā§āĻ¸ā§ āĻāĻāĻāĻŋ āĻ ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨ āĻāĻāĻāĻŋ āĻāĻžāĻ°ā§āĻ¨ā§āĻ˛-āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻāĻžāĻ°ā§ āĻ¸ā§āĻĨāĻžāĻ¨ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ āĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻāĻ°āĻ¤ā§ āĻā§āĻ˛āĻžāĻ¸ā§āĻ° āĻāĻāĻāĻŋ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĻŋāĻ¤ āĻāĻĻāĻžāĻšāĻ°āĻŖ "āĻā§āĻāĻā§" āĻĒā§āĻ¤ā§ āĻ¸āĻā§āĻˇāĻŽ āĻšāĻŦā§āĨ¤
āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽā§ āĻā§āĻ˛āĻžāĻ¸ āĻāĻ¨āĻ¸ā§āĻā§āĻ¯āĻžāĻ¨ā§āĻ¸ā§āĻ° āĻ¸āĻāĻā§āĻ¯āĻž āĻ¸āĻ¨āĻžāĻā§āĻ¤ āĻāĻ°āĻ¤ā§, ioclasscount āĻāĻāĻāĻŋāĻ˛āĻŋāĻāĻŋ āĻ°āĻ¯āĻŧā§āĻā§āĨ¤
my_kext_ioservice = 1
my_kext_iouserclient = 1
āĻ¯ā§ āĻā§āĻ¨ āĻāĻžāĻ°ā§āĻ¨ā§āĻ˛ āĻāĻā§āĻ¸āĻā§āĻ¨āĻļāĻ¨ āĻĄā§āĻ°āĻžāĻāĻāĻžāĻ° āĻ¸ā§āĻā§āĻ¯āĻžāĻā§āĻ° āĻ¸āĻžāĻĨā§ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĻ¨ āĻāĻ°āĻ¤ā§ āĻāĻžāĻ¯āĻŧ āĻ¤āĻžāĻā§ āĻ āĻŦāĻļā§āĻ¯āĻ āĻāĻŽāĻ¨ āĻāĻāĻāĻŋ āĻā§āĻ˛āĻžāĻ¸ āĻā§āĻˇāĻŖāĻž āĻāĻ°āĻ¤ā§ āĻšāĻŦā§ āĻ¯āĻž IOService āĻĨā§āĻā§ āĻāĻ¤ā§āĻ¤āĻ°āĻžāĻ§āĻŋāĻāĻžāĻ°āĻ¸ā§āĻ¤ā§āĻ°ā§ āĻĒāĻžāĻāĻ¯āĻŧāĻž āĻ¯āĻžāĻ¯āĻŧ, āĻāĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§āĻĒ my_kext_ioservice āĻāĻ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§ā§ˇ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻāĻžāĻ°ā§ āĻ ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨āĻā§āĻ˛āĻŋāĻā§ āĻ¸āĻāĻ¯ā§āĻā§āĻ¤ āĻāĻ°āĻžāĻ° āĻĢāĻ˛ā§ āĻā§āĻ˛āĻžāĻ¸ā§āĻ° āĻāĻāĻāĻŋ āĻ¨āĻ¤ā§āĻ¨ āĻĻā§āĻˇā§āĻāĻžāĻ¨ā§āĻ¤ āĻ¤ā§āĻ°āĻŋ āĻšāĻ¯āĻŧ āĻ¯āĻž IOUserClient āĻĨā§āĻā§ āĻāĻ¤ā§āĻ¤āĻ°āĻžāĻ§āĻŋāĻāĻžāĻ°āĻ¸ā§āĻ¤ā§āĻ°ā§ āĻĒāĻžāĻāĻ¯āĻŧāĻž āĻ¯āĻžāĻ¯āĻŧ, āĻāĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§āĻĒ my_kext_iouserclientā§ˇ
āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽ āĻĨā§āĻā§ āĻĄā§āĻ°āĻžāĻāĻāĻžāĻ° āĻāĻ¨āĻ˛ā§āĻĄ āĻāĻ°āĻžāĻ° āĻā§āĻˇā§āĻāĻž āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ (kextunload āĻāĻŽāĻžāĻ¨ā§āĻĄ), āĻāĻžāĻ°ā§āĻā§āĻ¯āĻŧāĻžāĻ˛ āĻĢāĻžāĻāĻļāĻ¨ "āĻŦā§āĻ˛ āĻāĻžāĻ°ā§āĻŽāĻŋāĻ¨ā§āĻ(IOOptionBits āĻŦāĻŋāĻāĻ˛ā§āĻĒ)" āĻŦāĻ˛āĻž āĻšāĻ¯āĻŧāĨ¤ āĻā§āĻā§āĻ¸āĻā§āĻ¨āĻ˛ā§āĻĄ āĻ āĻā§āĻˇāĻŽ āĻāĻ°āĻ¤ā§ āĻāĻ¨āĻ˛ā§āĻĄ āĻāĻ°āĻžāĻ° āĻā§āĻˇā§āĻāĻž āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻŦāĻ¨ā§āĻ§ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻ˛ā§ āĻŽāĻŋāĻĨā§āĻ¯āĻž āĻĢā§āĻ°āĻ¤ āĻĻā§āĻāĻ¯āĻŧāĻž āĻ¯āĻĨā§āĻˇā§āĻāĨ¤
bool Kext::terminate(IOOptionBits options)
{
if (!IsUnloadAllowed)
{
// Unload is not allowed, returning false
return false;
}
return super::terminate(options);
}
āĻ˛ā§āĻĄ āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ IOUserClient āĻĻā§āĻŦāĻžāĻ°āĻž IsUnloadAllowed āĻĒāĻ¤āĻžāĻāĻž āĻ¸ā§āĻ āĻāĻ°āĻž āĻ¯ā§āĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤ āĻ¯āĻāĻ¨ āĻāĻāĻāĻŋ āĻĄāĻžāĻāĻ¨āĻ˛ā§āĻĄ āĻ¸ā§āĻŽāĻž āĻĨāĻžāĻā§, āĻā§āĻā§āĻ¸āĻā§āĻ¨āĻ˛ā§āĻĄ āĻāĻŽāĻžāĻ¨ā§āĻĄ āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻāĻŋāĻ¤ āĻāĻāĻāĻĒā§āĻāĻāĻŋ āĻĢāĻŋāĻ°āĻŋāĻ¯āĻŧā§ āĻĻā§āĻŦā§:
admin@admins-Mac drivermanager % sudo kextunload ./test.kext
Password:
(kernel) Can't remove kext my.kext.test; services failed to terminate - 0xe00002c7.
Failed to unload my.kext.test - (iokit/common) unsupported function.
IOUserClient āĻāĻ° āĻāĻ¨ā§āĻ¯ āĻ āĻ¨ā§āĻ°ā§āĻĒ āĻ¸ā§āĻ°āĻā§āĻˇāĻž āĻāĻ°āĻž āĻāĻŦāĻļā§āĻ¯āĻāĨ¤ IOKitLib āĻāĻāĻāĻžāĻ°āĻ¸ā§āĻĒā§āĻ¸ āĻĢāĻžāĻāĻļāĻ¨ "IOCatalogueTerminate(mach_port_t, uint32_t āĻĒāĻ¤āĻžāĻāĻž, io_name_t āĻŦāĻŋāĻŦāĻ°āĻŖ);" āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻā§āĻ˛āĻžāĻ¸ā§āĻ° āĻāĻĻāĻžāĻšāĻ°āĻŖāĻā§āĻ˛āĻŋ āĻāĻ¨āĻ˛ā§āĻĄ āĻāĻ°āĻž āĻ¯ā§āĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤ āĻāĻĒāĻ¨āĻŋ "āĻāĻžāĻ°ā§āĻŽāĻŋāĻ¨ā§āĻ" āĻāĻŽāĻžāĻ¨ā§āĻĄā§ āĻāĻ˛ āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻŽāĻŋāĻĨā§āĻ¯āĻž āĻĢā§āĻ°āĻ¤ āĻĻāĻŋāĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ āĻ¯āĻ¤āĻā§āĻˇāĻŖ āĻ¨āĻž āĻāĻāĻāĻžāĻ°āĻ¸ā§āĻĒā§āĻ¸ āĻ ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨ "āĻĄāĻŋāĻ¸" āĻšāĻ¯āĻŧ, āĻ āĻ°ā§āĻĨāĻžā§ "āĻā§āĻ˛āĻžāĻ¯āĻŧā§āĻ¨ā§āĻāĻĄāĻŋāĻĄ" āĻĢāĻžāĻāĻļāĻ¨āĻāĻŋ āĻāĻ˛ āĻ¨āĻž āĻāĻ°āĻž āĻšāĻ¯āĻŧāĨ¤
āĻĢāĻžāĻāĻ˛ āĻ¸ā§āĻ°āĻā§āĻˇāĻž
āĻĢāĻžāĻāĻ˛āĻā§āĻ˛āĻŋ āĻ¸ā§āĻ°āĻā§āĻˇāĻŋāĻ¤ āĻāĻ°āĻ¤ā§, Kauth API āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻž āĻ¯āĻĨā§āĻˇā§āĻ, āĻ¯āĻž āĻāĻĒāĻ¨āĻžāĻā§ āĻĢāĻžāĻāĻ˛āĻā§āĻ˛āĻŋāĻ¤ā§ āĻ ā§āĻ¯āĻžāĻā§āĻ¸ā§āĻ¸ āĻ¸ā§āĻŽāĻžāĻŦāĻĻā§āĻ§ āĻāĻ°āĻ¤ā§ āĻĻā§āĻ¯āĻŧā§ˇ āĻ ā§āĻ¯āĻžāĻĒāĻ˛ āĻĄā§āĻā§āĻ˛āĻĒāĻžāĻ°āĻĻā§āĻ° āĻ¸ā§āĻ¯ā§āĻā§āĻ° āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻāĻā§āĻ¨ā§āĻ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻŦāĻŋāĻā§āĻāĻĒā§āĻ¤āĻŋ āĻĒā§āĻ°āĻĻāĻžāĻ¨ āĻāĻ°ā§; āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻ¨ā§āĻ¯, KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA āĻāĻŦāĻ KAUTH_VNODE_DELETE_CHILD āĻ āĻĒāĻžāĻ°ā§āĻļāĻ¨āĻā§āĻ˛āĻŋ āĻā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§āĻ°ā§āĻŖā§ˇ āĻĢāĻžāĻāĻ˛āĻā§āĻ˛āĻŋāĻ¤ā§ āĻ ā§āĻ¯āĻžāĻā§āĻ¸ā§āĻ¸ āĻ¸ā§āĻŽāĻžāĻŦāĻĻā§āĻ§ āĻāĻ°āĻžāĻ° āĻ¸āĻŦāĻā§āĻ¯āĻŧā§ āĻ¸āĻšāĻ āĻāĻĒāĻžāĻ¯āĻŧ āĻšāĻ˛ āĻĒāĻžāĻĨ - āĻāĻŽāĻ°āĻž āĻĢāĻžāĻāĻ˛ā§āĻ° āĻĒāĻžāĻĨ āĻĒā§āĻ¤ā§ āĻāĻŦāĻ āĻĒāĻžāĻĨ āĻĒā§āĻ°āĻŋāĻĢāĻŋāĻā§āĻ¸ā§āĻ° āĻ¤ā§āĻ˛āĻ¨āĻž āĻāĻ°āĻ¤ā§ "vn_getpath" API āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻŋāĨ¤ āĻŽāĻ¨ā§ āĻ°āĻžāĻāĻŦā§āĻ¨ āĻ¯ā§ āĻĢāĻžāĻāĻ˛ āĻĢā§āĻ˛ā§āĻĄāĻžāĻ° āĻĒāĻžāĻĨā§āĻ° āĻ°āĻŋāĻ¨āĻžāĻŽāĻŋāĻ āĻ āĻĒā§āĻāĻŋāĻŽāĻžāĻāĻ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯, āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽ āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻĢāĻžāĻāĻ˛ā§ āĻ ā§āĻ¯āĻžāĻā§āĻ¸ā§āĻ¸ āĻ āĻ¨ā§āĻŽā§āĻĻāĻ¨ āĻāĻ°ā§ āĻ¨āĻž, āĻ¤āĻŦā§ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻ¸ā§āĻ āĻĢā§āĻ˛ā§āĻĄāĻžāĻ°ā§ āĻ¯āĻž āĻĒā§āĻ¨āĻāĻ¨āĻžāĻŽāĻāĻ°āĻŖ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§āĨ¤ āĻŽā§āĻ˛ āĻĒāĻĨā§āĻ° āĻ¤ā§āĻ˛āĻ¨āĻž āĻāĻ°āĻž āĻāĻŦāĻ āĻāĻāĻŋāĻ° āĻāĻ¨ā§āĻ¯ KAUTH_VNODE_DELETE āĻ¸ā§āĻŽāĻžāĻŦāĻĻā§āĻ§ āĻāĻ°āĻž āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§ˇ
āĻāĻĒāĻ¸āĻ°ā§āĻā§āĻ° āĻ¸āĻāĻā§āĻ¯āĻž āĻŦā§āĻĻā§āĻ§āĻŋāĻ° āĻāĻžāĻ°āĻŖā§ āĻāĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ° āĻ
āĻ¸ā§āĻŦāĻŋāĻ§āĻž āĻāĻŽ āĻāĻ°ā§āĻŽāĻā§āĻˇāĻŽāĻ¤āĻž āĻšāĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤ āĻ¤ā§āĻ˛āĻ¨āĻžāĻāĻŋ O(āĻāĻĒāĻ¸āĻ°ā§āĻ*āĻĻā§āĻ°ā§āĻā§āĻ¯) āĻāĻ° āĻ¸āĻŽāĻžāĻ¨ āĻ¨āĻž āĻšāĻ¯āĻŧ āĻ¤āĻž āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤ āĻāĻ°āĻ¤ā§, āĻ¯ā§āĻāĻžāĻ¨ā§ āĻāĻĒāĻ¸āĻ°ā§āĻ āĻšāĻ˛ āĻāĻĒāĻ¸āĻ°ā§āĻā§āĻ° āĻ¸āĻāĻā§āĻ¯āĻž, āĻĻā§āĻ°ā§āĻā§āĻ¯ āĻšāĻ˛ āĻ¸ā§āĻā§āĻ°āĻŋāĻāĻāĻŋāĻ° āĻĻā§āĻ°ā§āĻā§āĻ¯, āĻāĻĒāĻ¨āĻŋ āĻāĻĒāĻ¸āĻ°ā§āĻ āĻĻā§āĻŦāĻžāĻ°āĻž āĻ¨āĻŋāĻ°ā§āĻŽāĻŋāĻ¤ āĻāĻāĻāĻŋ āĻ¨āĻŋāĻ°ā§āĻ§āĻžāĻ°āĻ āĻ¸āĻ¸ā§āĻŽ āĻ
āĻā§āĻŽā§āĻāĻ¨ (DFA) āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨āĨ¤
āĻĒā§āĻ°āĻĻāĻ¤ā§āĻ¤ āĻāĻĒāĻ¸āĻ°ā§āĻā§āĻ° āĻ¸ā§āĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ DFA āĻ¨āĻŋāĻ°ā§āĻŽāĻžāĻŖā§āĻ° āĻāĻāĻāĻŋ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻŦāĻŋāĻŦā§āĻāĻ¨āĻž āĻāĻ°āĻž āĻ¯āĻžāĻāĨ¤ āĻāĻŽāĻ°āĻž āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻāĻĒāĻ¸āĻ°ā§āĻā§āĻ° āĻļā§āĻ°ā§āĻ¤ā§ āĻāĻžāĻ°ā§āĻ¸āĻžāĻ°āĻā§āĻ˛āĻŋ āĻļā§āĻ°ā§ āĻāĻ°āĻŋāĨ¤ āĻ¯āĻĻāĻŋ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻāĻžāĻ°ā§āĻ¸āĻžāĻ° āĻāĻāĻ āĻ āĻā§āĻˇāĻ° āĻ¨āĻŋāĻ°ā§āĻĻā§āĻļ āĻāĻ°ā§, āĻ¤āĻžāĻšāĻ˛ā§ āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻāĻžāĻ°ā§āĻ¸āĻžāĻ°āĻā§ āĻāĻāĻāĻŋ āĻ āĻā§āĻˇāĻ° āĻĻā§āĻŦāĻžāĻ°āĻž āĻŦā§āĻĻā§āĻ§āĻŋ āĻāĻ°ā§āĻ¨ āĻāĻŦāĻ āĻŽāĻ¨ā§ āĻ°āĻžāĻāĻŦā§āĻ¨ āĻ¯ā§ āĻāĻāĻ āĻ˛āĻžāĻāĻ¨ā§āĻ° āĻĻā§āĻ°ā§āĻā§āĻ¯ āĻāĻ āĻĻā§āĻŦāĻžāĻ°āĻž āĻŦāĻĄāĻŧāĨ¤ āĻ¯āĻĻāĻŋ āĻāĻ˛āĻžāĻĻāĻž āĻāĻ˛āĻžāĻĻāĻž āĻāĻŋāĻšā§āĻ¨ āĻ¸āĻš āĻĻā§āĻāĻŋ āĻāĻžāĻ°ā§āĻ¸āĻžāĻ° āĻĨāĻžāĻā§, āĻ¤āĻžāĻšāĻ˛ā§ āĻāĻžāĻ°ā§āĻ¸āĻžāĻ°āĻā§āĻ˛āĻŋāĻā§ āĻ¤āĻžāĻ°āĻž āĻ¯ā§ āĻāĻŋāĻšā§āĻ¨ā§āĻ° āĻĻāĻŋāĻā§ āĻ¨āĻŋāĻ°ā§āĻĻā§āĻļ āĻāĻ°ā§ āĻ¸ā§āĻ āĻ āĻ¨ā§āĻ¸āĻžāĻ°ā§ āĻā§āĻ°ā§āĻĒā§ āĻāĻžāĻ āĻāĻ°ā§āĻ¨ āĻāĻŦāĻ āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻā§āĻ°ā§āĻĒā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ ā§āĻ¯āĻžāĻ˛āĻāĻ°āĻŋāĻĻāĻŽ āĻĒā§āĻ¨āĻ°āĻžāĻŦā§āĻ¤ā§āĻ¤āĻŋ āĻāĻ°ā§āĻ¨āĨ¤
āĻĒā§āĻ°āĻĨāĻŽ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§ (āĻāĻžāĻ°āĻ¸āĻžāĻ°ā§āĻ° āĻ āĻ§ā§āĻ¨ā§ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ āĻā§āĻˇāĻ° āĻāĻāĻ), āĻāĻŽāĻ°āĻž āĻāĻāĻāĻŋ DFA āĻ āĻŦāĻ¸ā§āĻĨāĻž āĻĒāĻžāĻ āĻ¯āĻžāĻ° āĻāĻāĻ āĻ˛āĻžāĻāĻ¨ āĻŦāĻ°āĻžāĻŦāĻ° āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻāĻāĻāĻŋ āĻ°ā§āĻĒāĻžāĻ¨ā§āĻ¤āĻ° āĻ°āĻ¯āĻŧā§āĻā§āĨ¤ āĻĻā§āĻŦāĻŋāĻ¤ā§āĻ¯āĻŧ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§, āĻāĻŽāĻ°āĻž āĻĢāĻžāĻāĻļāĻ¨āĻāĻŋāĻā§ āĻĒā§āĻ¨āĻ°āĻžāĻŦā§āĻ¤ā§āĻ¤āĻāĻžāĻŦā§ āĻāĻ˛ āĻāĻ°āĻžāĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻĒā§āĻ°āĻžāĻĒā§āĻ¤ āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§ āĻ¸ā§āĻā§āĻā§ 256 āĻāĻāĻžāĻ°ā§āĻ° (āĻ āĻā§āĻˇāĻ°ā§āĻ° āĻ¸āĻāĻā§āĻ¯āĻž āĻāĻŦāĻ āĻ¸āĻ°ā§āĻŦāĻžāĻ§āĻŋāĻ āĻ¸āĻāĻā§āĻ¯āĻ āĻā§āĻ°ā§āĻĒ) āĻ°ā§āĻĒāĻžāĻ¨ā§āĻ¤āĻ°ā§āĻ° āĻāĻāĻāĻŋ āĻā§āĻŦāĻŋāĻ˛ āĻĒāĻžāĻāĨ¤
āĻāĻ° āĻāĻāĻāĻŋ āĻāĻĻāĻžāĻšāĻ°āĻŖ āĻ¤āĻžāĻāĻžāĻ¨. āĻāĻĒāĻ¸āĻ°ā§āĻāĻā§āĻ˛āĻŋāĻ° āĻāĻāĻāĻŋ āĻ¸ā§āĻā§āĻ° āĻāĻ¨ā§āĻ¯ (â/foo/bar/tmp/â, â/var/db/foo/â, â/foo/bar/aba/â, âfoo/bar/aac/â) āĻāĻĒāĻ¨āĻŋ āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻāĻŋāĻ¤āĻā§āĻ˛āĻŋ āĻĒā§āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ āĻĄāĻŋāĻāĻĢāĻāĨ¤ āĻāĻŋāĻ¤ā§āĻ°āĻāĻŋ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻ āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻ°āĻžāĻā§āĻ¯ā§āĻ° āĻĻāĻŋāĻā§ āĻ¨āĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻāĻ¯āĻŧāĻž āĻ°ā§āĻĒāĻžāĻ¨ā§āĻ¤āĻ° āĻĻā§āĻāĻžāĻ¯āĻŧ; āĻ āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻ°ā§āĻĒāĻžāĻ¨ā§āĻ¤āĻ° āĻā§āĻĄāĻŧāĻžāĻ¨ā§āĻ¤ āĻšāĻŦā§ āĻ¨āĻžāĨ¤
DKA āĻ°āĻžāĻā§āĻ¯ā§āĻ° āĻŽāĻ§ā§āĻ¯ āĻĻāĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻāĻ¯āĻŧāĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ, 3āĻāĻŋ āĻŽāĻžāĻŽāĻ˛āĻž āĻšāĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤
- āĻā§āĻĄāĻŧāĻžāĻ¨ā§āĻ¤ āĻ āĻŦāĻ¸ā§āĻĨāĻžāĻ¯āĻŧ āĻĒā§āĻāĻā§ āĻā§āĻā§ - āĻĒāĻĨāĻāĻŋ āĻ¸ā§āĻ°āĻā§āĻˇāĻŋāĻ¤, āĻāĻŽāĻ°āĻž KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA āĻāĻŦāĻ KAUTH_VNODE_DELETE_CHILD āĻ āĻĒāĻžāĻ°ā§āĻļāĻ¨ āĻ¸ā§āĻŽāĻŋāĻ¤ āĻāĻ°āĻŋ
- āĻā§āĻĄāĻŧāĻžāĻ¨ā§āĻ¤ āĻ āĻŦāĻ¸ā§āĻĨāĻžāĻ¯āĻŧ āĻĒā§āĻāĻāĻžāĻ¨ā§ āĻ¯āĻžāĻ¯āĻŧāĻ¨āĻŋ, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻĒāĻĨ "āĻļā§āĻˇ" (āĻ¨āĻžāĻ˛ āĻāĻžāĻ°ā§āĻŽāĻŋāĻ¨ā§āĻāĻ° āĻĒā§āĻāĻā§āĻā§) - āĻĒāĻĨāĻāĻŋ āĻāĻāĻāĻŋ āĻ āĻāĻŋāĻāĻžāĻŦāĻ, āĻāĻāĻŋ KAUTH_VNODE_DELETE āĻ¸ā§āĻŽāĻžāĻŦāĻĻā§āĻ§ āĻāĻ°āĻž āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§ˇ āĻŽāĻ¨ā§ āĻ°āĻžāĻāĻŦā§āĻ¨ āĻ¯ā§ vnode āĻāĻāĻāĻŋ āĻĢā§āĻ˛ā§āĻĄāĻžāĻ° āĻšāĻ˛ā§, āĻāĻĒāĻ¨āĻžāĻā§ āĻļā§āĻˇā§ āĻāĻāĻāĻŋ '/' āĻ¯ā§āĻ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§, āĻ āĻ¨ā§āĻ¯āĻĨāĻžāĻ¯āĻŧ āĻāĻāĻŋ "/foor/bar/t" āĻĢāĻžāĻāĻ˛ā§ āĻ¸ā§āĻŽāĻžāĻŦāĻĻā§āĻ§ āĻšāĻ¤ā§ āĻĒāĻžāĻ°ā§, āĻ¯āĻž āĻā§āĻ˛āĨ¤
- āĻā§āĻĄāĻŧāĻžāĻ¨ā§āĻ¤ āĻ āĻŦāĻ¸ā§āĻĨāĻžāĻ¯āĻŧ āĻĒā§āĻāĻāĻžāĻ¯āĻŧāĻ¨āĻŋ, āĻĒāĻĨ āĻļā§āĻˇ āĻšāĻ¯āĻŧāĻ¨āĻŋāĨ¤ āĻāĻĒāĻ¸āĻ°ā§āĻāĻā§āĻ˛āĻŋāĻ° āĻāĻāĻāĻŋāĻ āĻāĻ° āĻ¸āĻžāĻĨā§ āĻŽā§āĻ˛ā§ āĻ¨āĻž, āĻāĻŽāĻ°āĻž āĻŦāĻŋāĻ§āĻŋāĻ¨āĻŋāĻˇā§āĻ§ āĻĒā§āĻ°āĻŦāĻ°ā§āĻ¤āĻ¨ āĻāĻ°āĻŋ āĻ¨āĻžāĨ¤
āĻāĻĒāĻ¸āĻāĻšāĻžāĻ°
āĻ¯ā§ āĻ¨āĻŋāĻ°āĻžāĻĒāĻ¤ā§āĻ¤āĻž āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨āĻā§āĻ˛āĻŋ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻž āĻšāĻā§āĻā§ āĻ¤āĻžāĻ° āĻ˛āĻā§āĻˇā§āĻ¯ āĻšāĻ˛ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻāĻžāĻ°ā§ āĻāĻŦāĻ āĻ¤āĻžāĻ° āĻĄā§āĻāĻžāĻ° āĻ¨āĻŋāĻ°āĻžāĻĒāĻ¤ā§āĻ¤āĻžāĻ° āĻ¸ā§āĻ¤āĻ° āĻŦāĻžāĻĄāĻŧāĻžāĻ¨ā§āĨ¤ āĻāĻāĻĻāĻŋāĻā§, āĻ ā§āĻ¯āĻžāĻā§āĻ°ā§āĻ¨āĻŋāĻ¸ āĻ¸āĻĢā§āĻāĻāĻ¯āĻŧā§āĻ¯āĻžāĻ° āĻĒāĻŖā§āĻ¯ā§āĻ° āĻŦāĻŋāĻāĻžāĻļā§āĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻāĻ āĻ˛āĻā§āĻˇā§āĻ¯āĻāĻŋ āĻ āĻ°ā§āĻāĻ¨ āĻāĻ°āĻž āĻšāĻ¯āĻŧ, āĻ¯āĻž āĻ¸ā§āĻ āĻĻā§āĻ°ā§āĻŦāĻ˛āĻ¤āĻžāĻā§āĻ˛āĻŋ āĻŦāĻ¨ā§āĻ§ āĻāĻ°ā§ āĻ¯ā§āĻāĻžāĻ¨ā§ āĻ āĻĒāĻžāĻ°ā§āĻāĻŋāĻ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽ āĻ¨āĻŋāĻā§āĻ "āĻĻā§āĻ°ā§āĻŦāĻ˛"āĨ¤ āĻ āĻ¨ā§āĻ¯āĻĻāĻŋāĻā§, OS āĻāĻ° āĻĻāĻŋāĻā§ āĻāĻ¨ā§āĻ¨āĻ¤ āĻāĻ°āĻž āĻ¯ā§āĻ¤ā§ āĻĒāĻžāĻ°ā§ āĻāĻŽāĻ¨ āĻ¨āĻŋāĻ°āĻžāĻĒāĻ¤ā§āĻ¤āĻžāĻ° āĻĻāĻŋāĻāĻā§āĻ˛āĻŋāĻā§ āĻļāĻā§āĻ¤āĻŋāĻļāĻžāĻ˛ā§ āĻāĻ°āĻžāĻ° āĻŦāĻŋāĻˇāĻ¯āĻŧā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻ āĻŦāĻšā§āĻ˛āĻž āĻāĻ°āĻž āĻāĻāĻŋāĻ¤ āĻ¨āĻ¯āĻŧ, āĻŦāĻŋāĻļā§āĻˇ āĻāĻ°ā§ āĻ¯ā§āĻšā§āĻ¤ā§ āĻāĻ āĻ§āĻ°āĻ¨ā§āĻ° āĻĻā§āĻ°ā§āĻŦāĻ˛āĻ¤āĻžāĻā§āĻ˛āĻŋ āĻŦāĻ¨ā§āĻ§ āĻāĻ°āĻž āĻĒāĻŖā§āĻ¯ āĻšāĻŋāĻ¸āĻžāĻŦā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻ¨āĻŋāĻāĻ¸ā§āĻŦ āĻ¸ā§āĻĨāĻžāĻ¯āĻŧāĻŋāĻ¤ā§āĻŦ āĻŦāĻžāĻĄāĻŧāĻžāĻ¯āĻŧāĨ¤ āĻĻā§āĻ°ā§āĻŦāĻ˛āĻ¤āĻž āĻ ā§āĻ¯āĻžāĻĒāĻ˛ āĻĒā§āĻ°ā§āĻĄāĻžāĻā§āĻ āĻ¸āĻŋāĻāĻŋāĻāĻ°āĻŋāĻāĻŋ āĻāĻŋāĻŽā§āĻ° āĻāĻžāĻā§ āĻ°āĻŋāĻĒā§āĻ°ā§āĻ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§ āĻāĻŦāĻ macOS 10.14.5 (https://support.apple.com/en-gb/HT210119) āĻ āĻ āĻŋāĻ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§āĨ¤
āĻāĻĒāĻ¨āĻžāĻ° āĻāĻāĻāĻŋāĻ˛āĻŋāĻāĻŋ āĻāĻ¨ā§āĻˇā§āĻ āĻžāĻ¨āĻŋāĻāĻāĻžāĻŦā§ āĻāĻžāĻ°ā§āĻ¨ā§āĻ˛ā§ āĻāĻ¨āĻ¸ā§āĻāĻ˛ āĻāĻ°āĻž āĻĨāĻžāĻāĻ˛ā§āĻ āĻāĻ āĻ¸āĻŦ āĻāĻ°āĻž āĻ¯ā§āĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤ āĻ
āĻ°ā§āĻĨāĻžā§, āĻŦāĻžāĻšā§āĻ¯āĻŋāĻ āĻāĻŦāĻ āĻ
āĻŦāĻžāĻā§āĻāĻŋāĻ¤ āĻ¸āĻĢā§āĻāĻāĻ¯āĻŧā§āĻ¯āĻžāĻ°āĻā§āĻ˛āĻŋāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻ āĻ§āĻ°āĻ¨ā§āĻ° āĻā§āĻ¨ āĻ¤ā§āĻ°ā§āĻāĻŋ āĻ¨ā§āĻāĨ¤ āĻ¯āĻžāĻāĻšā§āĻ, āĻāĻĒāĻ¨āĻŋ āĻĻā§āĻāĻ¤ā§ āĻĒāĻžāĻā§āĻā§āĻ¨, āĻāĻŽāĻ¨āĻāĻŋ āĻ
ā§āĻ¯āĻžāĻ¨ā§āĻāĻŋāĻāĻžāĻāĻ°āĻžāĻ¸ āĻāĻŦāĻ āĻŦā§āĻ¯āĻžāĻāĻāĻĒ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽā§āĻ° āĻŽāĻ¤ā§ āĻŦā§āĻ§ āĻĒā§āĻ°ā§āĻā§āĻ°āĻžāĻŽāĻā§āĻ˛āĻŋāĻā§ āĻ°āĻā§āĻˇāĻž āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯āĻ āĻāĻžāĻ āĻāĻ°āĻž āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨āĨ¤ āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻāĻ¨ macOS-āĻāĻ° āĻāĻ¨ā§āĻ¯ āĻ¨āĻ¤ā§āĻ¨ Acronis āĻĒāĻŖā§āĻ¯āĻā§āĻ˛āĻŋāĻ° āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽ āĻĨā§āĻā§ āĻāĻ¨āĻ˛ā§āĻĄ āĻāĻ°āĻžāĻ° āĻŦāĻŋāĻ°ā§āĻĻā§āĻ§ā§ āĻ
āĻ¤āĻŋāĻ°āĻŋāĻā§āĻ¤ āĻ¸ā§āĻ°āĻā§āĻˇāĻž āĻĨāĻžāĻāĻŦā§āĨ¤
āĻāĻ¤ā§āĻ¸: www.habr.com