zoukankan      html  css  js  c++  java
  • 汇编语言11堆栈修改

    1.下面这段代码运行的结果是什么?

    #include <stdio.h>
    #include <Windows.h>
    DWORD dz=0;
    DWORD dz1=0;
    void fun1()
    {
      __asm
      {
      mov eax, dz
      push eax
      ret
      }
    }
    void main()
    {
      HMODULE h = GetModuleHandle(NULL);
      dz1= dz =(DWORD)h;
      dz+=0x1062;//0x1062为 printf("2222
    ")相对于代码段基址的偏移
      dz1+=0x0;
      __asm
      {
      call fun1
      }
      printf("1111
    ");
      printf("2222
    ");
    }

    不仔细思考,运行结果为:
    2222

    实际运行结果:
    2222
    1111
    2222
    为什么会这样,分析下原因:
    1. call fun1语句执行后: printf("1111 ") 的地址压入栈.

    2. fun1函数执行后: ret指令改变了eip, eip = dz, 转到main函数里面执行 printf("2222 ")

    3. main函数执行ret后: 取出printf("1111 ")地址赋给了eip, 导致程序又跳到了printf("1111 ")处执行


    2.把fun1函数改进下,使运行结果为:
    2222

    实现代码:

    #include <stdio.h>
    #include <Windows.h>
    DWORD dz=0;
    DWORD dz1=0;
    void fun1()
    {
        __asm
       {
       add esp,8 //前面默认执行了push eip, push ebp, 保存main ret的地址内存就在esp+8的位置
         mov eax, dz1
           push eax //把printf("1111
    ")的地址替换为 main 的'}'
           sub esp,4 //还原栈指针
    
      mov eax, dz
      push eax
      ret
      }
    }
    void main()
    {
      HMODULE h = GetModuleHandle(NULL);
      dz1= dz =(DWORD)h;
      dz+=0x1077; //0x1062为 printf("2222
    ")相对于代码段基址的偏移
      dz1+=0x1085;//0x1085为 main函数的'}' 相对于代码段基址的偏移
      __asm
      {
        call fun1
      }
      printf("1111
    ");
      printf("2222
    ");
    }

    这样 main函数执行ret后: eip= '}' 地方的地址, 程序结束,运行结果为:
    2222

  • 相关阅读:
    ScriptOJ-flatten2#91
    ScriptOJ-unique#89
    ScriptOJ-safeGet#99
    测试
    SQL中常用的时间格式
    SQL Server -ISNULL()函数
    SQL Server -查看数据库扩展属性
    SQL Server 中创建数据库、更改主文件组示例
    SQL Server -SET QUOTED_IDENTIFIER
    SQL Server -SET ANSI_NULLS
  • 原文地址:https://www.cnblogs.com/mayingkun/p/4645566.html
Copyright © 2011-2022 走看看