标签:
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
标签:
原文地址:http://www.cnblogs.com/mayingkun/p/4645566.html