Beispiel #1
0
    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)
Beispiel #2
0
    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)
Beispiel #3
0
    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)
Beispiel #4
0
    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)
Beispiel #5
0
    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)
Beispiel #6
0
    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)