在C语言中:发送func指针,用它调用func,使用EIP、jmp_buf和longjmp

在C语言中:发送func指针,用它调用func,使用EIP、jmp_buf和longjmp,c,function-pointers,setjmp,C,Function Pointers,Setjmp,我需要首先确保我理解一些基本的东西: 如何将函数A作为参数传递给函数B 如何从B内部调用函数A 现在让我们来看看大灾难: 我试着做一些类似的事情: jmp_buf buf; buf.__jmpbuf[JB_PC] = functionA; longjmp(buf,10); 这意味着我想使用longjmp来转到函数。我应该怎么做?您需要使用指向函数的指针。声明函数指针的语法为: rettype (*)(paramtype1,paramtype2,...,paramtypeN) 例如,我们可能有

我需要首先确保我理解一些基本的东西:

  • 如何将函数A作为参数传递给函数B
  • 如何从B内部调用函数A
  • 现在让我们来看看大灾难:

    我试着做一些类似的事情:

    jmp_buf buf;
    buf.__jmpbuf[JB_PC] = functionA;
    longjmp(buf,10);
    

    这意味着我想使用
    longjmp
    来转到函数。我应该怎么做?

    您需要使用指向函数的指针。声明函数指针的语法为:

    rettype (*)(paramtype1,paramtype2,...,paramtypeN)
    
    例如,我们可能有以下代码:

    char functionA(int x)
    {
          printf("%d\n",x):
          return 'a';
    }
    
    char functionB(char (*f)(int), int val)
    {
           return f(val); // invokes the function pointer
    }
    
    int main(int argc, char* argv[])
    {
           char result = functionB(&functionA,3); // prints "3"
           printf("%c\n",result); // prints 'a'
           return 0;
    }
    
    另外,需要注意的是,虽然&functo使用functo的地址,但实际上没有必要在那里使用符号and。。。我个人会这样做,因为我认为它更清楚地表明它是一个函数指针。调用函数指针时使用的语法与调用函数时相同

    至于使用跳转缓冲区,我相信你正在做的事情是不可靠的。如果您想在调用某个函数之前创建一个跳转缓冲区并调用setjmp,然后在稍后调用longjmp,以便在调用之前立即返回,那么这是定义良好的。然而,jmp_buf的实际定义和结构是特定于实现的。它必须满足某些要求(例如,它必须是一个数组类型,因为setjmp必须能够通过值获取它并修改它),但除此之外,没有定义jmp_buf的结构。因此,任何试图直接操纵jmp_buf的东西都是特定于特定平台的

  • 将函数作为参数传递给函数B:

    类型定义无效函数类型(无效)

    失效函数(失效) { printf(“这是函数A\n”); }

    int main(int argc,字符**argv) { 函数b(和函数a); 返回(0); }

  • 从函数B调用函数A:

    无效函数B(函数类型*func) { func(); }

  • 使用
    longjmp()
    转到函数。最好的答案是“不要这样做”——几乎总是有更好的方法来实现同样的目标。你能解释一下你需要这个的情况吗


  • 遗憾的是,这是我正在学习的操作系统课程中的作业。我们需要创建一个库,类似于pthreads。他们让我们使用setjmp和longjmp在线程之间执行上下文切换。问题是,一个新线程需要jmp_buf填充。因此,我想不出任何其他方法来让它的SP和IP在第一次进入上下文切换时达到我需要的位置。不要这样做。以这种方式使用setjmp()非常脆弱。在Unix或windows上使用makecontext/setcontext/swapcontext函数。