Example #1
0
bool ksmach_i_VMStats(vm_statistics_data_t* const vmStats,
                      vm_size_t* const pageSize)
{
    kern_return_t kr;
    const mach_port_t hostPort = mach_host_self();

    if((kr = host_page_size(hostPort, pageSize)) != KERN_SUCCESS)
    {
        KSLOG_ERROR("host_page_size: %s", mach_error_string(kr));
        return false;
    }

    mach_msg_type_number_t hostSize = sizeof(*vmStats) / sizeof(natural_t);
    kr = host_statistics(hostPort,
                         HOST_VM_INFO,
                         (host_info_t)vmStats,
                         &hostSize);
    if(kr != KERN_SUCCESS)
    {
        KSLOG_ERROR("host_statistics: %s", mach_error_string(kr));
        return false;
    }
    
    return true;
}
Example #2
0
int64_t kscrs_addUserReport(const char* report, int reportLength)
{
    pthread_mutex_lock(&g_mutex);
    int64_t currentID = g_nextUniqueID++;
    char crashReportPath[KSCRS_MAX_PATH_LENGTH];
    getCrashReportPathByID(currentID, crashReportPath);

    int fd = open(crashReportPath, O_WRONLY | O_CREAT, 0644);
    if(fd < 0)
    {
        KSLOG_ERROR("Could not open file %s: %s", crashReportPath, strerror(errno));
        goto done;
    }

    int bytesWritten = (int)write(fd, report, (unsigned)reportLength);
    if(bytesWritten < 0)
    {
        KSLOG_ERROR("Could not write to file %s: %s", crashReportPath, strerror(errno));
        goto done;
    }
    else if(bytesWritten < reportLength)
    {
        KSLOG_ERROR("Expected to write %lull bytes to file %s, but only wrote %ll", crashReportPath, reportLength, bytesWritten);
    }

done:
    if(fd >= 0)
    {
        close(fd);
    }
    pthread_mutex_unlock(&g_mutex);

    return currentID;
}
Example #3
0
bool ksfu_makePath(const char* absolutePath)
{
    bool isSuccessful = false;
    char* pathCopy = strdup(absolutePath);
    for(char* ptr = pathCopy+1; *ptr != '\0';ptr++)
    {
        if(*ptr == '/')
        {
            *ptr = '\0';
            if(mkdir(pathCopy, S_IRWXU) < 0 && errno != EEXIST)
            {
                KSLOG_ERROR("Could not create directory %s: %s", pathCopy, strerror(errno));
                goto done;
            }
            *ptr = '/';
        }
    }
    if(mkdir(pathCopy, S_IRWXU) < 0 && errno != EEXIST)
    {
        KSLOG_ERROR("Could not create directory %s: %s", pathCopy, strerror(errno));
        goto done;
    }
    isSuccessful = true;

done:
    free(pathCopy);
    return isSuccessful;
}
Example #4
0
static inline bool getThreadList(KSMachineContext* context)
{
    const task_t thisTask = mach_task_self();
    KSLOG_DEBUG("Getting thread list");
    kern_return_t kr;
    thread_act_array_t threads;
    mach_msg_type_number_t actualThreadCount;

    if((kr = task_threads(thisTask, &threads, &actualThreadCount)) != KERN_SUCCESS)
    {
        KSLOG_ERROR("task_threads: %s", mach_error_string(kr));
        return false;
    }
    KSLOG_TRACE("Got %d threads", context->threadCount);
    int threadCount = (int)actualThreadCount;
    int maxThreadCount = sizeof(context->allThreads) / sizeof(context->allThreads[0]);
    if(threadCount > maxThreadCount)
    {
        KSLOG_ERROR("Thread count %d is higher than maximum of %d", threadCount, maxThreadCount);
        threadCount = maxThreadCount;
    }
    for(int i = 0; i < threadCount; i++)
    {
        context->allThreads[i] = threads[i];
    }
    context->threadCount = threadCount;

    for(mach_msg_type_number_t i = 0; i < actualThreadCount; i++)
    {
        mach_port_deallocate(thisTask, context->allThreads[i]);
    }
    vm_deallocate(thisTask, (vm_address_t)threads, sizeof(thread_t) * actualThreadCount);

    return true;
}
Example #5
0
bool kssysctl_getMacAddress(const char* const name,
                            char* const macAddressBuffer)
{
    // Based off http://iphonedevelopertips.com/device/determine-mac-address.html

    int mib[6] =
    {
        CTL_NET,
        AF_ROUTE,
        0,
        AF_LINK,
        NET_RT_IFLIST,
        (int)if_nametoindex(name)
    };
    if(mib[5] == 0)
    {
        KSLOG_ERROR("Could not get interface index for %s: %s",
                    name, strerror(errno));
        return false;
    }

    size_t length;
    if(sysctl(mib, 6, NULL, &length, NULL, 0) != 0)
    {
        KSLOG_ERROR("Could not get interface data for %s: %s",
                    name, strerror(errno));
        return false;
    }

    void* ifBuffer = malloc(length);
    if(ifBuffer == NULL)
    {
        KSLOG_ERROR("Out of memory");
        return false;
    }

    if(sysctl(mib, 6, ifBuffer, &length, NULL, 0) != 0)
    {
        KSLOG_ERROR("Could not get interface data for %s: %s",
                    name, strerror(errno));
        free(ifBuffer);
        return false;
    }

    struct if_msghdr* msgHdr = (struct if_msghdr*) ifBuffer;
    struct sockaddr_dl* sockaddr = (struct sockaddr_dl*) &msgHdr[1];
    memcpy(macAddressBuffer, LLADDR(sockaddr), 6);

    free(ifBuffer);

    return true;
}
/** Load the persistent state portion of a crash context.
 *
 * @param path The path to the file to read.
 *
 * @return true if the operation was successful.
 */
static bool loadState(const char* const path)
{
    // Stop if the file doesn't exist.
    // This is expected on the first run of the app.
    const int fd = open(path, O_RDONLY);
    if(fd < 0)
    {
        return false;
    }
    close(fd);

    char* data;
    int length;
    if(!ksfu_readEntireFile(path, &data, &length, 50000))
    {
        KSLOG_ERROR("%s: Could not load file", path);
        return false;
    }

    KSJSONDecodeCallbacks callbacks;
    callbacks.onBeginArray = onBeginArray;
    callbacks.onBeginObject = onBeginObject;
    callbacks.onBooleanElement = onBooleanElement;
    callbacks.onEndContainer = onEndContainer;
    callbacks.onEndData = onEndData;
    callbacks.onFloatingPointElement = onFloatingPointElement;
    callbacks.onIntegerElement = onIntegerElement;
    callbacks.onNullElement = onNullElement;
    callbacks.onStringElement = onStringElement;

    int errorOffset = 0;

    char stringBuffer[1000];
    const int result = ksjson_decode(data,
                                     (int)length,
                                     stringBuffer,
                                     sizeof(stringBuffer),
                                     &callbacks,
                                     &g_state,
                                     &errorOffset);
    free(data);
    if(result != KSJSON_OK)
    {
        KSLOG_ERROR("%s, offset %d: %s",
                    path, errorOffset, ksjson_stringForError(result));
        return false;
    }
    return true;
}
Example #7
0
static bool deletePathContents(const char* path, bool deleteTopLevelPathAlso)
{
    struct stat statStruct = {0};
    if(stat(path, &statStruct) != 0)
    {
        KSLOG_ERROR("Could not stat %s: %s", path, strerror(errno));
        return false;
    }
    if(S_ISDIR(statStruct.st_mode))
    {
        char** entries = NULL;
        int entryCount = 0;
        dirContents(path, &entries, &entryCount);

        int bufferLength = KSFU_MAX_PATH_LENGTH;
        char* pathBuffer = malloc((unsigned)bufferLength);
        snprintf(pathBuffer, bufferLength, "%s/", path);
        char* pathPtr = pathBuffer + strlen(pathBuffer);
        int pathRemainingLength = bufferLength - (int)(pathPtr - pathBuffer);

        for(int i = 0; i < entryCount; i++)
        {
            char* entry = entries[i];
            if(entry != NULL && canDeletePath(entry))
            {
                strncpy(pathPtr, entry, pathRemainingLength);
                deletePathContents(pathBuffer, true);
            }
        }

        free(pathBuffer);
        freeDirListing(entries, entryCount);
        if(deleteTopLevelPathAlso)
        {
            ksfu_removeFile(path, false);
        }
    }
    else if(S_ISREG(statStruct.st_mode))
    {
        ksfu_removeFile(path, false);
    }
    else
    {
        KSLOG_ERROR("Could not delete %s: Not a regular file.", path);
        return false;
    }
    return true;
}
Example #8
0
static int getReportCount()
{
    int count = 0;
    DIR* dir = opendir(g_reportsPath);
    if(dir == NULL)
    {
        KSLOG_ERROR("Could not open directory %s", g_reportsPath);
        goto done;
    }
    struct dirent* ent;
    while((ent = readdir(dir)) != NULL)
    {
        if(getReportIDFromFilename(ent->d_name) > 0)
        {
            count++;
        }
    }

done:
    if(dir != NULL)
    {
        closedir(dir);
    }
    return count;
}
Example #9
0
static int getReportIDs(int64_t* reportIDs, int count)
{
    int index = 0;
    DIR* dir = opendir(g_reportsPath);
    if(dir == NULL)
    {
        KSLOG_ERROR("Could not open directory %s", g_reportsPath);
        goto done;
    }

    struct dirent* ent;
    while((ent = readdir(dir)) != NULL && index < count)
    {
        int64_t reportID = getReportIDFromFilename(ent->d_name);
        if(reportID > 0)
        {
            reportIDs[index++] = reportID;
        }
    }

    qsort(reportIDs, (unsigned)count, sizeof(reportIDs[0]), compareInt64);

done:
    if(dir != NULL)
    {
        closedir(dir);
    }
    return index;
}
Example #10
0
void kscrash_setDoNotIntrospectClasses(const char** doNotIntrospectClasses, size_t length)
{
    const char** oldClasses = crashContext()->config.introspectionRules.restrictedClasses;
    size_t oldClassesLength = crashContext()->config.introspectionRules.restrictedClassesCount;
    const char** newClasses = nil;
    size_t newClassesLength = 0;
    
    if(doNotIntrospectClasses != nil && length > 0)
    {
        newClassesLength = length;
        newClasses = malloc(sizeof(*newClasses) * newClassesLength);
        if(newClasses == nil)
        {
            KSLOG_ERROR("Could not allocate memory");
            return;
        }
        
        for(size_t i = 0; i < newClassesLength; i++)
        {
            newClasses[i] = strdup(doNotIntrospectClasses[i]);
        }
    }

    crashContext()->config.introspectionRules.restrictedClasses = newClasses;
    crashContext()->config.introspectionRules.restrictedClassesCount = newClassesLength;

    if(oldClasses != nil)
    {
        for(size_t i = 0; i < oldClassesLength; i++)
        {
            free((void*)oldClasses[i]);
        }
        free(oldClasses);
    }
}
/** Restore the original mach exception ports.
 */
void ksmachexc_i_restoreExceptionPorts(void)
{
    KSLOG_DEBUG("Restoring original exception ports.");
    if(g_previousExceptionPorts.count == 0)
    {
        KSLOG_DEBUG("Original exception ports were already restored.");
        return;
    }

    const task_t thisTask = mach_task_self();
    kern_return_t kr;

    // Reinstall old exception ports.
    for(mach_msg_type_number_t i = 0; i < g_previousExceptionPorts.count; i++)
    {
        KSLOG_TRACE("Restoring port index %d", i);
        kr = task_set_exception_ports(thisTask,
                                      g_previousExceptionPorts.masks[i],
                                      g_previousExceptionPorts.ports[i],
                                      g_previousExceptionPorts.behaviors[i],
                                      g_previousExceptionPorts.flavors[i]);
        if(kr != KERN_SUCCESS)
        {
            KSLOG_ERROR("task_set_exception_ports: %s",
                        mach_error_string(kr));
        }
    }
    KSLOG_DEBUG("Exception ports restored.");
    g_previousExceptionPorts.count = 0;
}
Example #12
0
void ksmach_init(void)
{
    static volatile sig_atomic_t initialized = 0;
    if(!initialized)
    {
        kern_return_t kr;
        const task_t thisTask = mach_task_self();
        thread_act_array_t threads;
        mach_msg_type_number_t numThreads;

        if((kr = task_threads(thisTask, &threads, &numThreads)) != KERN_SUCCESS)
        {
            KSLOG_ERROR("task_threads: %s", mach_error_string(kr));
            return;
        }

        g_topThread = pthread_from_mach_thread_np(threads[0]);

        for(mach_msg_type_number_t i = 0; i < numThreads; i++)
        {
            mach_port_deallocate(thisTask, threads[i]);
        }
        vm_deallocate(thisTask, (vm_address_t)threads, sizeof(thread_t) * numThreads);
        initialized = true;
    }
}
Example #13
0
const char* kscpu_exceptionRegisterName(const int regNumber)
{
    if(regNumber < kscpu_numExceptionRegisters())
    {
        return g_exceptionRegisterNames[regNumber];
    }
    KSLOG_ERROR("Invalid register number: %d", regNumber);
    return NULL;
}
Example #14
0
bool ksfu_readEntireFile(const char* const path,
                         char** data,
                         size_t* length)
{
    struct stat st;
    if(stat(path, &st) < 0)
    {
        KSLOG_ERROR("Could not stat %s: %s", path, strerror(errno));
        return false;
    }

    void* mem = NULL;
    int fd = open(path, O_RDONLY);
    if(fd < 0)
    {
        KSLOG_ERROR("Could not open %s: %s", path, strerror(errno));
        return false;
    }

    mem = malloc((size_t)st.st_size);
    if(mem == NULL)
    {
        KSLOG_ERROR("Out of memory");
        goto failed;
    }

    if(!ksfu_readBytesFromFD(fd, mem, (ssize_t)st.st_size))
    {
        goto failed;
    }

    close(fd);
    *length = (size_t)st.st_size;
    *data = mem;
    return true;

failed:
    close(fd);
    if(mem != NULL)
    {
        free(mem);
    }
    return false;
}
void kscrashsentry_reportUserException(const char* name,
                                       const char* reason,
                                       const char* language,
                                       const char* lineOfCode,
                                       const char* stackTrace,
                                       bool terminateProgram)
{
    if(g_context == NULL)
    {
        KSLOG_WARN("User-reported exception sentry is not installed. Exception has not been recorded.");
    }
    else
    {
        kscrashsentry_beginHandlingCrash(g_context);

        KSLOG_DEBUG("Suspending all threads");
        kscrashsentry_suspendThreads();

        KSLOG_DEBUG("Fetching call stack.");
        int callstackCount = 100;
        uintptr_t callstack[callstackCount];
        callstackCount = backtrace((void**)callstack, callstackCount);
        if(callstackCount <= 0)
        {
            KSLOG_ERROR("backtrace() returned call stack length of %d", callstackCount);
            callstackCount = 0;
        }

        KSLOG_DEBUG("Filling out context.");
        g_context->crashType = KSCrashTypeUserReported;
        g_context->offendingThread = ksmach_thread_self();
        g_context->registersAreValid = false;
        g_context->crashReason = reason;
        g_context->stackTrace = callstack;
        g_context->stackTraceLength = callstackCount;
        g_context->userException.name = name;
        g_context->userException.language = language;
        g_context->userException.lineOfCode = lineOfCode;
        g_context->userException.customStackTrace = stackTrace;

        KSLOG_DEBUG("Calling main crash handler.");
        g_context->onCrash();

        if(terminateProgram)
        {
            kscrashsentry_uninstall(KSCrashTypeAll);
            kscrashsentry_resumeThreads();
            abort();
        }
        else
        {
            kscrashsentry_clearContext(g_context);
            kscrashsentry_resumeThreads();
        }
    }
}
Example #16
0
void ksmc_addReservedThread(KSThread thread)
{
    int nextIndex = g_reservedThreadsCount;
    if(nextIndex > g_reservedThreadsMaxIndex)
    {
        KSLOG_ERROR("Too many reserved threads (%d). Max is %d", nextIndex, g_reservedThreadsMaxIndex);
        return;
    }
    g_reservedThreads[g_reservedThreadsCount++] = thread;
}
Example #17
0
static void dirContents(const char* path, char*** entries, int* count)
{
    DIR* dir = NULL;
    char** entryList = NULL;
    int entryCount = dirContentsCount(path);
    if(entryCount <= 0)
    {
        goto done;
    }
    dir = opendir(path);
    if(dir == NULL)
    {
        KSLOG_ERROR("Error reading directory %s: %s", path, strerror(errno));
        goto done;
    }

    entryList = calloc((unsigned)entryCount, sizeof(char*));
    struct dirent* ent;
    int index = 0;
    while((ent = readdir(dir)))
    {
        if(index >= entryCount)
        {
            KSLOG_ERROR("Contents of %s have been mutated", path);
            goto done;
        }
        entryList[index] = strdup(ent->d_name);
        index++;
    }

done:
    if(dir != NULL)
    {
        closedir(dir);
    }
    if(entryList == NULL)
    {
        entryCount = 0;
    }
    *entries = entryList;
    *count = entryCount;
}
Example #18
0
bool ksfu_removeFile(const char* path, bool mustExist)
{
    if(remove(path) < 0)
    {
        if(mustExist || errno != ENOENT)
        {
            KSLOG_ERROR("Could not delete %s: %s", path, strerror(errno));
        }
        return false;
    }
    return true;
}
Example #19
0
bool ksfu_openBufferedWriter(KSBufferedWriter* writer, const char* const path, char* writeBuffer, int writeBufferLength)
{
    writer->buffer = writeBuffer;
    writer->bufferLength = writeBufferLength;
    writer->position = 0;
    writer->fd = open(path, O_RDWR | O_CREAT | O_EXCL, 0644);
    if(writer->fd < 0)
    {
        KSLOG_ERROR("Could not open crash report file %s: %s", path, strerror(errno));
        return false;
    }
    return true;
}
Example #20
0
struct timeval kssysctl_timevalForName(const char* const name)
{
    struct timeval value = {0};
    size_t size = sizeof(value);

    if(0 != sysctlbyname(name, &value, &size, NULL, 0))
    {
        KSLOG_ERROR("Could not get timeval value for %s: %s",
                    name, strerror(errno));
    }

    return value;
}
Example #21
0
uint64_t kscpu_registerValue(const KSMachineContext* const context, const int regNumber)
{
    switch(regNumber)
    {
        case 0:
            return context->machineContext.__ss.__rax;
        case 1:
            return context->machineContext.__ss.__rbx;
        case 2:
            return context->machineContext.__ss.__rcx;
        case 3:
            return context->machineContext.__ss.__rdx;
        case 4:
            return context->machineContext.__ss.__rdi;
        case 5:
            return context->machineContext.__ss.__rsi;
        case 6:
            return context->machineContext.__ss.__rbp;
        case 7:
            return context->machineContext.__ss.__rsp;
        case 8:
            return context->machineContext.__ss.__r8;
        case 9:
            return context->machineContext.__ss.__r9;
        case 10:
            return context->machineContext.__ss.__r10;
        case 11:
            return context->machineContext.__ss.__r11;
        case 12:
            return context->machineContext.__ss.__r12;
        case 13:
            return context->machineContext.__ss.__r13;
        case 14:
            return context->machineContext.__ss.__r14;
        case 15:
            return context->machineContext.__ss.__r15;
        case 16:
            return context->machineContext.__ss.__rip;
        case 17:
            return context->machineContext.__ss.__rflags;
        case 18:
            return context->machineContext.__ss.__cs;
        case 19:
            return context->machineContext.__ss.__fs;
        case 20:
            return context->machineContext.__ss.__gs;
    }

    KSLOG_ERROR("Invalid register number: %d", regNumber);
    return 0;
}
Example #22
0
void ksmc_resumeEnvironment()
{
#if KSCRASH_HAS_THREADS_API
    KSLOG_DEBUG("Resuming environment.");
    kern_return_t kr;
    const task_t thisTask = mach_task_self();
    const thread_t thisThread = (thread_t)ksthread_self();
    thread_act_array_t threads;
    mach_msg_type_number_t numThreads;
    
    if((kr = task_threads(thisTask, &threads, &numThreads)) != KERN_SUCCESS)
    {
        KSLOG_ERROR("task_threads: %s", mach_error_string(kr));
        return;
    }
    
    for(mach_msg_type_number_t i = 0; i < numThreads; i++)
    {
        thread_t thread = threads[i];
        if(thread != thisThread && !isThreadInList(thread, g_reservedThreads, g_reservedThreadsCount))
        {
            if((kr = thread_resume(thread)) != KERN_SUCCESS)
            {
                // Record the error and keep going.
                KSLOG_ERROR("thread_resume (%08x): %s", thread, mach_error_string(kr));
            }
        }
    }
    
    for(mach_msg_type_number_t i = 0; i < numThreads; i++)
    {
        mach_port_deallocate(thisTask, threads[i]);
    }
    vm_deallocate(thisTask, (vm_address_t)threads, sizeof(thread_t) * numThreads);

    KSLOG_DEBUG("Resume complete.");
#endif
}
Example #23
0
bool kssysctl_getProcessInfo(const int pid,
                             struct kinfo_proc* const procInfo)
{
    int cmd[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
    size_t size = sizeof(*procInfo);

    if(0 != sysctl(cmd, sizeof(cmd)/sizeof(*cmd), procInfo, &size, NULL, 0))
    {
        KSLOG_ERROR("Could not get the name for process %d: %s",
                    pid, strerror(errno));
        return false;
    }
    return true;
}
Example #24
0
struct timeval kssysctl_timeval(const int major_cmd, const int minor_cmd)
{
    int cmd[2] = {major_cmd, minor_cmd};
    struct timeval value = {0};
    size_t size = sizeof(value);

    if(0 != sysctl(cmd, sizeof(cmd)/sizeof(*cmd), &value, &size, NULL, 0))
    {
        KSLOG_ERROR("Could not get timeval value for %d,%d: %s",
                    major_cmd, minor_cmd, strerror(errno));
    }

    return value;
}
Example #25
0
/** Check if the current process is being traced or not.
 *
 * @return true if we're being traced.
 */
bool ksmach_isBeingTraced(void)
{
    struct kinfo_proc procInfo;
    size_t structSize = sizeof(procInfo);
    int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()};

    if(sysctl(mib, sizeof(mib)/sizeof(*mib), &procInfo, &structSize, NULL, 0) != 0)
    {
        KSLOG_ERROR("sysctl: %s", strerror(errno));
        return false;
    }

    return (procInfo.kp_proc.p_flag & P_TRACED) != 0;
}
Example #26
0
uint64_t kscpu_exceptionRegisterValue(const KSMachineContext* const context, const int regNumber)
{
    switch(regNumber)
    {
        case 0:
            return context->machineContext.__es.__trapno;
        case 1:
            return context->machineContext.__es.__err;
        case 2:
            return context->machineContext.__es.__faultvaddr;
    }

    KSLOG_ERROR("Invalid register number: %d", regNumber);
    return 0;
}
Example #27
0
bool ksmach_resumeAllThreadsExcept(thread_t* exceptThreads, int exceptThreadsCount)
{
    kern_return_t kr;
    const task_t thisTask = mach_task_self();
    const thread_t thisThread = ksmach_thread_self();
    thread_act_array_t threads;
    mach_msg_type_number_t numThreads;

    if((kr = task_threads(thisTask, &threads, &numThreads)) != KERN_SUCCESS)
    {
        KSLOG_ERROR("task_threads: %s", mach_error_string(kr));
        return false;
    }

    for(mach_msg_type_number_t i = 0; i < numThreads; i++)
    {
        thread_t thread = threads[i];
        if(thread != thisThread && !isThreadInList(thread, exceptThreads, exceptThreadsCount))
        {
            if((kr = thread_resume(thread)) != KERN_SUCCESS)
            {
                KSLOG_ERROR("thread_resume (%08x): %s",
                            thread, mach_error_string(kr));
                // Don't treat this as a fatal error.
            }
        }
    }

    for(mach_msg_type_number_t i = 0; i < numThreads; i++)
    {
        mach_port_deallocate(thisTask, threads[i]);
    }
    vm_deallocate(thisTask, (vm_address_t)threads, sizeof(thread_t) * numThreads);

    return true;
}
Example #28
0
bool ksfu_readBytesFromFD(const int fd, char* const bytes, int length)
{
    char* pos = bytes;
    while(length > 0)
    {
        int bytesRead = (int)read(fd, pos, (unsigned)length);
        if(bytesRead == -1)
        {
            KSLOG_ERROR("Could not write to fd %d: %s", fd, strerror(errno));
            return false;
        }
        length -= bytesRead;
        pos += bytesRead;
    }
    return true;
}
Example #29
0
uint64_t ksmach_exceptionRegisterValue(const STRUCT_MCONTEXT_L* const machineContext,
                                       const int regNumber)
{
    switch(regNumber)
    {
        case 0:
            return machineContext->__es.__exception;
        case 1:
            return machineContext->__es.__esr;
        case 2:
            return machineContext->__es.__far;
    }

    KSLOG_ERROR("Invalid register number: %d", regNumber);
    return 0;
}
Example #30
0
bool ksmach_fillState(const thread_t thread,
                      const thread_state_t state,
                      const thread_state_flavor_t flavor,
                      const mach_msg_type_number_t stateCount)
{
    mach_msg_type_number_t stateCountBuff = stateCount;
    kern_return_t kr;

    kr = thread_get_state(thread, flavor, state, &stateCountBuff);
    if(kr != KERN_SUCCESS)
    {
        KSLOG_ERROR("thread_get_state: %s", mach_error_string(kr));
        return false;
    }
    return true;
}