memcpy函数拷贝时候遇到的虚拟地址与物理地址问题

 使用memcpy拷贝的时候,原地址、目的地址、拷贝长度均有:0x71234567,0x345343,200,但是就是拷贝出现异常,找了好久,由于0x72333333是随意使用的一个地址,而它是虚拟地址,所以导致从虚拟地址中拷贝数据到实际分配的物理地址中出现异常,这个如何解决呢?我只想到了将0x71234567变成自己定义分配了内存的数组之类的内存地址,也就是让实际地址中的数据拷贝到实际地址中,这样就没问题,但是想要随机读取一个内存 的数据如何做呢?难道是使用ReadProcessMemory()吗?或者有什么方法将虚拟地址定向到的物理地址得到?希望知道的大侠可以留言。


一些资料:

32|64位的系统|CPU

        操作系统运行在硬件CPU上,32位操作系统运行于32位CPU上,64位操作系统运行于64位CPU上;目前没有真正的64位CPU。

32位CPU一次只能操作32位二进制数;位数多CPU设计越复杂,软件设计越简单。

       软件的进程运行于32位系统上,其寻址位也是32位,能表示的空间是232=4G,范围从0x0000 0000~0xFFFF FFFF。

·        NULL指针分区

范围:0x0000 0000~0x0000 FFFF

作用:保护内存非法访问

例子:分配内存时,如果由于某种原因分配不成功,则返回空指针0x0000 0000;当用户继续使用比如改写数据时,系统将因为发生访问违规而退出。

        那么,为什么需要那么大的区域呢,一个地址值不就行了吗?我在想,是不是因为不让8或16位的程序运行于32位的系统上呢?!因为NULL分区刚好范围是16的进程空间。

·        独享用户分区

范围:0x0001 0000~0x7FFE FFFF

作用:进程只能读取或访问这个范围的虚拟地址;超越这个范围的行为都会产生违规退出。

例子:

        程序的二进制代码中所用的地址大部分将在这个范围,所有exe和dll文件都加载到这个。每个进程将近2G的空间是独享的。

注意:如果在boot.ini上设置了/3G,这个区域的范围从2G扩大为3G:0x0001 0000~0xBFFE FFFF。

·        共享内核分区

范围:0x8000 0000~0xFFFF FFFF

作用:这个空间是供操作系统内核代码、设备驱动程序、设备I/O高速缓存、非页面内存池的分配、进程目表和页表等。

例子:

       这段地址各进程是可以共享的。                                                                                                                                         

注意:如果在boot.ini上设置了/3G,这个区域的范围从2G缩小为1G:0xC000 0000~0xFFFF FFFF。

       通过以上分析,可以知道,如果系统有n个进程,它所需的虚拟空间是:2G*n+2G (内核只需2G的共享空间)。
之前遇到问题的是使用的google 的test出错,但是直接使用C就没有问题:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned char buffer[20];

void main()
{
	unsigned char *pch;
	int i;
	pch = (unsigned char *)0x7c8168c6;
	memcpy(buffer, pch, 20);

	for (i = 0; i < 20; i++)
		printf("%X", buffer[i]);
}

后来发现直接这样写还有几点需要注意的:

XP系统下可以读取到数据,但是Win7就不可以,而且Win7使用XP虚拟机也不能获取,程序直接崩溃;当memcpy 地址 0~0x0000ffff的时候,由于该地址是内存保护的,所以自然不能读取了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值