通过堆栈溢出重定向指令指针



我一直在阅读The Shellcoder's Handbook (2e),并一直试图重现第18-23页的堆栈溢出实验。

我有这个代码

void return_input (void)
{
    char array[30];
    gets (array);
    printf(“%sn”, array);
}
main()
{
    return_input();
    return 0;
}

编译:gcc -fno-stack-protector -o overflow overflow.c

main函数的汇编代码转储:

0x080483ea <main+0>:  push %ebp
0x080483eb <main+1>:  mov  %esp,%ebp
0x080483ed <main+3>:  call 0x80483c4 <return_input>
0x080483f2 <main+8>:  mov  $0x0,%eax
0x080483f7 <main+13>: pop  %ebp
0x080483f8 <main+14>: ret

我们可以用return_input()的调用地址覆盖保存的返回地址

$ printf
"AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDxedx83x04x08" | ./overflow
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDí
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDò

这将导致我们的输入被打印两次。但是,没有提示我第二次输入。第二次呼叫return_input()不应该导致第二次呼叫gets()吗?

这可能与gets()从stdin读取的内容有关。

稍微修改过的程序版本:

#include <stdio.h>
int n = 1;
void return_input(void)
{
    char array[30];
    gets (array);
    printf("%sn", array);
    if (n--) return_input();
}
int main(void)
{
    return_input();
    return 0;
}

如果我只是运行它,我可以输入2个短字符串(每个后跟回车键),像这样:

C:gets.exe
qwe
qwe
123
123

这里qwe和123都在屏幕上重复出现(第一次是在我输入它们时,第二次是在它们被打印时)。

当我在Windows上使用echo命令管道程序输入时,我得到了以下内容,没有机会输入第二个字符串,gets()在第二次调用时不知何故设法获得垃圾作为输入:

C:echo qwe|gets.exe
qwe
№  ☺

所以,gets()读取管道输入的方式有问题,这与堆栈溢出无关。

最新更新