首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >重新定位线程控制块

重新定位线程控制块
EN

Stack Overflow用户
提问于 2014-01-09 19:47:34
回答 1查看 206关注 0票数 1

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

  • 所有这些都由指令调用*%gs:0x10触发。
  • %gs是使用全局描述符表的段寄存器。GDT是存储在与进程相关的内核堆栈中的关联表,并在进程的地址空间中保持段寄存器值和地址之间的对应关系。它是随机初始化的,由加载程序( glibc库的一部分)选择。
  • 一旦建立了对应关系,处理器就会读取*(GDT%gs+0x10)的地址,并进行VDSO中的调用。
  • syscall被执行,从内核返回到用户进程使用内核的AS中的返回地址存储。

我的问题是,我需要用其他东西覆盖我的一些进程内存,而且大多数情况下,它会擦除地址(GDT%gs+0x10)上的部分。

我想要做的是重新定位TCB的内容(从GDT%gs到GDT%gs+0x..)在我的进程中的一个自由位置‘AS,但这将意味着改变GDT内容,我认为我不能从用户模式。换句话说,我想改变GDT中%GS的关联。

谢谢您的答复,/iansus

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-31 17:52:07

好的,我找到了解决办法:

代码语言:javascript
运行
复制
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;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21029729

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档