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
如果你们中的任何人也可以请我解释一下这个代码..我是一个装配工人..
答案 0 :(得分:4)
这只是显示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个字节)提供空间。
答案 1 :(得分: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 //-
答案 2 :(得分:1)
原始C函数是:
void myfun1(char *str) {
char buffer[16];
strcpy(buffer, str);
myfun2(buffer);
}
您在语句周围看到的程序集就是编译器为每个语句生成的程序集。例如,使用myfun2(buffer)
调用myfun2会生成以下汇编指令:
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
这样的输出可以由反汇编程序产生,前提是已编译的代码有足够的信息将汇编语句映射回源代码行。