欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

windows下32位汇编语言学习笔记 第十章 内存管理部分 1

windows下32位汇编语言学习笔记 第十章 内存管理部分 1

windows下32位汇编语言学习笔记 第十章 内存管理部分

前面5 6 7 8 9章都是介绍windows界面设计有关的内容,这些内容大概看一下就可以,等需要用的时候再回过头来查。一次性记住的可能性不大。这些章节也没有什么难度,自己看看就可以。
我所关心的还是windows系统相关知识,说道界面设置,对RC资源再熟悉做界面还是Delphi,C++builder比较快速。
本章介绍了很多windows下关于内存管理的函数,书上有句话说的很好,不要去深究这些函数分配的内存具体放在内存寻址空间的什么地方,只需要知道什么时候该用什么类型的内存管理函数就可以。

Global标准内存管理
GlobalAlloc函数使用GMEM_MOVEABLE参数返回的是个内存句柄,内容是一个地址,这个地址才是可以使用的内存块。比如:
PVOID lpMem =  GlobalAlloc(GHND, 1000);
现在lpMem指向的内容是一个地址,必须通过GlobalLock(lpMem)函数返回这个指针才能使用。
实际上GMEM_MOVEABLE参数和GMEM_FIXED区别就是前者必须要经过GlobalLock才能使用,后者则通过返回的指针直接使用。
关于什么时候可移动,我没法测,不知道windows在什么情况下去移动这块内存。
GlobalAlloc分配内存是紧凑的,就是说分配的多个内存空间可以放在一个内存页面里,只要能放的下。

Heap堆内存管理
Heap内存管理非配基本上和Global的用法相当,一般的用法都是GetProcessHeap得到进程默认堆,然后HeapAlloc分配。

虚拟内存管理
有一点必须知道,VirtualAlloc,所分配的空间都是页对齐的,分配1字节的内存空间也会占用4096字节的一个内存页,再次使用VirtualAlloc分配内存会从新的一页开始。
每个虚拟内存页面有三种状态:Free:自由状态,Commit:提交状态,Reserve:保留状态。
八种保护属性:
PAGE_NOACCESS,PAGE_READONLY,PAGE_READWRITE,PAGE_EXECUTE,PAGE_EXECUTE_READ,PAGE_EXECUTE_READWRITE,PAGE_EXECUTE_WRITECOPY,PAGE_WRITECOPY
这八种属性在第一章的笔记里有介绍。
虚拟内存页面还有4种类型
Free:空闲,没有提交也没有使用的。Private:私有,该区域的虚拟地址和系统页文件关联。Image:映像,改区域的虚拟内存地址和exe文件或dll文件关联。
Mapped:映射,改区域的内存和其他硬盘上的文件关联。
这些页面的属性,类型,状态,就是80386保护模式下,windows系统管理虚拟内存的机制。
虚拟内存管理函数中提供了几个可以操作其他进程虚拟地址的函数。
LPVOID VirtualAllocEx(HANDLE hProess,LPVOID lpAddress,SIZE_T dwSize,DWORD flProtect)
这个函数可以在别的进程空间保留或者提交一块内存。比如DLL的远程注入就是使用这个函数在目标进程开辟一块虚拟内存空间,将要注入的dll名通过WriteProcessMemory函数写进目标进程的虚拟内存空间,然后再通过CreateRemoteThread函数运行LoadLibraryA加载写入的dll文件,LoadLibraryA函数位于kernel32.dll中,由于每个进程运行都会加载这个dll,所以LoadLibraryA函数在不同进程中的地址是一样的,可以直接再目标进程使用。
比如下面的例子:
// 向目标进程地址空间写入DLL名称
DWORD dwSize, dwWritten;
dwSize = lstrlenA( lpszDll ) + 1;
LPVOID lpBuf = VirtualAllocEx( hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE );
if ( NULL == lpBuf )
{
     CloseHandle( hProcess );
    // 失败处理
}
if ( WriteProcessMemory( hProcess, lpBuf, (LPVOID)lpszDll, dwSize, &dwWritten ) )
{
    // 要写入字节数与实际写入字节数不相等,仍属失败
    if ( dwWritten != dwSize )
     {
         VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT );
         CloseHandle( hProcess );
        // 失败处理
     }
}
else
{
     CloseHandle( hProcess );
    // 失败处理
}
// 使目标进程调用LoadLibrary,加载DLL
DWORD dwID;
LPVOID pFunc = LoadLibraryA;
HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, lpBuf, 0, &dwID );
___________________________________________________________________________________________________________________________

DWORD VirtualQuery(PVOID pvAddress,PMEMORY_BASIC_INFORMATION lpBuffer,SIZE_T dwLength);
这个函数可以用来查询pvAddress指定的内存空间的状态State,类型Type,和保护属性Protect,地址空间的属性保存在MEMORY_BASIC_INFO结构中。用这个函数,就可以写一个和Cheat Engine里一样的查看内存Region的程序。
下面这个小程序就是使用VirtualQuery函数实现查询当前进程中的内存区域状态。实现的功能比Cheat Engine里的还多了可以知道哪里的内存是进程堆,那里映射,映像了什么文件。
部分参考windows核心编程第10章的内容

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功