• 汇编语言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

  • 相关阅读:
    [算法]外部排序
    [笔试]华为编程大赛题目
    [C++]字符串处理方法(STL与C风格)
    如何动态建立VFP能够打开的中文字段 dbf 表 北极星
    使用 VCL BDE 组件动态创建数据库表 北极星
    如何用Table控件判断数据库是否为空 北极星
    DNGuard HVM副产品(元数据名称编辑器)
    常见dotNet加密保护工具分析介绍
    DNGuard HVM 试用版 RC1 发布
    [转载]Modifying IL at runtime
  • 原文地址:https://www.cnblogs.com/mayingkun/p/4645566.html
Copyright © 2020-2023  润新知