Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 重新定位线程控制块_Assembly_Process_Kernel_Internals - Fatal编程技术网

Assembly 重新定位线程控制块

Assembly 重新定位线程控制块,assembly,process,kernel,internals,Assembly,Process,Kernel,Internals,我目前的情况是需要重新定位TCB线程控制块。 据我所知,在根据调用VDSO时,在进程执行中采用了以下方案 全部由指令调用触发*%gs:0x10 %gs是使用全局描述符表的段寄存器。GDT是一个关联表,存储在与进程相关的内核堆栈中,并保持进程地址空间中的段寄存器值和地址之间的对应关系。它是随机初始化的,由glibc库的加载程序部分选择 一旦建立了对应关系,处理器将读取*GDT[%gs]+0x10处的地址,并进行VDSO中的调用。 系统调用被执行,并且从内核返回到用户进程使用内核AS中的返回地址存储

我目前的情况是需要重新定位TCB线程控制块。 据我所知,在根据调用VDSO时,在进程执行中采用了以下方案

全部由指令调用触发*%gs:0x10 %gs是使用全局描述符表的段寄存器。GDT是一个关联表,存储在与进程相关的内核堆栈中,并保持进程地址空间中的段寄存器值和地址之间的对应关系。它是随机初始化的,由glibc库的加载程序部分选择 一旦建立了对应关系,处理器将读取*GDT[%gs]+0x10处的地址,并进行VDSO中的调用。 系统调用被执行,并且从内核返回到用户进程使用内核AS中的返回地址存储。 我的问题是,我需要用其他东西覆盖我的一些进程内存,大多数情况下,它会擦除地址GDT[%gs]+0x10处的部分

我想做的是将TCB的内容从GDT[%gs]重新定位到GDT[%gs]+0x。。在我的流程中的一个免费位置,但这意味着改变GDT的内容,我认为我不能从用户模式做这件事。换句话说,我想更改GDT中%GS的关联

提前感谢您的回答,
/iansus

好的,我找到了解决方案:

int relocateTCB()
{

#ifndef TCB_LDT_INDEX
#define TCB_LDT_INDEX 6
#endif


    struct user_desc* u_info = (struct user_desc*) malloc(sizeof(struct user_desc));
    int r,j;
    int mstart, map;
    int PS = sysconf(_SC_PAGESIZE);

    if(u_info == NULL)
    {
        errno = EFAULT;
        return -1;
    }

    u_info->entry_number = TCB_LDT_INDEX;
    r = syscall(SYS_get_thread_area, u_info);

    if(r==-1) return -1;

    mstart = (u_info->base_addr) & ~(PS-1);
    map = (int) mmap(NULL, PS, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, (off_t)0);

    if(!map)
    {
        errno = EFAULT;
        return -1;
    }

    for(j=mstart; j<mstart+PS; j+=sizeof(int))
    {
        * ((int*) (map+j-mstart)) = * ((int*) j);
    }

    u_info->base_addr = map + u_info->base_addr - mstart;
    r = syscall(SYS_set_thread_area, u_info);

    if(r==-1)
    {
        errno = EINVAL;
        return -1;
    }

    for(j=mstart; j<mstart+PS; j+=sizeof(int))
        *((int*) j) = 0;

    // Keep *%gs = %gs
    *((int*) u_info->base_addr) = u_info->base_addr;

    return 0;
}