“调用0x80482f0 <puts @ plt>”?只需要在x86程序集中的'hello world'程序中澄清一行代码</puts @ plt>

时间:2011-10-02 05:52:36

标签: linux debugging assembly x86

call 0x80482f0 <puts@plt>”?只需要在x86程序集中的“hello world”程序中获得一行代码的帮助。

注意:我在编程/调试时正在运行ubuntu linux,使用gcc作为编译器,使用gdb作为调试器。

我正在阅读 Hacking:剥削技术V2 并编译了这个C程序:

1       #include <stdio.h>
2
3       int main()
4       {
5         int i;
6         for(i=0; i<10; i++)
7         {
8           printf("Hello, world\n");
9         }
10        return 0;

汇编到这个程序中:

   0x080483b4 <+0>:     push   ebp
   0x080483b5 <+1>:     mov    ebp,esp
   0x080483b7 <+3>:     and    esp,0xfffffff0
   0x080483ba <+6>:     sub    esp,0x20
   0x080483bd <+9>:     mov    DWORD PTR [esp+0x1c],0x0
   0x080483c5 <+17>:    jmp    0x80483d8 <main+36>
   0x080483c7 <+19>:    mov    DWORD PTR [esp],0x80484b0
   0x080483ce <+26>:    call   0x80482f0 <puts@plt>
=> 0x080483d3 <+31>:    add    DWORD PTR [esp+0x1c],0x1
   0x080483d8 <+36>:    cmp    DWORD PTR [esp+0x1c],0x9
   0x080483dd <+41>:    jle    0x80483c7 <main+19>
   0x080483df <+43>:    mov    eax,0x0
   0x080483e4 <+48>:    leave  
   0x080483e5 <+49>:    ret

现在......我理解这个程序的每个部分,直到它:

   0x080483ce <+26>:    call   0x80482f0 <puts@plt>

我不明白的是..如果“Hello,world \ n”存储在0x80484b0,然后该地址存储在ESP的地址中,为什么会这样:

0x080483ce <+26>:    call   0x80482f0 <puts@plt>

参考0x80482f0,而不是[esp]或只是“0x80484b0”将“Hello,world \ n”打印到屏幕上?我使用gdb,我无法弄清楚究竟是什么引用0x80482f0 ..任何帮助都会很棒

谢谢(记住,我刚刚开始使用这些东西,所以我是一个菜鸟)

另外..为了方便起见,我从gdb复制并粘贴了反汇编的main函数,如果你需要更多的信息,请问。如果你想为我解释一个命令,那也很好,因为我之前只用了“int 80h”将内容打印到屏幕上

1 个答案:

答案 0 :(得分:15)

0x80482f0puts函数的地址。更确切地说,它指向program linker table(PLT)中puts()的条目 - 基本上只是一堆JMP <some routine in a so-library> s(它是a little more complex,但那是这个讨论并不重要)。 puts函数在堆栈上查找其参数 - 即[esp]

您可能想知道puts()调用来自何处 - 此处的编译器非常智能,可以看到您在调用printf()时实际上没有使用任何格式字符串参数,并将其替换为打电话给({更快] puts()。如果你仔细观察,你会发现它也从你的字符串中删除了换行符,因为puts()在打印出它的字符串后附加了换行符。