2
void myfun1(char *str) {
push ebp
mov ebp,esp
char buffer[16];
sub esp,0x18
strcpy(buffer, str);
mov eax,DWORDPTR [ebp+8]
mov DWORD PTR [esp+4],eax
lea eax,[ebp-16]
mov DWORD PTR [esp],eax
call 0x80482c4 <strcpy@plt>
myfun2(buffer);
lea eax,[ebp-16]
mov DWORD PTR [esp],eax
call 0x80483b4 <myfun2>
}
leave
ret

如果你们中的任何人都可以请也为我解释这段代码..我是汇编中的初学者..

4

3 回答 3

5

这只是显示由 C 函数生成的汇编代码。如果您注释掉 C 行,并在其间添加一些换行符,那么发生的事情就会变得更加清晰。

// void myfun1(char *str) {
push ebp
mov ebp,esp

// char buffer[16];
sub esp,0x18                  // Allocate space for buffer and function args.

// strcpy(buffer, str);
mov eax,DWORDPTR [ebp+8]      // Load the str parameter into eax.
mov DWORD PTR [esp+4],eax     // Set str as the second argument to strcpy.
lea eax,[ebp-16]              // Load the address of the buffer into eax.
mov DWORD PTR [esp],eax       // Set the address as the first argument to strcpy.
call 0x80482c4 <strcpy@plt>   // Call strcpy.

// myfun2(buffer);
lea eax,[ebp-16]              // Load the address of the buffer into eax.
mov DWORD PTR [esp],eax       // Set the address as the first argument to myfunc.
call 0x80483b4 <myfun2>       // Call myfunc.

// }
leave
ret

这与我通常期望生成的 C 代码有点不同。您通常会在调用函数之前将参数压入堆栈,而此代码已提前在堆栈上腾出空间,然后将参数移入堆栈。

为了更好地理解 ebp 和 esp 引用,它有助于构建堆栈的样子。

       ebp+08  The str parameter
       ebp+04  The return address
       ebp+00  The saved copy of ebp            <- ebp
       ebp-04  Space for buffer
       ebp-08  Space for buffer
       ebp-12  Space for buffer
       ebp-16  Space for buffer
esp+04 ebp-20  Second function argument
esp+00 ebp-24  First function argument          <- esp

当函数被调用时,str参数被压入堆栈,加上调用代码的返回地址。然后该函数保存 ebp 的副本,并将 ebp 设置为指向堆栈上的该位置。最后,它为缓冲区(16 个字节)加上函数调用中使用的两个参数(另外 8 个字节)腾出空间。

于 2013-07-12T20:30:13.680 回答
1

这似乎是 C 代码,其中逐行混合了汇编,完全按照前一行所说的进行。请注意,这样做没有任何意义。其中一种语言应该被注释掉。

void myfun1(char *str) {        //C
    push ebp                    //ASM
    mov ebp,esp                 //-
    char buffer[16];            //C
    sub esp,0x18                //ASM
    strcpy(buffer, str);        //C
    mov eax,DWORDPTR [ebp+8]    //ASM
    mov DWORD PTR [esp+4],eax   //-
    lea eax,[ebp-16]            //-
    mov DWORD PTR [esp],eax     //-
    call 0x80482c4 <strcpy@plt> //-
    myfun2(buffer);             //C
    lea eax,[ebp-16]            //ASM
    mov DWORD PTR [esp],eax     //-
    call 0x80483b4 <myfun2>     //-
}                               //C
leave                           //ASM
ret                             //-
于 2013-07-12T20:18:33.443 回答
1

原始的 C 函数是:

void myfun1(char *str) {
   char buffer[16];
   strcpy(buffer, str);
   myfun2(buffer);
}

您在语句周围看到的程序集只是编译器为每个语句生成的。例如,调用 myfun2myfun2(buffer)会产生以下汇编指令:

lea eax,[ebp-16]            ; load the address of buffer (local variable at ebp-16) into eax
mov DWORD PTR [esp],eax     ; "push" the address on the stack as parameter - stack pointer has already been adjusted earlier
call 0x80483b4 <myfun2>     ; call the function

如果编译后的代码有足够的信息将汇编语句映射回源代码行,则可以由反汇编程序生成此类输出。

于 2013-07-12T20:18:37.150 回答