`
java-mans
  • 浏览: 11432708 次
文章分类
社区版块
存档分类
最新评论

《Windows核心编程》の内存操作和内存信息管理

 
阅读更多

=======================内存操作函数========================

1)复制内存使用函数CopyMemory:(注意:源内存区域与目的地址区域不能重叠)

void CopyMemory(

__in PVOID Destination, //目的地址

__in const VOID *Source, //源地址

__in SIZE_T Length //要复制的数据的字节大小,注意Destination必须足够大来容纳Length长的数据

);

下面的实例是更安全地使用CopyMemory的方法:

#include <windows.h>

#include <tchar.h>

#include <stdio.h>

#define BUFFER_SIZE 1024

#define COPY_SIZE 512

/*

* ASCECopyMemory--A Wrapper for CopyMemory

* buf--destination buffer

* pbData--source buffer

* cbData--size of block to copy, in bytes

* bufsize--size of the destination buffer

*/

void ASCECopyMemory(TCHAR *buf, TCHAR *pbData, SIZE_T cbData, SIZE_T bufsize)

{

CopyMemory(buf, pbData, min(cbData, bufsize));

}

int main()

{

TCHAR buf[BUFFER_SIZE] = TEXT("This is the destination");

TCHAR pbData[BUFFER_SIZE] = TEXT("This is the source");

ASCECopyMemory(buf, pbData, COPY_SIZE*sizeof(TCHAR), BUFFER_SIZE*sizeof(TCHAR));

_tprintf(TEXT("Destination buffer contents : %s/n"), buf);

system("pause");

return 0;

}

2)填充内存使用函数FillMemory

void FillMemory(

[out] PVOID Destination, //需要填充的内存地址

[in] SIZE_T Length, //需要填充的字节大小

[in] BYTE Fill //需要填充的值

);

3)复制内存还可以使用函数MoveMemory:(注意:源内存区域可以和目的内存区域重叠)

void MoveMemory(

__in PVOID Destination, //目的地址

__in const VOID *Source, //源地址

__in SIZE_T Length //复制的数据的字节大小,注意Destination必须足够大来容纳Length长的数据

);

下面的实例是更安全地使用MoveMemory的方法:

#include <windows.h>

#include <tchar.h>

#include <stdio.h>

#define BUFFER_SIZE 1024

#define COPY_SIZE 512

/*

* ASCEMoveMemory--A Wrapper for MoveMemory

* buf--destination buffer

* pbData--source buffer

* cbData--size of block to copy, in bytes

*/

void ASCEMoveMemory(TCHAR *buf, TCHAR *pbData, SIZE_T cbData)

{

MoveMemory(buf, pbData, min(cbData, strlen(buf)));

}

int main()

{

TCHAR buf[BUFFER_SIZE] = TEXT("This is the destination");

TCHAR pbData[BUFFER_SIZE] = TEXT("This is the source");

ASCEMoveMemory(buf, pbData, COPY_SIZE*sizeof(TCHAR));

_tprintf(TEXT("Destination buffer contents : %s/n"), buf);

system("pause");

return 0;

}

4)将指定内存清零使用函数ZeroMemory

void ZeroMemory(

[in] PVOID Destination, //要清零的内存地址

[in] SIZE_T Length //Destination内存区域的字节大小

);

在有些情况下,为了避免编译器优化带来的副作用,我们可以使用SecureZeroMemory函数:

PVOID SecureZeroMemory(

__in PVOID ptr, //要清零的内存地址

__in SIZE_T cnt //内存区域的字节大小

);

下面的代码片段最好使用SecureZeroMemory,而不是ZeroMemory

WCHAR szPassword[MAX_PATH];

//Retrieve the password

if(GetPasswordFromUser(szPassword, MAX_PATH))

UsePassword(szPassword);

//Clear the password from memory

SecureZeroMemory(szPassword, sizeof(szPassword));

上面的代码如果使用ZeroMemory,那么编译器可能会优化该函数的调用,使得szPassword中的密码一直留着应用程序的堆栈中,而不是清零,这显然会造成安全问题。

====================获得当前系统内存使用情况====================

当前系统内存使用情况包括物理内存、可使用的物理内存、总虚拟内存、可用虚拟内存、磁盘上的页面缓存文件大小、可使用的缓存文件大小等。

详见:Windows核心编程》---获得内存的当前状态のGlobalMemoryStatusEx

http://blog.csdn.net/ACE1985/archive/2010/07/24/5761972.aspx

======================判断内存指针可用性======================

判断内存指针的可用性,是通过判断指针所指向的虚拟内存页面的状态和属性来实现的。Windows提供了相关的API。相同的功能也可以通过获取虚拟内存页面属性来判断。

1IsBadCodePtr

判断调用进程是否拥有对指定地址内存的读操作权限,函数原型如下:

BOOL WINAPI IsBadCodePtr(

__in FARPROC lpfn //指定的内存地址

);

返回值表示当前进程是否拥有对该地址内存的读取权限。

2IsBadReadPtr

判断调用进程是否拥有对指定地址段内存的读操作权限,函数原型如下:

BOOL WINAPI IsBadReadPtr(

__in const VOID *lp, //指定起始内存地址

__in UINT_PTR ucb //从起始内存地址开始的内存块长度

);

返回值表示当前进程是否拥有对该段地址内存块的读取权限。

3IsBadStringPtr

判断调用进程是否拥有对指定字符串指针的读取权限,函数原型如下:

BOOL WINAPI IsBadStringPtr(

__in LPCTSTR lpsz, //指向字符串的指针

__in UINT_PTR ucchMax //读取字符串的最大长度

);

返回值表示当前进程是否拥有字符串指针指向的字符串的读取权限。

4IsBadWritePtr

BOOL WINAPI IsBadWritePtr(

__in LPVOID lp, //指向起始内存地址

__in UINT_PTR ucb //从起始内存地址开始的内存块长度

);

返回值表示当前进程是否拥有该段地址内存块的写入权限。

分享到:
评论

相关推荐

    Windows应用程序捆绑核心编程光盘代码

    1.2 内存管理概述 1 1.2.1 虚拟内存 1 1.2.2 CPU工作模式 2 1.2.3 逻辑、线性和物理地址 3 1.2.4 存储器分页管理机制 3 1.2.5 线性地址到物理地址的转换 4 1.3 虚拟内存访问 5 1.3.1 获取系统信息 5 1.3.2 ...

    精通WindowsAPI 函数 接口 编程实例

    5.5 内存操作与内存信息管理 144 5.5.1 复制、填充、移动、清零内存块、防止缓冲区溢出 144 5.5.2 获得当前系统内存使用情况 146 5.5.3 判断内存指针的可用性 147 5.6 各种内存分配方式的关系与比较 148 ...

    精通Windows.API-函数、接口、编程实例.pdf

    5.5 内存操作与内存信息管理 144 5.5.1 复制、填充、移动、清零内存块、防止缓冲区溢出 144 5.5.2 获得当前系统内存使用情况 146 5.5.3 判断内存指针的可用性 147 5.6 各种内存分配方式的关系与比较 148 ...

    windows驱动开发技术详解-part2

    用WinDBG和VMWARE软件对驱动进行源码级调试,深入Windows操作系统的底层和内核,透析Windows驱动 开发的本质。 本书是作者结合教学和科研实践经验编写而成的,不仅详细介绍了Windows内核原理,而且介绍了编程技 巧...

    Windows驱动开发技术详解的光盘-part1

    本书是作者结合教学和科研实践经验编写而成的,不仅详细介绍了Windows内核原理,而且介绍了编程技巧和应用实例,兼顾了在校研究生和工程技术人员的实际需求,对教学、生产和科研有现实的指导意义,是一本值得推荐的...

    C/C++-数据结构-教室管理系统-课程设计-大学生课设

    程序拥有权限控制,分为管理员和普通用户。 管理员需求:查看某栋楼教室的概要信息、每个教室的详细信息(包括教室 基本信息、预约情况、上课情况)、修改某教室基本信息、增加教室、删除教室、 增加某教室上课情况...

Global site tag (gtag.js) - Google Analytics