【问题标题】:alternative to mangling jmp_buf in c for a context switch替代在 c 中修改 jmp_buf 以进行上下文切换
【发布时间】:2021-11-07 22:06:59
【问题描述】:

在 linux 系统的 setjmp.h 库中,jmp_buf 被加密解密,我们使用 mangle 函数

*/static long int i64_ptr_mangle(long int p) {
    long int ret;
    asm(" mov %1, %%rax;\n"
        " xor %%fs:0x30, %%rax;"
        " rol $0x11, %%rax;"
        " mov %%rax, %0;"
        : "=r"(ret)
        : "r"(p)
        : "%rax"
    );
    return ret;
}

 

我需要保存上下文并更改 jmp_buffer 中的堆栈指针、基指针和程序计数器,我可以使用此函数的任何替代方法。我正在尝试构建基本线程库,但无法解决这个问题。我不能使用 ucontext.h 。

【问题讨论】:

    标签: c multithreading context-switch setjmp


    【解决方案1】:

    您不妨推出自己的 setjmp/longjmp 版本;即使您对这种混乱进行逆向工程,您的结果也会比正确的版本更脆弱。 您需要了解一下您的环境的调用约定,但主要是这样的:

    mov  4(%esp), %eax
    mov  %ebx, _BX(%eax)
    mov  %esi, _SI(%eax)
    mov  %edi, _DI(%eax)
    mov  %ebp, _BP(%eax)
    pushf; pop _FL(%eax)
    mov  %esp, _SP(%eax)
    pop _PC(%eax)
    xor %eax,%eax
    ret
    
    loadctx:
    mov  4(%esp), %edx
    mov  8(%esp), %eax
    mov  _BX(%edx), %ebx
    ...
    push _FL(%edx)
    popf
    mov  _SP(%edx), %esp
    jmp _PC(%edx)
    

    然后你定义你的寄存器布局可能像:

    #define _PC  0
    #define _SP  4
    #define _FL  8
    ...
    

    应该在过时的编译器中工作,例如 gcc2.x。更多现代编译器已经,呃,增强,依赖于头本地存储(TLS)等。您可能必须在上下文中添加位。 另一个增强功能是堆栈检查,通常在 TLS 上分层。即使您禁用堆栈检查,您使用的库也可能会依赖它,因此您必须交换适当的条目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-04
      • 2011-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-13
      • 2018-09-22
      相关资源
      最近更新 更多