def calculate(self): args = () common.set_plugin_members(self) sym_addrs = self.profile.get_all_addresses() nsysent = obj.Object("int", offset = self.addr_space.profile.get_symbol("_nsysent"), vm = self.addr_space) sysents = obj.Object(theType = "Array", offset = self.addr_space.profile.get_symbol("_sysent"), vm = self.addr_space, count = nsysent, targetType = "sysent") for (i, sysent) in enumerate(sysents): hooked = False ent_addr = sysent.sy_call.v() syscall_name = self.profile.get_symbol_by_address("kernel", ent_addr) if 'dtrace' in syscall_name: # syscall probes: http://siliconblade.blogspot.com/2013/04/hunting-d-trace-rootkits-with.html hooked = "syscall_probe" else: # fbt probes: http://reverse.put.as/2013/05/07/syscan13-revisiting-mac-os-x-rootkits-presentation/ data = sysent.obj_vm.zread(ent_addr + 1, 2) if binascii.hexlify(data) == 'f089': hooked = 'fbt_probe' if hooked != False: yield ('Syscall_Table', i, ent_addr, syscall_name, hooked) # mach_trap probes: http://felinemenace.org/~nemo/dtrace-infiltrate.pdf t = trap.mac_check_trap_table(self._config, args) for (table_addr, table_name, index, call_addr, sym_name, other_hooked) in t.calculate(): if other_hooked == True: sym_name = "HOOKED" if 'dtrace' in sym_name: hooked = "mach_trap_probe" yield ('Trap_Table', index, call_addr, sym_name, hooked)
def calculate(self): args = () common.set_plugin_members(self) sym_addrs = self.profile.get_all_addresses() nsysent = obj.Object( "int", offset=self.addr_space.profile.get_symbol("_nsysent"), vm=self.addr_space) sysents = obj.Object( theType="Array", offset=self.addr_space.profile.get_symbol("_sysent"), vm=self.addr_space, count=nsysent, targetType="sysent") for (i, sysent) in enumerate(sysents): hooked = False ent_addr = sysent.sy_call.v() syscall_name = self.profile.get_symbol_by_address( "kernel", ent_addr) if 'dtrace' in syscall_name: # syscall probes: http://siliconblade.blogspot.com/2013/04/hunting-d-trace-rootkits-with.html hooked = "syscall_probe" else: # fbt probes: http://reverse.put.as/2013/05/07/syscan13-revisiting-mac-os-x-rootkits-presentation/ data = sysent.obj_vm.zread(ent_addr + 1, 2) if binascii.hexlify(data) == 'f089': hooked = 'fbt_probe' if hooked != False: yield ('Syscall_Table', i, ent_addr, syscall_name, hooked) # mach_trap probes: http://felinemenace.org/~nemo/dtrace-infiltrate.pdf t = trap.mac_check_trap_table(self._config, args) for (table_addr, table_name, index, call_addr, sym_name, other_hooked) in t.calculate(): if other_hooked == True: sym_name = "HOOKED" if 'dtrace' in sym_name: hooked = "mach_trap_probe" yield ('Trap_Table', index, call_addr, sym_name, hooked)
def calculate(self): common.set_plugin_members(self) (kernel_symbol_addresses, kmod) = common.get_kernel_function_addrs(self) model = self.addr_space.profile.metadata.get('memory_model', 0) if model == '32bit': distorm_mode = distorm3.Decode32Bits else: distorm_mode = distorm3.Decode64Bits sym_addrs = self.profile.get_all_function_addresses() # get kernel start, end kp = self.addr_space.profile.get_symbol("_g_kernel_kmod_info") kmodk = obj.Object("kmod_info", offset = kp, vm = self.addr_space) k_start = kmodk.address k_end = k_start + kmodk.m('size') ####### STEP 1 - CHECK SYSTEM CALL INLINE HOOKS ############ # get syscall table nsysent = obj.Object("int", offset = self.addr_space.profile.get_symbol("_nsysent"), vm = self.addr_space) sysents = obj.Object(theType = "Array", offset = self.addr_space.profile.get_symbol("_sysent"), vm = self.addr_space, count = nsysent, targetType = "sysent") # check if syscall table entries have been modified dict_syscall_funcs = {} list_syscall_names = [] for (i, sysent) in enumerate(sysents): ent_addr = sysent.sy_call.v() hooked = ent_addr not in sym_addrs # using check_syscalls method inlined, dst_addr = self.isInlined(model, distorm_mode, ent_addr, kernel_symbol_addresses, [kmodk]) prolog_inlined = self.isPrologInlined(model, distorm_mode, ent_addr) if hooked == True or inlined == True or prolog_inlined == True: if dst_addr != None: kext = self.findKextWithAddress(dst_addr) else: kext = self.findKextWithAddress(ent_addr) yield ("SyscallTable1", i, ent_addr, hooked, (inlined or prolog_inlined), False, '-', kext) else: ent_name = self.profile.get_symbol_by_address_type("kernel", ent_addr, "N_FUN") # check for duplicate syscall functions if ent_name != "_nosys" and ent_name in dict_syscall_funcs: prev_ent = dict_syscall_funcs[ent_name] kext = self.findKextWithAddress(ent_addr) yield ("SyscallTable", list_syscall_names.index(ent_name), prev_ent.sy_call.v(), False, False, False, '-', kext) yield ("DuplicateSyscall -> {0}".format(ent_name), i, ent_addr, True, False, False, '-', kext) else: # check for dtrace syscall hooks if ent_name.find("dtrace") > -1: kext = self.findKextWithAddress(ent_addr) yield ("SyscallTable", i, ent_addr, False, False, False, '-', kext) else: # add to list list_syscall_names.append(ent_name) dict_syscall_funcs[ent_name] = sysent ####### STEP 2 - KERNEL & KEXTS ############### # get symbols from kext __TEXT in memory rather than file kext_addr_list = [] # get kernel address kmod = obj.Object("kmod_info", offset = self.addr_space.profile.get_symbol("_g_kernel_kmod_info"), vm = self.addr_space) kext_addr_list.append((kmod.address.v(), kmod.address + kmod.m('size'), '__kernel__')) # get other kext addresses p = self.addr_space.profile.get_symbol("_kmod") kmodaddr = obj.Object("Pointer", offset = p, vm = self.addr_space) kmod = kmodaddr.dereference_as("kmod_info") while kmod.is_valid(): kext_addr_list.append((kmod.address.v(), kmod.address + kmod.m('size'), kmod.name)) kmod = kmod.next # loop thru kexts for kext_address, kext_end, kext_name in kext_addr_list: #loop thru kext functions for func_name, func_addr in self.getKextSymbols(kext_addr = kext_address, onlyFunctions = True, fmodel = model): inlined = False # false positive, remove if needed if func_name in ["pthreads_dummy_symbol"]: continue # check if function's been modified modified, dst_addr = self.isCallReferenceModified(model, distorm_mode, func_addr, kernel_symbol_addresses, kext_addr_list) if modified: if dst_addr != None: hook_kext = self.findKextWithAddress(dst_addr) else: hook_kext = kext_name yield ("SymbolsTable", '-', func_addr, False, modified, False, '-', hook_kext) inlined, dst_addr = self.isInlined(model, distorm_mode, func_addr, kernel_symbol_addresses, kext_addr_list) if inlined: if dst_addr != None: hook_kext = self.findKextWithAddress(dst_addr) else: hook_kext = kext_name yield ("SymbolsTable", '-', func_addr, False, inlined, False, '-', hook_kext) ########## STEP 3 - TRAP TABLE ############### # check if trap table hooked using check_trap_table args = () trap = check_trap_table.mac_check_trap_table(self._config, args) for (table_addr, table_name, i, call_addr, sym_name, hooked) in trap.calculate(): if hooked == True or 'dtrace' in sym_name: kext = self.findKextWithAddress(call_addr) yield ("TrapTable", i, call_addr, hooked, False, False, '-', kext) else: inlined, dst_addr = self.isInlined(model, distorm_mode, call_addr, kernel_symbol_addresses, [kmodk]) if inlined: if dst_addr != None: hook_kext = self.findKextWithAddress(dst_addr) else: hook_kext = kext_name yield ("TrapTable", '-', func_addr, False, inlined, False, '-', hook_kext) else: modified, dst_addr = self.isCallReferenceModified(model, distorm_mode, call_addr, kernel_symbol_addresses, [kmodk]) if modified: if dst_addr != None: hook_kext = self.findKextWithAddress(dst_addr) else: hook_kext = kext_name yield ("TrapTable", '-', func_addr, False, modified, False, '-', hook_kext)
def calculate(self): common.set_plugin_members(self) (kernel_symbol_addresses, kmod) = common.get_kernel_function_addrs(self) model = self.addr_space.profile.metadata.get('memory_model', 0) if model == '32bit': distorm_mode = distorm3.Decode32Bits else: distorm_mode = distorm3.Decode64Bits sym_addrs = self.profile.get_all_function_addresses() # get kernel start, end kp = self.addr_space.profile.get_symbol("_g_kernel_kmod_info") kmodk = obj.Object("kmod_info", offset=kp, vm=self.addr_space) k_start = kmodk.address k_end = k_start + kmodk.m('size') ####### STEP 1 - CHECK SYSTEM CALL INLINE HOOKS ############ # get syscall table nsysent = obj.Object( "int", offset=self.addr_space.profile.get_symbol("_nsysent"), vm=self.addr_space) sysents = obj.Object( theType="Array", offset=self.addr_space.profile.get_symbol("_sysent"), vm=self.addr_space, count=nsysent, targetType="sysent") # check if syscall table entries have been modified dict_syscall_funcs = {} list_syscall_names = [] for (i, sysent) in enumerate(sysents): ent_addr = sysent.sy_call.v() hooked = ent_addr not in sym_addrs # using check_syscalls method inlined, dst_addr = self.isInlined(model, distorm_mode, ent_addr, kernel_symbol_addresses, [kmodk]) prolog_inlined = self.isPrologInlined(model, distorm_mode, ent_addr) if hooked == True or inlined == True or prolog_inlined == True: if dst_addr != None: kext = self.findKextWithAddress(dst_addr) else: kext = self.findKextWithAddress(ent_addr) yield ("SyscallTable1", i, ent_addr, hooked, (inlined or prolog_inlined), False, '-', kext) else: ent_name = self.profile.get_symbol_by_address_type( "kernel", ent_addr, "N_FUN") # check for duplicate syscall functions if ent_name != "_nosys" and ent_name in dict_syscall_funcs: prev_ent = dict_syscall_funcs[ent_name] kext = self.findKextWithAddress(ent_addr) yield ("SyscallTable", list_syscall_names.index(ent_name), prev_ent.sy_call.v(), False, False, False, '-', kext) yield ("DuplicateSyscall -> {0}".format(ent_name), i, ent_addr, True, False, False, '-', kext) else: # check for dtrace syscall hooks if ent_name.find("dtrace") > -1: kext = self.findKextWithAddress(ent_addr) yield ("SyscallTable", i, ent_addr, False, False, False, '-', kext) else: # add to list list_syscall_names.append(ent_name) dict_syscall_funcs[ent_name] = sysent ####### STEP 2 - KERNEL & KEXTS ############### # get symbols from kext __TEXT in memory rather than file kext_addr_list = [] # get kernel address kmod = obj.Object( "kmod_info", offset=self.addr_space.profile.get_symbol("_g_kernel_kmod_info"), vm=self.addr_space) kext_addr_list.append( (kmod.address.v(), kmod.address + kmod.m('size'), '__kernel__')) # get other kext addresses p = self.addr_space.profile.get_symbol("_kmod") kmodaddr = obj.Object("Pointer", offset=p, vm=self.addr_space) kmod = kmodaddr.dereference_as("kmod_info") while kmod.is_valid(): kext_addr_list.append( (kmod.address.v(), kmod.address + kmod.m('size'), kmod.name)) kmod = kmod.next # loop thru kexts for kext_address, kext_end, kext_name in kext_addr_list: #loop thru kext functions for func_name, func_addr in self.getKextSymbols( kext_addr=kext_address, onlyFunctions=True, fmodel=model): inlined = False # false positive, remove if needed if func_name in ["pthreads_dummy_symbol"]: continue # check if function's been modified modified, dst_addr = self.isCallReferenceModified( model, distorm_mode, func_addr, kernel_symbol_addresses, kext_addr_list) if modified: if dst_addr != None: hook_kext = self.findKextWithAddress(dst_addr) else: hook_kext = kext_name yield ("SymbolsTable", '-', func_addr, False, modified, False, '-', hook_kext) inlined, dst_addr = self.isInlined(model, distorm_mode, func_addr, kernel_symbol_addresses, kext_addr_list) if inlined: if dst_addr != None: hook_kext = self.findKextWithAddress(dst_addr) else: hook_kext = kext_name yield ("SymbolsTable", '-', func_addr, False, inlined, False, '-', hook_kext) ########## STEP 3 - TRAP TABLE ############### # check if trap table hooked using check_trap_table args = () trap = check_trap_table.mac_check_trap_table(self._config, args) for (table_addr, table_name, i, call_addr, sym_name, hooked) in trap.calculate(): if hooked == True or 'dtrace' in sym_name: kext = self.findKextWithAddress(call_addr) yield ("TrapTable", i, call_addr, hooked, False, False, '-', kext) else: inlined, dst_addr = self.isInlined(model, distorm_mode, call_addr, kernel_symbol_addresses, [kmodk]) if inlined: if dst_addr != None: hook_kext = self.findKextWithAddress(dst_addr) else: hook_kext = kext_name yield ("TrapTable", '-', func_addr, False, inlined, False, '-', hook_kext) else: modified, dst_addr = self.isCallReferenceModified( model, distorm_mode, call_addr, kernel_symbol_addresses, [kmodk]) if modified: if dst_addr != None: hook_kext = self.findKextWithAddress(dst_addr) else: hook_kext = kext_name yield ("TrapTable", '-', func_addr, False, modified, False, '-', hook_kext)
def calculate(self): common.set_plugin_members(self) model = self.addr_space.profile.metadata.get('memory_model', 0) if model == '32bit': distorm_mode = distorm3.Decode32Bits else: distorm_mode = distorm3.Decode64Bits sym_addrs = self.profile.get_all_addresses() # get all kexts and symbols if self._config.DISPLAYSYMBOLS != False: kext_addr_list = [] # get kernel address kmod = obj.Object("kmod_info", offset = self.addr_space.profile.get_symbol("_g_kernel_kmod_info"), vm = self.addr_space) kext_addr_list.append(('__kernel__', kmod.address, kmod.m('size'))) p = self.addr_space.profile.get_symbol("_kmod") kmodaddr = obj.Object("Pointer", offset = p, vm = self.addr_space) kmod = kmodaddr.dereference_as("kmod_info") while kmod.is_valid(): kext_addr_list.append((kmod.name, kmod.address, kmod.m('size'))) kmod = kmod.next # loop thru kexts for kext_name, kext_address, kext_size in kext_addr_list: if self._config.DISPLAYSYMBOLS in "{0}".format(kext_name): k_start = kext_address k_end = kext_address + kext_size #loop thru kext functions for func_name, func_addr in self.getKextSymbols(kext_addr = kext_address, onlyFunctions = True, fmodel = model): print "{0} {1} {2:#10x}".format(kext_name, func_name, func_addr) yield ('-', 0, False, False, False, False, '-', '-') return # get kernel start, end kp = self.addr_space.profile.get_symbol("_g_kernel_kmod_info") kmodk = obj.Object("kmod_info", offset = kp, vm = self.addr_space) k_start = kmodk.address k_end = k_start + kmodk.m('size') # get syscall table nsysent = obj.Object("int", offset = self.addr_space.profile.get_symbol("_nsysent"), vm = self.addr_space) sysents = obj.Object(theType = "Array", offset = self.addr_space.profile.get_symbol("_sysent"), vm = self.addr_space, count = nsysent, targetType = "sysent") # check if syscall table is shadowed, if so use shadow address (syscall_shadowed, shadow_addr) = self.isSyscallShadowed(model, distorm_mode, sysents.obj_offset) if syscall_shadowed: # use shadow table address to check hooking sysents = obj.Object(theType = "Array", offset = shadow_addr, vm = self.addr_space, count = nsysent, targetType = "sysent") # check if shadow syscall functions have been modified for (i, sysent) in enumerate(sysents): ent_addr = sysent.sy_call.v() inlined, dst_addr = self.isInlined(model, distorm_mode, ent_addr, k_start, k_end) hooked = ent_addr not in sym_addrs # using check_syscalls method prolog_inlined = self.isPrologInlined(model, distorm_mode, ent_addr) if hooked == True or inlined == True or prolog_inlined == True: if dst_addr != None: kext = self.findKextWithAddress(dst_addr) else: kext = self.findKextWithAddress(ent_addr) yield ("ShadowSyscallTable", i, ent_addr, hooked, inlined, syscall_shadowed, '-', kext) else: # check if syscall table entries have been modified dict_syscall_funcs = {} list_syscall_names = [] for (i, sysent) in enumerate(sysents): ent_addr = sysent.sy_call.v() hooked = ent_addr not in sym_addrs # using check_syscalls method inlined, dst_addr = self.isInlined(model, distorm_mode, ent_addr, k_start, k_end) prolog_inlined = self.isPrologInlined(model, distorm_mode, ent_addr) if hooked == True or inlined == True or prolog_inlined == True: if dst_addr != None: kext = self.findKextWithAddress(dst_addr) else: kext = self.findKextWithAddress(ent_addr) yield ("SyscallTable", i, ent_addr, hooked, (inlined or prolog_inlined), False, '-', kext) else: ent_name = self.profile.get_symbol_by_address("kernel", ent_addr) # check for duplicate syscall functions if ent_name != "_nosys" and ent_name in dict_syscall_funcs: prev_ent = dict_syscall_funcs[ent_name] kext = self.findKextWithAddress(ent_addr) yield ("SyscallTable", list_syscall_names.index(ent_name), prev_ent.sy_call.v(), False, False, False, '-', kext) yield ("DuplicateSyscall -> {0}".format(ent_name), i, ent_addr, True, False, False, '-', kext) else: # check for dtrace syscall hooks if ent_name.find("dtrace") > -1: kext = self.findKextWithAddress(ent_addr) yield ("SyscallTable", i, ent_addr, False, False, False, '-', kext) else: # add to list list_syscall_names.append(ent_name) dict_syscall_funcs[ent_name] = sysent # check if kext functions are inlined, including kernel symbols if self._config.CHECKKEXTS or self._config.CHECKKERNEL: # get symbols from kext __TEXT in memory rather than file kext_addr_list = [] # get kernel address kmod = obj.Object("kmod_info", offset = self.addr_space.profile.get_symbol("_g_kernel_kmod_info"), vm = self.addr_space) kext_addr_list.append(('__kernel__', kmod.address, kmod.m('size'))) # get all kexts if self._config.CHECKKERNEL == False: # get other kext addresses p = self.addr_space.profile.get_symbol("_kmod") kmodaddr = obj.Object("Pointer", offset = p, vm = self.addr_space) kmod = kmodaddr.dereference_as("kmod_info") while kmod.is_valid(): kext_addr_list.append((kmod.name, kmod.address, kmod.m('size'))) kmod = kmod.next # loop thru kexts for kext_name, kext_address, kext_size in kext_addr_list: k_start = kext_address k_end = kext_address + kext_size #loop thru kext functions for func_name, func_addr in self.getKextSymbols(kext_addr = kext_address, onlyFunctions = True, fmodel = model): inlined = False # false positive, remove if needed if func_name in ["pthreads_dummy_symbol"]: continue # check if function's been modified modified, dst_addr = self.isCallReferenceModified(model, distorm_mode, func_addr, k_start, k_end) if modified: if dst_addr != None: hook_kext = self.findKextWithAddress(dst_addr) else: hook_kext = kext_name yield ("SymbolsTable", '-', func_addr, False, modified, False, '-', hook_kext) inlined, dst_addr = self.isInlined(model, distorm_mode, func_addr, k_start, k_end) #prolog_inlined = self.isPrologInlined(model, distorm_mode, func_addr) if inlined: if dst_addr != None: hook_kext = self.findKextWithAddress(dst_addr) else: hook_kext = kext_name yield ("SymbolsTable", '-', func_addr, False, (inlined or prolog_inlined), False, '-', hook_kext) # check if trap table hooked using check_trap_table args = () trap = check_trap_table.mac_check_trap_table(self._config, args) for (table_addr, table_name, i, call_addr, sym_name, hooked) in trap.calculate(): if hooked == True or 'dtrace' in sym_name: kext = self.findKextWithAddress(call_addr) yield ("TrapTable", i, call_addr, hooked, False, False, '-', kext)
def calculate(self): common.set_plugin_members(self) model = self.addr_space.profile.metadata.get('memory_model', 0) if model == '32bit': distorm_mode = distorm3.Decode32Bits else: distorm_mode = distorm3.Decode64Bits sym_addrs = self.profile.get_all_addresses() # get all kexts and symbols if self._config.DISPLAYSYMBOLS != False: kext_addr_list = [] # get kernel address kmod = obj.Object("kmod_info", offset=self.addr_space.profile.get_symbol( "_g_kernel_kmod_info"), vm=self.addr_space) kext_addr_list.append(('__kernel__', kmod.address, kmod.m('size'))) p = self.addr_space.profile.get_symbol("_kmod") kmodaddr = obj.Object("Pointer", offset=p, vm=self.addr_space) kmod = kmodaddr.dereference_as("kmod_info") while kmod.is_valid(): kext_addr_list.append( (kmod.name, kmod.address, kmod.m('size'))) kmod = kmod.next # loop thru kexts for kext_name, kext_address, kext_size in kext_addr_list: if self._config.DISPLAYSYMBOLS in "{0}".format(kext_name): k_start = kext_address k_end = kext_address + kext_size #loop thru kext functions for func_name, func_addr in self.getKextSymbols( kext_addr=kext_address, onlyFunctions=True, fmodel=model): print "{0} {1} {2:#10x}".format( kext_name, func_name, func_addr) yield ('-', 0, False, False, False, False, '-', '-') return # get kernel start, end kp = self.addr_space.profile.get_symbol("_g_kernel_kmod_info") kmodk = obj.Object("kmod_info", offset=kp, vm=self.addr_space) k_start = kmodk.address k_end = k_start + kmodk.m('size') # get syscall table nsysent = obj.Object( "int", offset=self.addr_space.profile.get_symbol("_nsysent"), vm=self.addr_space) sysents = obj.Object( theType="Array", offset=self.addr_space.profile.get_symbol("_sysent"), vm=self.addr_space, count=nsysent, targetType="sysent") # check if syscall table is shadowed, if so use shadow address (syscall_shadowed, shadow_addr) = self.isSyscallShadowed(model, distorm_mode, sysents.obj_offset) if syscall_shadowed: # use shadow table address to check hooking sysents = obj.Object(theType="Array", offset=shadow_addr, vm=self.addr_space, count=nsysent, targetType="sysent") # check if shadow syscall functions have been modified for (i, sysent) in enumerate(sysents): ent_addr = sysent.sy_call.v() inlined, dst_addr = self.isInlined(model, distorm_mode, ent_addr, k_start, k_end) hooked = ent_addr not in sym_addrs # using check_syscalls method prolog_inlined = self.isPrologInlined(model, distorm_mode, ent_addr) if hooked == True or inlined == True or prolog_inlined == True: if dst_addr != None: kext = self.findKextWithAddress(dst_addr) else: kext = self.findKextWithAddress(ent_addr) yield ("ShadowSyscallTable", i, ent_addr, hooked, inlined, syscall_shadowed, '-', kext) else: # check if syscall table entries have been modified dict_syscall_funcs = {} list_syscall_names = [] for (i, sysent) in enumerate(sysents): ent_addr = sysent.sy_call.v() hooked = ent_addr not in sym_addrs # using check_syscalls method inlined, dst_addr = self.isInlined(model, distorm_mode, ent_addr, k_start, k_end) prolog_inlined = self.isPrologInlined(model, distorm_mode, ent_addr) if hooked == True or inlined == True or prolog_inlined == True: if dst_addr != None: kext = self.findKextWithAddress(dst_addr) else: kext = self.findKextWithAddress(ent_addr) yield ("SyscallTable", i, ent_addr, hooked, (inlined or prolog_inlined), False, '-', kext) else: ent_name = self.profile.get_symbol_by_address( "kernel", ent_addr) # check for duplicate syscall functions if ent_name != "_nosys" and ent_name in dict_syscall_funcs: prev_ent = dict_syscall_funcs[ent_name] kext = self.findKextWithAddress(ent_addr) yield ("SyscallTable", list_syscall_names.index(ent_name), prev_ent.sy_call.v(), False, False, False, '-', kext) yield ("DuplicateSyscall -> {0}".format(ent_name), i, ent_addr, True, False, False, '-', kext) else: # check for dtrace syscall hooks if ent_name.find("dtrace") > -1: kext = self.findKextWithAddress(ent_addr) yield ("SyscallTable", i, ent_addr, False, False, False, '-', kext) else: # add to list list_syscall_names.append(ent_name) dict_syscall_funcs[ent_name] = sysent # check if kext functions are inlined, including kernel symbols if self._config.CHECKKEXTS or self._config.CHECKKERNEL: # get symbols from kext __TEXT in memory rather than file kext_addr_list = [] # get kernel address kmod = obj.Object("kmod_info", offset=self.addr_space.profile.get_symbol( "_g_kernel_kmod_info"), vm=self.addr_space) kext_addr_list.append(('__kernel__', kmod.address, kmod.m('size'))) # get all kexts if self._config.CHECKKERNEL == False: # get other kext addresses p = self.addr_space.profile.get_symbol("_kmod") kmodaddr = obj.Object("Pointer", offset=p, vm=self.addr_space) kmod = kmodaddr.dereference_as("kmod_info") while kmod.is_valid(): kext_addr_list.append( (kmod.name, kmod.address, kmod.m('size'))) kmod = kmod.next # loop thru kexts for kext_name, kext_address, kext_size in kext_addr_list: k_start = kext_address k_end = kext_address + kext_size #loop thru kext functions for func_name, func_addr in self.getKextSymbols( kext_addr=kext_address, onlyFunctions=True, fmodel=model): inlined = False # false positive, remove if needed if func_name in ["pthreads_dummy_symbol"]: continue # check if function's been modified modified, dst_addr = self.isCallReferenceModified( model, distorm_mode, func_addr, k_start, k_end) if modified: if dst_addr != None: hook_kext = self.findKextWithAddress(dst_addr) else: hook_kext = kext_name yield ("SymbolsTable", '-', func_addr, False, modified, False, '-', hook_kext) inlined, dst_addr = self.isInlined(model, distorm_mode, func_addr, k_start, k_end) #prolog_inlined = self.isPrologInlined(model, distorm_mode, func_addr) if inlined: if dst_addr != None: hook_kext = self.findKextWithAddress(dst_addr) else: hook_kext = kext_name yield ("SymbolsTable", '-', func_addr, False, (inlined or prolog_inlined), False, '-', hook_kext) # check if trap table hooked using check_trap_table args = () trap = check_trap_table.mac_check_trap_table(self._config, args) for (table_addr, table_name, i, call_addr, sym_name, hooked) in trap.calculate(): if hooked == True or 'dtrace' in sym_name: kext = self.findKextWithAddress(call_addr) yield ("TrapTable", i, call_addr, hooked, False, False, '-', kext)