DarkKnight121 发表于 2020-11-25 16:33:09

汇编语言入栈和出战问题

#include<stdio.h>
#include<string.h>

void func(char *src){
        char buf;
        strcpy(buf,str);
}

char gbuf="1111111111111";
int main(){
        void *p;
                __asm{
                push ebp;            //第一个问题点         
                mov p,offset aa;//第二个问点
        }
        *((void **)(gbuf+8))=p;
        func(gbuf);
        printf("Hello,never execute\n");
        goto end ;
        aa:
                __asm add esp,4 ;//第三个问题点
                __asm pop ebp ;
                printf("new Path\n");
        end :
                printf("end\n");
       
        return 0;

}

这段代码最后运行的是什么结果?第一个问题点和第三个问题点有没有必然联系?如果去掉第三个问题点对整个代码的执行有什么影响?

xieglt 发表于 2020-11-25 17:10:06

运行结果是:
输出
Hello,never execute
end
然后程序崩溃

#include<stdio.h>
#include<string.h>

void func(char *src){
      char buf;
                //错误,str未定义,是src吧?
      strcpy(buf,src);
}

//错误,数组溢出
char gbuf={'1'};

int main(){
      void *p;
                __asm{
                        //第一个问题点,高级语言中,在函数里通常是用ebp 来访问栈的,
                        //栈里保存着参数、返回地址,同时栈用来分配临时变量.所以在函数
                        //开始,一定要保存ebp,因为ebp在其他函数里也一定会用到。
                        push ebp;            
                       
                        //第二个问点,将语句标号aa的地址赋给变量p
                        mov p,offset aa;
      }

                //将p的值即aa的地址赋给 gbuf;
      *((void **)(gbuf+8))=p;
                //调用函数 func,其实func 里啥也没干
      func(gbuf+8);
                //输出信息
      printf("Hello,never execute\n");
                //跳转到 end
      goto end ;
                //这下面3条语句被跳过
      aa:
                                //第三个问题点,add esp,4 这是用来释放临时变量空间的
                __asm add esp,4 ;
                __asm pop ebp ;
                printf("new Path\n");
                //因为之前 push ebp,而后面没有pop ebp,所以栈乱了,程序不能正常返回,必然崩溃。
      end :
                printf("end\n");
      
      return 0;

}
页: [1]
查看完整版本: 汇编语言入栈和出战问题