关于程序基址的问题

安然 2014-04-17 10:22:33
起因是这样的:
前段时间我知道了用CE,当时对每次重启游戏甚至电脑基址都不会变觉得很奇怪
,因为我以为基址是实实在在的物理内存地址,怎么可能不变呢
(假设当关闭程序重启之前有其它程序占据了那个程序的基址不就不可能不变了吗?)。。
后来自己查了下,好像有一点懂就是基址不是物理地址而是虚拟地址(不知道是不是?)?
但还是有疑问,既然是虚拟地址CE是怎么调用的。。
我自己自圆其说(就是CE向操作系统发送请求调用基址0x********,
操作系统知道CE请求的是虚拟地址,
于是通过对应表之类的东西返回CE基址的物理地址于是CE通过基址对应的物理地址+偏移量更改数据?),
但是我又觉得有问题,因为两个程序的基址可能一样(比如我开两个同样的程序)
,于是我开了两个相同的模拟器,找到了一个模拟器的基址,对应的数值为2(2格血),
然后用CE打开另一个模拟器,且游戏也是一样的,
这时候(基址->地址)+偏移量的值变成了6(之前的模拟器因为要找基址游戏里的人物血量变成了2,6是满血),
我让后者模拟器去少了一个血,6变成了5,
说明前一个模拟器找的基址和后面开的模拟器是一样的。。
这又不能圆我之前的理解(向操作系统请求基址对应的内存地址,但是基址相同怎么分别是要找哪个?)
以上都是我自己看资料后的猜测,有没有大神能帮我解释一下每个 问号 的问题。
...全文
518 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
安然 2014-04-19
  • 打赏
  • 举报
回复
引用 10 楼 buyong 的回复:
这个问题如果就用应用层的知识,估计是很难解释清楚的。 必须对操作系统内核机制深入研究。 使用虚拟地址是肯定的。
噢,既然大家言尽于此,后面的我自己看看操作系统的书来自己理解吧
buyong 2014-04-18
  • 打赏
  • 举报
回复
这个问题如果就用应用层的知识,估计是很难解释清楚的。 必须对操作系统内核机制深入研究。 使用虚拟地址是肯定的。
安然 2014-04-18
  • 打赏
  • 举报
回复
引用 8 楼 xiaohuh421 的回复:
各种进程空间, 虚拟地址是隔离的. 基址, 即是程序代码被编译成二进制码时就已经规定好的一个绝对地址值. 一般反汇编后为: mov xxx [XXXXXX] //XXXXX就是16进制数字代表的值, 除非程序被破坏,或者被重新编译生成,否则是不会改变的.
噢,比如基址epx(是一个虚拟地址),某程序向操作系统发出对epx+7A读或写2个字节的请求,那么操作系统会查找类似于地址转换表之类的东西,找到epx+7A对应的内存地址进行操作(读、写),那么是不是说系统分配给该程序的数据区的内存是连续的?假设我前面设想的正确:当我开了两个一样的程序时,则它们基址相同(物理内存不同?),那么我对操作系统发出对epx+7A读或写2个字节的请求时,这时候系统又该怎么找对应的物理内存地址呢?(现在是一个基址对应两块物理内存),还是说发送请求时要附加其它条件?
xiaohuh421 2014-04-18
  • 打赏
  • 举报
回复
各种进程空间, 虚拟地址是隔离的. 基址, 即是程序代码被编译成二进制码时就已经规定好的一个绝对地址值. 一般反汇编后为: mov xxx [XXXXXX] //XXXXX就是16进制数字代表的值, 除非程序被破坏,或者被重新编译生成,否则是不会改变的.
安然 2014-04-18
  • 打赏
  • 举报
回复
引用 1 楼 u012033027 的回复:
程序运行时,编译器生成的可执行码中的地址都是虚地址。操作系统负责把虚拟地址转换为物理地址。 至于你说的虚地址相同的问题,可能他们处于不同的进程,所以操作系统能够区分。
噢,那么是不是:以同一个基址或基址+偏移量向操作系统发送读写请求,操作系统返回的是同一个物理内存地址?
安然 2014-04-18
  • 打赏
  • 举报
回复
引用 3 楼 fengzizhuang 的回复:
-------问题1,“假设当关闭程序重启之前有其它程序占据了那个程序的基址不就不可能不变了吗?” 程序的逻辑地址是不变的,编译的时候已经决定了,当程序启动时,即加载的内存中,操作系统会映射一定的内存给改程序,但程序的寻址任然是按自己的逻辑地址进行,映射过程由操作系统决定,是透明的 -------问题2,“好像有一点懂就是基址不是物理地址而是虚拟地址(不知道是不是?)?” 没错,基址的确不是物理地址,一个程序在寻址是,都是相对于基址的偏移量。基址与偏移量进行运算得到逻辑地址,操作系统会将逻辑地址转为为内存的物理地址。详细的原理可以参见《计算机操作系统》这本书 你可以看看,操作系统中内存管理这一块,应该能够帮助你理解程序调用过程,及地址换行法则
谢谢你的解答,那么基地址是逻辑地址,操作系统给程序分配内存是是一块连续的内存吗?如果不是,基址+偏移量不就不是某个属性的动态地址了吗?既然基址是逻辑地址那CE又是怎么找到某程序的基址对应的内存地址的呢(比如我开了两个一模一样的程序,它们基址相同,CE不就不能分别是哪个了吗?)?
安然 2014-04-18
  • 打赏
  • 举报
回复
引用 4 楼 sd530842780 的回复:
你还是没有找到 基址吧,ce不是有tutor么,多级寻址看一下。
不是,已经找到了,我是按教程找的,而且做了测试是基地址。主要就是不明白基地址为什么不变等问题。
不要做咸鱼 2014-04-18
  • 打赏
  • 举报
回复
你还是没有找到 基址吧,ce不是有tutor么,多级寻址看一下。
dophiJing 2014-04-17
  • 打赏
  • 举报
回复
-------问题1,“假设当关闭程序重启之前有其它程序占据了那个程序的基址不就不可能不变了吗?” 程序的逻辑地址是不变的,编译的时候已经决定了,当程序启动时,即加载的内存中,操作系统会映射一定的内存给改程序,但程序的寻址任然是按自己的逻辑地址进行,映射过程由操作系统决定,是透明的 -------问题2,“好像有一点懂就是基址不是物理地址而是虚拟地址(不知道是不是?)?” 没错,基址的确不是物理地址,一个程序在寻址是,都是相对于基址的偏移量。基址与偏移量进行运算得到逻辑地址,操作系统会将逻辑地址转为为内存的物理地址。详细的原理可以参见《计算机操作系统》这本书 你可以看看,操作系统中内存管理这一块,应该能够帮助你理解程序调用过程,及地址换行法则
softee 2014-04-17
  • 打赏
  • 举报
回复
如果你对这个感兴趣,可以看看《深入理解计算机系统》这本书。
softee 2014-04-17
  • 打赏
  • 举报
回复
程序运行时,编译器生成的可执行码中的地址都是虚地址。操作系统负责把虚拟地址转换为物理地址。 至于你说的虚地址相同的问题,可能他们处于不同的进程,所以操作系统能够区分。
本课程主要以口袋西游为例,学习一个网络游戏是怎么通过游戏服务器与玩家客户端进行通信交互的,通过OD,CE等工具对游戏进行调试,找到各个数据基址(例如角色基址,背包基址等),找出游戏里面的功能CALL(例如寻路CALL,打坐CALL等)及参数分析,并且编码实现功能。本课程可以带领你游戏逆向入门可以学会 CE,OD,找游戏基址,功能CALL等实现变态功能可以更深入的理解从高级语言到汇编语言的一个对应过程可以学会 逆向软件  外挂与反外挂 破解防破解  游戏安全的基础知识可以为以后的及逆向高级课程 打下良好的基础可以自己分析游戏数据,用C语言实现游戏外挂功能等重点:  本套课程的重点就是带领大家分析游戏数据,毫不客气的说,各位学完此套课程对分析游戏数据这块会有一个质的飞跃。课程目录  01.课程简介及功能演示  02.CE找人物基址及人物属性偏移  03.OD找人物基址及人物属性偏移  04.创建MFC DLL项目  05.代码实现输出人物信息  06.发包函数概述  07.怎么看待重写的发包函数  08.普通发包与线程发包  09.找打坐CALL及参数分析  10.代码实现打坐CALL  11.喊话CALL及参数分析  12.代码实现喊话CALL  13.找寻路CALL及参数分析  14.代码编写寻路CALL  15.穿装备CALL及参数分析  16.代码实现穿装备CALL  17.NPC对话CALL  18.代码实现NPC对话CALL  19.唤出宠物  20.宠物合体  21.收回宠物  22.取下宠物

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧