首页
社区
课程
招聘
[求助]为什么xp下用VC输出地址,每次都不变,win7 64位运行软件,地址都随机的?
发表于: 2014-12-29 12:56 5794

[求助]为什么xp下用VC输出地址,每次都不变,win7 64位运行软件,地址都随机的?

2014-12-29 12:56
5794
#include <iostream>
using namespace std;
int main()
{
int i = 1;
cout<<&i<<endl;
// i在XP下每次运行地址不变,在win7 64位每次运行地址都变,为什么?

return 0;
}

有没有办法不换操作系统,更改设置,使地址每次都不变呢?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 2155
活跃值: (29)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
win7系统有可能是ASLR。。。应该就是这个原因了吧。。。
这个链接貌似有用,没仔细研究过这块:http://blog.adintr.com/313
2014-12-29 13:14
0
雪    币: 7048
活跃值: (3527)
能力值: ( LV12,RANK:340 )
在线值:
发帖
回帖
粉丝
3
就算没有ASLR,不换系统,你这代码也有问题.
#include <iostream>
using namespace std;
int main()
{
int i = 1;
cout<<&i<<endl;
// i在XP下每次运行地址不变,在win7 64位每次运行地址都变,为什么?

return 0;
}

你这取的是栈中的地址.因为每次程序入口时,esp基本都是固定的.所以你这个在xp下是一样的.

你要是写成这样:
#include <iostream>
using namespace std;

void printaddr()
{
  int i = 1;
  cout<<&i<<endl; 
}

void funcb()
{
  int a, b;
  printaddr();
}

int main()
{
  printaddr();
  funcb();
  return 0;
}


在编译成debug模式看看.

存放在栈中的变量,本来就不该保证其地址是固定的.
2014-12-29 13:21
0
雪    币: 123
活跃值: (27)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
4
栈地址本来就是不固定的,你那个固定也只是巧合而已
2014-12-30 16:40
0
雪    币: 75
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
我试了10几次,在xp下都不变
2014-12-31 03:10
0
雪    币: 123
活跃值: (27)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
6
只能说你的程序太小了,太简单了
2014-12-31 09:34
0
雪    币: 101
活跃值: (43)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
说明你测试程度不够,不是数量,是范围。有无数种可能会改变栈地址。栈就是一个大箱子,各个子程序的局部变量什么的有事没事都往里面塞,具体在哪个位置没人敢保证的,程序运行使用都是实时通过esp/ebp获取的,用固定地址就是作死。
2015-1-5 11:54
0
雪    币: 75
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
我都重启了,地址都没变?你用的是XP?
2015-1-5 15:14
0
雪    币: 101
活跃值: (43)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
重启了能证明什么呢

就跟

我都睡了一觉了气温还是6°

一个意思

当然,这个问题跟系统也无关。
2015-1-5 15:51
0
雪    币: 101
活跃值: (43)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
栈是什么,你可能知道,也可能不知道。简单的说,就是给每个线程分配的一块空间,这块空间遵循先进后出原则,也就是说你往里面塞一个东西,如果再塞了别的东西,要等那个东西拿走,才能拿出你的东西。而你的变量i就塞在里面,你无法保证这里面之前还塞了什么,塞的东西多大,所以你不能确定说地址是不变的。

比如说,你把这段代码放在另一个子程序里,然后再输出一下地址,是不是不一样了?为什么呢,因为子程序调用的过程也要往栈里塞东西(子程序的参数啊返回地址啊什么的),所以你的东西被垫起来了。所以你这段代码只能放在这个位置,在旁边再写点什么都有可能变化(不只是子程序调用会影响堆栈)。那么,是不是除了这个问题就没其他会影响地址的可能了呢,答案是还有得是。

比如,就算是你的代码不变,编译器有变动。有的编译器会在你程序运行之前(你自己写的代码之前)向堆栈里存储一些数据,比如安装一个全局的异常处理,这个异常处理的数据也在栈里面,然后你的地址就又变了,你可能说,这不是大事,我就用vc6.但是当你代码放个三年五年,vc6彻底淘汰了呢,你去装个什么vs2015什么的,然后你会发现这是一份废代码,因为你修改都不知道怎么修改。

再说一个情况,栈的起始地址并不是固定的,你反复强调你是xp系统,但是别忘了xp系统也至少有几百个补丁,只要影响到了exe加载机制的补丁都可能影响栈的起始值,也就是说你程序只有你电脑能用,当然  如果你打算让用户用你系统的ghost的话,哈哈哈哈哈哈哈

就算你不更新补丁,如果栈创建时,地址被占用了(比如有哪个不长眼的程序外部注入了你一个dll,而dll的基址就是你栈的地址。),杀软啊、输入法啊什么的经常会干这种事情,嗯 你这地址还是不对。

系统不同肯定不同这个就不说了

详细的就说这么多,我想不到所有可能,也没几个大神能把这些都背下来,其他小的问题?  

比如说你随手改了个优化选项,栈里的数据对齐方式变了 --出错
比如你程序运行在了兼容模式下,堆栈里有其他数据 --出错
比如用户开了xp盾甲,系统自带了ASLR 堆栈地址随机化 --出错
……
……
2015-1-5 16:07
0
游客
登录 | 注册 方可回帖
返回
//