×

内存地址 c

c++获取内存地址?内存地址最重要的特点

admin admin 发表于2023-03-23 19:55:45 浏览43 评论0

抢沙发发表评论

本文目录

c++获取内存地址

这是个我之前想查看植物大战僵尸相应的数据写的部分代码:
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
if (hProcess == NULL)
{
TRACE(“OpenProcess : %d\n“, GetLastError());
return ;
}
addr = 0xeca8b0;
ReadProcessMemory(hProcess, (LPVOID)addr, &buffer, sizeof(buffer), NULL);
TRACE(“buffer = %d \n“, buffer);
return ;
这里面的地址呢,是通过CHEAT ENGINE的软件获取的。
一开始,我觉得这个值是随机的,即每次运行的时候都不一样,结果,最后我换了好几点电脑结果都一样,那么我认真去查看了MSND:lpBaseAddress
[in] Pointer to the base address in the specified process from which to read. Before any data transfer occurs, the system verifies that all data in the base address and memory of the specified size is accessible for read access. If this is the case, the function proceeds; otherwise, the function fails.
那么这个地址其实是相对应于程序的起始地址,那么就有办法了,你可以事先个程序来遍历你的程序,然后找到相应的地址,以后就是固定死了,你都可以读到相应的数据了,除非程序有变动。

内存地址最重要的特点

内存条是连接CPU和其他设备的通道,起到缓冲和数据交换作用。当CPU在工作时,需要从硬盘等外部存储器上读取数据,但由于硬盘这个“仓库”太大,加上离CPU也很“远”,运输“原料”数据的速度就比较慢,导致CPU的生产效率大打折扣!为了解决这个问题,人们便在CPU与外部存储器之间,建了一个“小仓库”—内存条。
内存条虽然容量不大,一般只有几十MB到几GB,但中转速度非常快,如此一来,当CPU需要数据时,事先可以将部分数据存放在内存中,以解CPU的燃眉之急。由于内存只是一个“中转仓库”,因此它并不能用来长时间存储数据。
内存条的作用
内存条是电脑中的主要部件,它是相对于外存而言的。我们平常使用的程序,如WindowsXP系统、打字软件、游戏软件等,一般都是安装在硬盘等外存上的,但仅此是不能使用其功能的,必须把它们调入内存中运行,才能真正使用其功能,我们平时输入一段文字,或玩一个游戏,其实都是在内存中进行的。通常我们把要永久保存的、大量的数据存储在外存上,而把一些临时的或少量的数据和程序放在内存上。

计算机内存地址只有5种表现形式吗,为什么

了解了内存的知识,也知道内存的使用方法,那内存是内存条吗?答案是否定的,内存是暂时存储程序以及数据的地方。那内存有什么作用哪?大家都知道是存数据的。

上节中介绍了如何对内存读写,例如把一块内存地址[0x12345678]的数据存到另一块内存地址为[0x87654321]中去,用MOV指令实现。

解:

MOV EAX ,DWORD PTR DS:[0x12345678]

MOV DWORD PTR DS:[0x87654321],EAX

我们从答案中可以得出,内存地址是一些数值编号组成的,难道内存地址只有这一种表现形式吗?我们在调试程序的时候还会碰到其它的表现形式吗?我们在调试程序时,内存地址不止这一种表现形式,还有其它的表现形式,共分为五种。

2.6.1【内存地址的五种表现形式】

第一种形式:[立即数]

读取内存的值:

MOV EAX,DWORD PTR DS:[0x003EF8CC]

第一步:首先确定宽度DWORD表示宽度为四个字节,EAX寄存器为32位寄存器,0x003EF8CC是已经申请的内存。看图2-6-1中,此时EAX寄存器存储的数据为0x001D2BA2;
第二步:按F8观察EAX寄存器存储的数据有什么变化,,如图2-6-2所示,看到EAX寄存器存储的数据正是内存地址0x3EF8CC里面存储的数据。
向内存中写入数据:

MOV DWORD PTR DS:[0x003EF8D0],ECX

第一步:首先确定宽度DWORD表示宽度为四个字节,ECX寄存器为32位寄存器,0x003EF8D0是已经申请的内存,看图2-6-3中,ECX存储的数据为0x0000000,内存地址0x03EF8D0存储的数据是001D2BA2;
第二步:按F8观察内存地址0x003EF8D0存储的数据的变化,如图2-6-4所示,

看到内存地址0x003EF8CC里面存储的数据正是ECX寄存器里面存储的数据。
第二种形式:[register]

register代表通用寄存器,可以是8个通用寄存器中任意一个,表示该寄存器中储存的数据为内存地址。我们程序运行的时候,通常将基址保存在寄存器中。这里只能使用这8个32位通用寄存器,因为内存地址编号是32位。

读取内存中的值:

MOV ECX,0x002FFE18

MOV EAX, DWORD PTR DS:[ECX]

第一步:将指令MOV ECX,0x002FFE18 写入汇编窗口,如图2-6-5,记住当前ECX寄存器存储的数据为0x11111111。
第二步:按F8观察,是否把内存地址0x002FFE18写入ECX中,如图2-6-6所示:
第三步:将指令MOV EAX, DWORD PTR DS:[ECX]写入汇编窗口,如图2-6-7所示:
第四步:按F8观察,是否把ECX存储的内存地址对应的数据写入EAX中,如图2-6-8所示:
向内存中写入数据:

MOV EDX,0x002FFE1C

MOV DWORD PTR DS:[EDX],0x123456

第一步:将指令输入到汇编窗口;
第二步:按F8观察,把内存地址0x002FFE1C写入EDX中,看图2-6-10:
第三步:按F8观察,把立即数0x00123456写入EDX中,看图2-6-11:
第三种形式:[register+立即数]

读取内存中的值:

MOV ECX,0x003FF9E4

MOV EAX, DWORD PTR DS:[ECX+4]

第一步:输入指令,看图2-6-12所示:
第二步:按F8观察,把内存地址0x003FF9E4写入ECX中,看图2-6-13:
第三步:按F8观察,把[ECX+4](0X003FF9E4+4)存储的数据写入EAX中,看图2-6-14:
向内存中写入数据:

MOV EDX,0x002EFA50

MOV DWORD PTR DS:[EDX+0xC],0x123456

第一步:输入指令;

第二步:按F8观察,把内存地址0x002EFA50写入EDX中;

第二步:按F8观察,把立即数0x00123456写入[EDX+0xC](0x002EFA50+0xC)中。

第四种形式:[register+register*{1,2,4,8}]

1、2、4、8我们称为比例因子(Scale Factor)。【有兴趣需要深入了解可以查阅Intel白皮书相关内容】

读取内存的值:

MOV EAX,0x0012FFC4

MOV ECX,0x2

MOV EDX,DWORD PTR DS:[EAX+ECX*4]

第一步:输入指令;

第二步:按F8观察,把内存地址0x0012FFC4 写入EAX中;

第三步:按F8观察,把立即数0x2(0x00000002)写入ECX中;

第四步:按F8观察,把[EAX+ECX*4](0x12FFC4+0x2*4)的值写入EDX中;

表示将2放入宽度为4字节(DWORD),内存地址为0x12FFC4+2*4即0x12FFCC中。

向内存中写入数据:

MOV EAX,0x12FFC4

MOV ECX,0x2

MOV DWORD PTR DS:[EAX+ECX*4],0x12345678

第一步:输入指令;

第二步:按F8观察,把内存地址0x0012FFC4 写入EAX中;

第三步:按F8观察,把立即数0x2(0x00000002)写入ECX中;

第四步:按F8观察,把立即数0x12345678写入[EAX+ECX*4](0x0012FFC4+0x2*4)中。

第五种形式:[register+register*{1,2,4,8}+立即数]

读取内存的值:

MOV EAX,0x0012FFC4

MOV ECX,0x2

MOV EDX,DWORD PTR DS:[EAX+ECX*4+1]

第一步:输入指令;

第二步:按F8观察,把内存地址0x0012FFC4 写入EAX中;

第三步:按F8观察,把立即数0x2(0x00000002)写入ECX中;

第四步:按F8观察,把[EAX+ECX*4+1](0x0012FFC4+0x2*4+1)写入EDX中。

向内存中写入数据:

MOV EAX,0x0012FFC4

MOV ECX,0x2

MOV DWORD PTR DS:[EAX+ECX*4+1],EDX

第一步:把内存地址0x0012FFC4 写入EAX中;

第二步:把立即数0x2(0x00000002)写入ECX中;

第三步:把EDX的数据写入[EAX+ECX*4+1](0x0012FFC4+0x2*4+1)中。

每一种地址形式都是有意义的,目前内存地址只有这五种形式,这五钟形式的通用格式为:[register+register*数+立即数]。

肯定会有人问:为什么只有五种表示方法,而且比例因子只能是1,2,4,8哪?极有可能的原因是(猜测):计算机只识别机器语言,所以我们要将内存地址的表示方法翻译成机器语言才能得到执行。组合越多,翻译起来越麻烦,cpu的技术员们只好订个规矩:只能使用五种表示方法,否则一律不识别。【有兴趣需要深入了解可以查阅Intel白皮书相关内容】

注:

1、如果我们所加的立即数为0xFFFFFFFF,那么运算结果极有可能会超过32位0xFFFFFFFF这个范围,计算机限宽,只会保留运算后32位。

2、如果乘的比例因子为0 的情况下,那么计算机会自动把0忽略,虽然运行结果与乘的比例因子1的结果一样,但是它是错误的运行结果。

3、切记比例因子只能是1、2、4、8。

思考一下:如果算出的内存地址结果超过32位会怎样?

内存地址的地址区分

当使用80386时,我们必须区分以下三种不同的地址:
逻辑地址:
机器语言指令仍用这种地址指定一个操作数的地址或一条指令的地址。这种寻址方式在Intel的分段结构中表现得尤为具体,它使得MS-DOS或Windows程序员把程序分为若干段。每个逻辑地址都由一个段和偏移量组成。
线性地址:
线性地址是一个32位的无符号整数,可以表达高达2^32(4GB)的地址。通常用16进制表示线性地址,其取值范围为0x00000000~0xffffffff。
物理地址:
也就是内存单元的实际地址,用于芯片级内存单元寻址。物理地址也由32位无符号整数表示。

内存地址表示方法

单位是MB,大的话或者用GB。1GB=1024MB
DDR是一种规格吧。
DDR(Dual Data Rate SDRSM)是最新的内存标准之一,在系统时钟触发沿的上、下沿都能进行数据传输,因此即使在133MHz的总线频率下,带宽也能达到约2.1GB/S,为SDRAM的的两倍左右。

C语言中什么叫内存地址

任何一个变量或者一个程序都得需要给它分配一块内存空间,而这块内存空间的标识号码就把它叫做内存地址。内存地址是用16进制数表示的。
例如:ABC8F40
有了内存地址我们就可以更好的针对指定的内存进行操作,修改等。
比如一个变量是1,我们可以修改存放这个变量的内存地址的里的内容,把他改为2。
内存地址的访问通过指针来实现。

怎么理解 【内存单元】和【内存地址】

内存单元是计算机存储数据的最小单位,以字节计数
计算机在使用存储器时,要给这些存储器进行编号,这个编号就是地址
地址最小的就是字节地址
但有时数据不是以字节形式进行读写的,比如int型就是连续的4个字节组成,计算机就使用地址附加说明的方式来访问数据,一次读写就是4个字节
这些地址连续编号,就形成一整片地址区,地址顺序增大,最小单位是字节,这个连续编号就是所谓线性地址。
内存地址就是内存单元的编号,方便访问读写用的。

内存地址的概念

系统 RAM 中的特定位置,通常以 十六进制的数字表示。
在8086的实模式下,把某一段寄存器左移4位,然后与地址ADDR相加后被直接送到内存总线上,这个相加后的地址就是内存单元的物理地址,而程序中的这个地址就叫逻辑地址(或叫虚地址)。在80386的 保护模式下,这个 逻辑地址不是被直接送到内存总线,而是被送到 内存管理单元(MMU)。MMU由一个或一组芯片组成,其功能是把 逻辑地址映射为物理地址,即进行 地址转换。
当使用80386时,我们必须区分以下三种不同的地址:
逻辑地址:
机器语言指令仍用这种地址指定一个操作数的地址或一条指令的地址。这种 寻址方式在Intel的分段结构中表现得尤为具体,它使得MS-DOS或Windows程序员把程序分为若干段。每个 逻辑地址都由一个段和 偏移量组成。
线性地址:
线性地址是一个32位的无符号整数,可以表达高达2^32(4GB)的地址。通常用16进制表示 线性地址,其取值范围为0x00000000~0xffffffff。
物理地址:
也就是内存单元的实际地址,用于芯片级内存单元 寻址。物理地址也由32位 无符号整数表示。
MMU是一种硬件电路,它包含两个部件,一个是分段部件,一个是分页部件,在本书中,我们把它们分别叫做分段机制和分页机制,以利于从逻辑的角度来理解硬件的实现机制。分段机制把一个逻辑地址转换为 线性地址;接着,分页机制把一个线性地址转换为 物理地址。

怎么知道游戏的内存地址

内存地址,其实电脑的每个操作都会在内存中先存储,然后经CPU处理后返回内存最终显现出来,而内存里有个内存地址,是为了区分各种不同数据的,而每个地址则相对应一个数据。
网络游戏中,数据也会先存放到内存中,然后进行处理,包括坐标、血量、MANA等,其实所有信息都是在内存中一一存放并等待处理。处理完毕后结果将会返回原来的地址中(当然也有返回到其他的)。
通过以上的解释,你应该知道,其实任何数据都是会下载到本地电脑上然后经过处理后再返回的(至于返回到网络和返回到本地就看数据的重要性了)包括网页的浏览等,任何在你电脑上可以看见的东西必定先存放到本地内存中或硬盘中等待处理后才会显现出来的。

如何找到内存地址

当使用80386时,我们必须区分以下三种不同的地址:   逻辑地址:   机器语言指令仍用这种地址指定一个操作数的地址或一条指令的地址。这种寻址方式在Intel的分段结构中表现得尤为具体,它使得MS-DOS或Windows程序员把程序分为若干段。每个逻辑地址都由一个段和偏移量组成。   线性地址:   线性地址是一个32位的无符号整数,可以表达高达232(4GB)的地址。通常用16进制表示线性地址,其取值范围为0x00000000~0xffffffff。   物理地址:   也就是内存单元的实际地址,用于芯片级内存单元寻址。物理地址也由32位无符号整数表示。   MMU是一种硬件电路,它包含两个部件,一个是分段部件,一个是分页部件,在本书中,我们把它们分别叫做分段机制和分页机制,以利于从逻辑的角度来理解硬件的实现机制。分段机制把一个逻辑地址转换为线性地址;接着,分页机制把一个线性地址转换为物理地址。