码迷,mamicode.com
首页 > 编程语言 > 详细

汇编语言11堆栈修改

时间:2015-07-14 17:17:15      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:

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\n")相对于代码段基址的偏移
  dz1+=0x0;
  __asm
  {
  call fun1
  }
  printf("1111\n");
  printf("2222\n");
}

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

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

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

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

 


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\n")的地址替换为 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\n")相对于代码段基址的偏移
  dz1+=0x1085;//0x1085为 main函数的‘}‘ 相对于代码段基址的偏移
  __asm
  {
    call fun1
  }
  printf("1111\n");
  printf("2222\n");
}

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

汇编语言11堆栈修改

标签:

原文地址:http://www.cnblogs.com/mayingkun/p/4645566.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!