线程\u create\u运行会导致整个计算机在OSX 10.6上重新启动

线程\u create\u运行会导致整个计算机在OSX 10.6上重新启动,c,macos,reverse-engineering,C,Macos,Reverse Engineering,我正试图在OSX中编写一个C程序,它将改变另一个程序的执行流,就像调试器一样。但是,在我把所有的“片段”放在一起之前,我需要先测试它们是否各自工作 我已经成功地使用mach\u vm\u read\u overwrite()和mach\u vm\u write()读取和写入堆栈 我已经成功地使用thread\u get\u state()和thread\u set\u state()读取和写入寄存器 剩下的就是使用thread\u create\u running()在任务中创建一个线程来执

我正试图在OSX中编写一个C程序,它将改变另一个程序的执行流,就像调试器一样。但是,在我把所有的“片段”放在一起之前,我需要先测试它们是否各自工作

  • 我已经成功地使用
    mach\u vm\u read\u overwrite()
    mach\u vm\u write()
    读取和写入堆栈
  • 我已经成功地使用
    thread\u get\u state()
    thread\u set\u state()
    读取和写入寄存器
剩下的就是使用
thread\u create\u running()
在任务中创建一个线程来执行我的任意函数。然而,每当我创建一个线程时,OSX就会完全崩溃并自动重新启动我的计算机,哈哈。有人能更详细地解释一下发生了什么吗

这是我的远程程序test.c:

#include <unistd.h>
#include <stdio.h>

void function1() {
    printf("lol 1\n");
}

void function2() {
    printf("lol 2\n");
}

void function3() {
    printf("lol 3\n");
}

int main(int argc, char **argv) {
    while(1) {
        function1();
        sleep(1);
        function2();
        sleep(1);
        function3();
        sleep(1);
    }
    return 0;
}
#包括
#包括
无效函数1(){
printf(“lol 1\n”);
}
无效函数2(){
printf(“lol 2\n”);
}
无效函数3(){
printf(“lol 3\n”);
}
int main(int argc,字符**argv){
而(1){
功能1();
睡眠(1);
函数2();
睡眠(1);
功能3();
睡眠(1);
}
返回0;
}
下面是我正在进行的微型调试器:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <stdint.h>
#include <mach/mach_traps.h>
#include <mach/mach_init.h>
#include <mach/mach_error.h>
#include <mach/mach.h>
#include <mach/mach_types.h>
#include <mach/i386/thread_status.h>

void error(char *msg) {
        printf("error: %s\n", msg);
        exit(1);
}

int main(int argc, char **argv) {
    pid_t pid;
    mach_port_t eq_task;
    kern_return_t err;
    thread_act_port_array_t thread_list;
    mach_msg_type_number_t thread_count;
    x86_thread_state_t x86_state;
    mach_msg_type_number_t sc = x86_THREAD_STATE_COUNT;
    thread_act_t remoteThread;

    // Make sure we have an argument
    if (argc != 2)
        error("requires a PID");
    else
        pid = (pid_t)atoi(argv[1]);

    // Make sure we're root
    if (getuid() && geteuid())
        error("requires root");

    // Get the task port
    err = task_for_pid(mach_task_self(), pid, &eq_task);
    if ((err != KERN_SUCCESS) || !MACH_PORT_VALID(eq_task))
        error("getting eq task");

    // Suspend the process
    if(task_suspend(eq_task))
        error("suspending the task");

    // Get a list of threads from the port
    if (task_threads(eq_task, &thread_list, &thread_count))
        error("cannot get list of tasks");

    // Get the registers
    if (thread_get_state(thread_list[0], x86_THREAD_STATE, (thread_state_t)&x86_state, &sc))
        error("getting state from thread");

    // Create a new thread
    err = thread_create_running(eq_task, x86_THREAD_STATE, (thread_state_t)&x86_state, x86_THREAD_STATE_COUNT, &remoteThread);

    // BLACK SCREEN AND CRASH

    // Resume the process again
    if(task_resume(eq_task))
        error("resuming the task");

}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
无效错误(字符*消息){
printf(“错误:%s\n”,msg);
出口(1);
}
int main(int argc,字符**argv){
pid_t pid;
马赫端口均衡任务;
内核返回错误;
线程\动作\端口\数组\线程\列表;
马赫数、型号、螺纹数;
x86线程状态为x86线程状态;
马赫数、型号、编号、sc=x86螺纹、状态、计数;
线程行为远程线程;
//确保我们有争论
如果(argc!=2)
错误(“需要PID”);
其他的
pid=(pid_t)atoi(argv[1]);
//确保我们是根
if(getuid()&&geteuid())
错误(“需要根”);
//获取任务端口
err=任务对于pid(马赫任务、pid和均衡任务);
如果((err!=KERN_SUCCESS)| |!马赫数|u端口_有效(eq_任务))
错误(“获取eq任务”);
//暂停进程
if(任务暂停(均衡任务))
错误(“暂停任务”);
//从端口获取线程列表
if(任务线程(均衡任务、线程列表和线程计数))
错误(“无法获取任务列表”);
//拿到登记簿
if(线程获取状态(线程列表[0]、x86线程状态、(线程状态)和x86线程状态,&sc))
错误(“从线程获取状态”);
//创建一个新线程
err=线程创建运行(eq任务、x86线程状态、(线程状态)和x86线程状态、x86线程状态计数和远程线程);
//黑屏与崩溃
//再次恢复该过程
if(任务恢复(均衡任务))
错误(“恢复任务”);
}

我假设您试图以XD位执行此操作,除非您运行的是AMD而不是intel。那么它将是NX而不是XD。这将导致应用程序甚至整个计算机崩溃。

这可能不是您唯一的问题,但我始终发现,在另一个任务挂起时在该任务中创建线程会导致该任务崩溃。此外,崩溃日志通常用于查看导致问题的线程。即使该线程未挂起,我的计算机仍会重新启动。崩溃日志在哪里?您可以在控制台应用程序中查看它们。