我怎样才能调用缓冲区溢出?

我有一个家庭作业,要求我使用缓冲区溢出调用函数而不显式调用它。代码基本上是这样的:
#include <stdio.h>
#include <stdlib.h>

void g()
{
    printf("now inside g()!n");
}


void f()
{   
    printf("now inside f()!n");
    // can only modify this section
    // cant call g(), maybe use g (pointer to function)
}

int main (int argc, char *argv[])
{
    f();
    return 0;
}
虽然我不知道该怎么办。我想改变程序计数器的返回地址,以便它直接进入g()的地址,但我不知道如何访问它。无论如何,提示将是伟大的。     
已邀请:
基本思想是改变函数的返回地址,以便在函数返回时继续在新的黑客地址执行。正如Nils在其中一个答案中所做的那样,你可以声明一块内存(通常是数组)并以这样的方式溢出它,使得返回地址也被覆盖。 我建议你不要盲目地接受这里给出的任何程序,而不是真正了解它们是如何工作的。这篇文章写得很好,你会发现它非常有用: 缓冲区溢出漏洞的一步一步     
这取决于编译器,因此不能给出单个答案。 以下代码将为gcc 4.4.1执行您想要的操作。禁用优化编译(重要!)
#include <stdio.h>
#include <stdlib.h>

void g()
{
    printf("now inside g()!n");
}


void f()
{   
  int i;
  void * buffer[1];
  printf("now inside f()!n");

  // can only modify this section
  // cant call g(), maybe use g (pointer to function)

  // place the address of g all over the stack:
  for (i=0; i<10; i++)
     buffer[i] = (void*) g;

  // and goodbye..
}

int main (int argc, char *argv[])
{
    f();
    return 0;
}
输出:
nils@doofnase:~$ gcc overflow.c
nils@doofnase:~$ ./a.out
now inside f()!
now inside g()!
now inside g()!
now inside g()!
now inside g()!
now inside g()!
now inside g()!
Segmentation fault
    
由于这是家庭作业,我想回应codeaddict关于理解缓冲区溢出实际如何工作的建议。 我通过阅读关于利用缓冲区溢出漏洞的优秀(如果有点过时)文章/教程来学习这项技术,这些漏洞粉碎了堆栈的乐趣和利润。     
试试这个:
void f()
{   
    void *x[1];
    printf("now inside f()!n");
    // can only modify this section
    // cant call g(), maybe use g (pointer to function)
    x[-1]=&g;
}
或者这一个:
void f()
{   
    void *x[1];
    printf("now inside f()!n");
    // can only modify this section
    // cant call g(), maybe use g (pointer to function)
    x[1]=&g;
}
    
虽然这个解决方案没有使用溢出技术覆盖堆栈上函数的返回地址,但它仍然会导致
g()
在返回到
main()
的过程中从
f()
调用,只需修改
f()
而不直接调用
g()
。 函数结尾类似的内联汇编被添加到
f()
以修改堆栈上的返回地址的值,以便
f()
将通过
g()
返回。
#include <stdio.h>

void g()
{
    printf("now inside g()!n");
}

void f()
{   
    printf("now inside f()!n");
    // can only modify this section
    // cant call g(), maybe use g (pointer to function)

    /* x86 function epilogue-like inline assembly */
    /* Causes f() to return to g() on its way back to main() */
    asm(
        "mov %%ebp,%%esp;"
        "pop %%ebp;"
        "push %0;"
        "ret"
        : /* no output registers */
        : "r" (&g)
        : "%ebp", "%esp"
       );
}

int main (int argc, char *argv[])
{
    f();
    return 0;
}
了解此代码的工作原理可以更好地理解如何为构成缓冲区溢出技术基础的特定体系结构设置函数的堆栈帧。     

要回复问题请先登录注册