windows 物理内存获取
Posted 狂客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了windows 物理内存获取相关的知识,希望对你有一定的参考价值。
由于我一般使用的虚拟内存, 有时我们需要获取到物理内存中的数据(也就是内存条中的真实数据), 按理说是很简单,打开物理内存,读取就可以了.但似乎没这么简单:
- #include "windows.h"
- //定义相应的变量类型,见ntddk.h
- typedef LONG NTSTATUS;
- #define NT_SUCCESS(Status)((NTSTATUS)(Status) >= 0)
- #define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
- typedef struct _UNICODE_STRING
- {
- USHORT Length;
- USHORT MaximumLength;
- PWSTR Buffer;
- } UNICODE_STRING, *PUNICODE_STRING;
- typedef enum _SECTION_INHERIT
- {
- ViewShare = 1,
- ViewUnmap = 2
- } SECTION_INHERIT, *PSECTION_INHERIT;
- typedef struct _OBJECT_ATTRIBUTES
- {
- ULONG Length;
- HANDLE RootDirectory;
- PUNICODE_STRING ObjectName;
- ULONG Attributes;
- PVOID SecurityDescriptor;
- PVOID SecurityQualityOfService;
- } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
- // Interesting functions in NTDLL
- typedef NTSTATUS (WINAPI *ZwOpenSectionProc)
- (
- PHANDLE SectionHandle,
- DWORD DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes
- );
- typedef NTSTATUS (WINAPI *ZwMapViewOfSectionProc)
- (
- HANDLE SectionHandle,
- HANDLE ProcessHandle,
- PVOID *BaseAddress,
- ULONG ZeroBits,
- ULONG CommitSize,
- PLARGE_INTEGER SectionOffset,
- PULONG ViewSize,
- SECTION_INHERIT InheritDisposition,
- ULONG AllocationType,
- ULONG Protect
- );
- typedef NTSTATUS (WINAPI *ZwUnmapViewOfSectionProc)
- (
- HANDLE ProcessHandle,
- PVOID BaseAddress
- );
- typedef VOID (WINAPI *RtlInitUnicodeStringProc)
- (
- IN OUT PUNICODE_STRING DestinationString,
- IN PCWSTR SourceString
- );
- class PhysicalMemory
- {
- public:
- PhysicalMemory(DWORD dwDesiredAccess = SECTION_MAP_READ);
- ~PhysicalMemory();
- HANDLE OpenPhysicalMemory(DWORD dwDesiredAccess = SECTION_MAP_READ);
- VOID SetPhyscialMemoryAccess(HANDLE hPhysicalMemory,//由ZwOpenSection/NtOpenSection返回的物理内存句柄
- DWORD dwDesiredAccess//访问权限
- );
- BOOL ReadPhysicalMemory(OUT PVOID pvDataBuffer, //用于保存读取数据的缓冲区首地址
- IN DWORD dwAddress, //要读取的数据的首地址,要求4KB对齐
- IN DWORD dwLength //读取的长度
- );
- BOOL WritePhysicalMemory(IN PVOID pvDataBuffer, //用于保存要写入的数据的缓冲区首地址
- IN DWORD dwAddress, //要目标地址,要求4KB对齐
- IN DWORD dwLength //写入的长度
- );
- private:
- static BOOL InitPhysicalMemory() ;
- static void ExitPhysicalMemory() ;
- private:
- HANDLE m_hPhysicalMemory ;
- static HMODULE sm_hNtdllModule ;
- static ZwOpenSectionProc ZwOpenSection;
- static ZwMapViewOfSectionProc ZwMapViewOfSection;
- static ZwUnmapViewOfSectionProc ZwUnmapViewOfSection;
- static RtlInitUnicodeStringProc RtlInitUnicodeString;
- static PhysicalMemory * sm_pFirstObject;
- PhysicalMemory * m_pNextObject;
- }; ...
#include "windows.h" //定义相应的变量类型,见ntddk.h typedef LONG NTSTATUS; #define NT_SUCCESS(Status)((NTSTATUS)(Status) >= 0) #define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L) typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, *PUNICODE_STRING; typedef enum _SECTION_INHERIT { ViewShare = 1, ViewUnmap = 2 } SECTION_INHERIT, *PSECTION_INHERIT; typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService; } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; // Interesting functions in NTDLL typedef NTSTATUS (WINAPI *ZwOpenSectionProc) ( PHANDLE SectionHandle, DWORD DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes ); typedef NTSTATUS (WINAPI *ZwMapViewOfSectionProc) ( HANDLE SectionHandle, HANDLE ProcessHandle, PVOID *BaseAddress, ULONG ZeroBits, ULONG CommitSize, PLARGE_INTEGER SectionOffset, PULONG ViewSize, SECTION_INHERIT InheritDisposition, ULONG AllocationType, ULONG Protect ); typedef NTSTATUS (WINAPI *ZwUnmapViewOfSectionProc) ( HANDLE ProcessHandle, PVOID BaseAddress ); typedef VOID (WINAPI *RtlInitUnicodeStringProc) ( IN OUT PUNICODE_STRING DestinationString, IN PCWSTR SourceString ); class PhysicalMemory { public: PhysicalMemory(DWORD dwDesiredAccess = SECTION_MAP_READ); ~PhysicalMemory(); HANDLE OpenPhysicalMemory(DWORD dwDesiredAccess = SECTION_MAP_READ); VOID SetPhyscialMemoryAccess(HANDLE hPhysicalMemory,//由ZwOpenSection/NtOpenSection返回的物理内存句柄 DWORD dwDesiredAccess//访问权限 ); BOOL ReadPhysicalMemory(OUT PVOID pvDataBuffer, //用于保存读取数据的缓冲区首地址 IN DWORD dwAddress, //要读取的数据的首地址,要求4KB对齐 IN DWORD dwLength //读取的长度 ); BOOL WritePhysicalMemory(IN PVOID pvDataBuffer, //用于保存要写入的数据的缓冲区首地址 IN DWORD dwAddress, //要目标地址,要求4KB对齐 IN DWORD dwLength //写入的长度 ); private: static BOOL InitPhysicalMemory() ; static void ExitPhysicalMemory() ; private: HANDLE m_hPhysicalMemory ; static HMODULE sm_hNtdllModule ; static ZwOpenSectionProc ZwOpenSection; static ZwMapViewOfSectionProc ZwMapViewOfSection; static ZwUnmapViewOfSectionProc ZwUnmapViewOfSection; static RtlInitUnicodeStringProc RtlInitUnicodeString; static PhysicalMemory * sm_pFirstObject; PhysicalMemory * m_pNextObject; }; ...
- #include "windows.h"
- #include "Aclapi.h"
- #include "PhysicalMemory.h"
- //初始化OBJECT_ATTRIBUTES类型的变量
- #define InitializeObjectAttributes( p, n, a, r, s ) { (p)->Length = sizeof( OBJECT_ATTRIBUTES );(p)->RootDirectory = r; (p)->Attributes = a; (p)->ObjectName = n; (p)->SecurityDescriptor = s; (p)->SecurityQualityOfService = NULL; }
- // #define InitializeObjectAttributes( p, n, a, r, s ) { \\
- // (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \\
- // (p)->RootDirectory = r; \\
- // (p)->Attributes = a; \\
- // (p)->ObjectName = n; \\
- // (p)->SecurityDescriptor = s; \\
- // (p)->SecurityQualityOfService = NULL; \\
- //}
- // static variables of class PhysicalMemory
- PhysicalMemory* PhysicalMemory::sm_pFirstObject = NULL;
- HMODULE PhysicalMemory::sm_hNtdllModule = NULL;
- ZwOpenSectionProc PhysicalMemory::ZwOpenSection = NULL;
- ZwMapViewOfSectionProc PhysicalMemory::ZwMapViewOfSection = NULL;
- ZwUnmapViewOfSectionProc PhysicalMemory::ZwUnmapViewOfSection = NULL;
- RtlInitUnicodeStringProc PhysicalMemory::RtlInitUnicodeString = NULL;
- PhysicalMemory::PhysicalMemory(DWORD dwDesiredAccess)
- {
- if(sm_hNtdllModule == NULL)
- if(!InitPhysicalMemory())
- return;
- m_pNextObject = sm_pFirstObject;
- sm_pFirstObject = this;
- // 以下打开内核对象
- m_hPhysicalMemory = OpenPhysicalMemory(dwDesiredAccess);
- return ;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////
- PhysicalMemory::~PhysicalMemory()
- {
- if (m_hPhysicalMemory != NULL)
- {
- CloseHandle(m_hPhysicalMemory);
- m_hPhysicalMemory = NULL;
- }
- PhysicalMemory *pCurrentObject = sm_pFirstObject;
- if(pCurrentObject==this)
- sm_pFirstObject = sm_pFirstObject->m_pNextObject;
- else{
- while(pCurrentObject!=NULL){
- if(pCurrentObject->m_pNextObject==this){
- pCurrentObject->m_pNextObject=this->m_pNextObject;
- break;
- }
- pCurrentObject = pCurrentObject->m_pNextObject;
- }
- }
- if(sm_pFirstObject == NULL)
- ExitPhysicalMemory();
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////
- // initialize
- BOOL PhysicalMemory::InitPhysicalMemory()
- {
- if (!(sm_hNtdllModule = LoadLibrary("ntdll.dll")))
- {
- return FALSE;
- }
- // 以下从NTDLL获取我们需要的几个函数指针
- if (!(ZwOpenSection = (ZwOpenSectionProc)GetProcAddress(sm_hNtdllModule,"ZwOpenSection")))
- {
- return FALSE;
- }
- if (!(ZwMapViewOfSection = (ZwMapViewOfSectionProc)GetProcAddress(sm_hNtdllModule, "ZwMapViewOfSection")))
- {
- return FALSE;
- }
- if (!(ZwUnmapViewOfSection = (ZwUnmapViewOfSectionProc)GetProcAddress(sm_hNtdllModule, "ZwUnmapViewOfSection")))
- {
- return FALSE;
- }
- if (!(RtlInitUnicodeString = (RtlInitUnicodeStringProc)GetProcAddress(sm_hNtdllModule, "RtlInitUnicodeString")))
- {
- return FALSE;
- }
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////
- void PhysicalMemory::ExitPhysicalMemory()
- {
- if (sm_hNtdllModule != NULL)
- {
- // sm_pFirstObject->~PhysicalMemory();
- FreeLibrary(sm_hNtdllModule);
- }
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////
- HANDLE PhysicalMemory::OpenPhysicalMemory(DWORD dwDesiredAccess)
- {
- ULONG PhyDirectory;
- OSVERSIONINFO OSVersion;
- OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx (&OSVersion);
- if (5 != OSVersion.dwMajorVersion)
- return NULL;
- switch(OSVersion.dwMinorVersion)
- {
- case 0:
- PhyDirectory = 0x30000;
- break; //2k
- case 1:
- PhyDirectory = 0x39000;
- break; //xp
- default:
- return NULL;
- }
- WCHAR PhysicalMemoryName[] = L"\\\\Device\\\\PhysicalMemory";
- UNICODE_STRING PhysicalMemoryString;
- OBJECT_ATTRIBUTES attributes;
- RtlInitUnicodeString(&PhysicalMemoryString, PhysicalMemoryName);
- InitializeObjectAttributes(&attributes, &PhysicalMemoryString, 0, NULL, NULL);
- HANDLE hPhysicalMemory ;
- NTSTATUS status = ZwOpenSection(&hPhysicalMemory, dwDesiredAccess, &attributes );
- if(status == STATUS_ACCESS_DENIED)
- {
- status = ZwOpenSection(&hPhysicalMemory, READ_CONTROL|WRITE_DAC, &attributes);
- SetPhyscialMemoryAccess(hPhysicalMemory,dwDesiredAccess);
- CloseHandle(hPhysicalMemory);
- status = ZwOpenSection(&hPhysicalMemory, dwDesiredAccess, &attributes);
- }
- return ( NT_SUCCESS(status) ? hPhysicalMemory : NULL );
- // g_pMapPhysicalMemory = MapViewOfFile(g_hMPM, FILE_MAP_READ|FILE_MAP_WRITE, 0, PhyDirectory,
- //0x1000);
- // if( g_pMapPhysicalMemory == NULL )
- // return NULL;
- // return g_hMPM;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////
- VOID PhysicalMemory::SetPhyscialMemoryAccess(HANDLE hPhysicalMemory,//由ZwOpenSection/NtOpenSection返回的物理内存句柄
- DWORD dwDesiredAccess//访问权限
- )
- //设置物理内存的访问权限,成功返回TRUE,错误返回FALSE
- {
- PACL pDacl = NULL;
- PSECURITY_DESCRIPTOR pSD = NULL;
- PACL pNewDacl = NULL;
- DWORD dwRes = GetSecurityInfo(hPhysicalMemory, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL,
- NULL, &pDacl, NULL, &pSD);
- if(ERROR_SUCCESS != dwRes)
- {
- if(pSD)
- LocalFree(pSD);
- if(pNewDacl)
- LocalFree(pNewDacl);
- }
- EXPLICIT_ACCESS ea;
- RtlZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
- ea.grfAccessPermissions = SECTION_MAP_WRITE;
- ea.grfAccessMode = GRANT_ACCESS;
- ea.grfInheritance= NO_INHERITANCE;
- ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
- ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
- ea.Trustee.ptstrName = "CURRENT_USER";
- dwRes = SetEntriesInAcl(1,&ea,pDacl,&pNewDacl);
- if(ERROR_SUCCESS != dwRes)
- {
- if(pSD)
- LocalFree(pSD);
- if(pNewDacl)
- LocalFree(pNewDacl);
- }
- dwRes = SetSecurityInfo
- (hPhysicalMemory,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL);
- if(ERROR_SUCCESS != dwRes)
- {
- if(pSD)
- LocalFree(pSD);
- if(pNewDacl)
- LocalFree(pNewDacl);
- }
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////
- BOOL PhysicalMemory::ReadPhysicalMemory(OUT PVOID pvDataBuffer, //用于保存读取数据的缓冲区首地址
- IN DWORD dwAddress, //要读取的数据的首地址,要求4KB对齐
- IN DWORD dwLength //读取的长度
- )
- {
- if((dwAddress & 0x0fff ))//若地址不是4KB对齐,则返回
- {
- return FALSE;
- }
- if(m_hPhysicalMemory == NULL)
- {
- return FALSE;
- }
- DWORD dwOutLenth; // 输出长度,根据内存分页大小可能大于要求的长度
- PVOID pvVirtualAddress; // 映射的虚地址
- NTSTATUS status; // NTDLL函数返回的状态
- LARGE_INTEGER base; // 物理内存地址
- pvVirtualAddress = 0;
- dwOutLenth = dwLength;
- base.QuadPart = (ULONGLONG)(dwAddress);
- // 映射物理内存地址到当前进程的虚地址空间
- status = ZwMapViewOfSection(m_hPhysicalMemory,
- (HANDLE) -1,
- (PVOID *)&pvVirtualAddress,
- 0,
- dwLength,
- &base,
- &dwOutLenth,
- ViewShare,
- 0,
- PAGE_READONLY
- );
- if (status < 0)
- {
- return FALSE;
- }
- // 当前进程的虚地址空间中,复制数据到输出缓冲区
- memmove(pvDataBuffer,pvVirtualAddress, dwLength);
- // 完成访问,取消地址映射
- status = ZwUnmapViewOfSection((HANDLE)-1, (PVOID)pvVirtualAddress);
- return (status >= 0);
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////
- BOOL PhysicalMemory::WritePhysicalMemory(IN PVOID pvDataBuffer, //用于保存要写入的数据的缓冲区首地址
- IN DWORD dwAddress, //要目标地址,要求4KB对齐
- IN DWORD dwLength //写入的长度
- )
- {
- if((dwAddress & 0x0fff ))//若地址不是4KB对齐,则返回
- {
- return FALSE;
- }
- if(m_hPhysicalMemory == NULL)
- {
- return FALSE;
- }
- DWORD dwOutLenth; // 输出长度,根据内存分页大小可能大于要求的长度
- PVOID pvVirtualAddress; // 映射的虚地址
- NTSTATUS status; // NTDLL函数返回的状态
- LARGE_INTEGER base; // 物理内存地址
- pvVirtualAddress = 0;
- dwOutLenth = dwLength;
- base.QuadPart = (ULONGLONG)(dwAddress);
- // 映射物理内存地址到当前进程的虚地址空间
- status = ZwMapViewOfSection(m_hPhysicalMemory,
- (HANDLE) -1,
- (PVOID *)&pvVirtualAddress,
- 0,
- dwLength,
- &base,
- &dwOutLenth,
- ViewShare,
- ,0
- FILE_MAP_WRITE//PAGE_READWRITE
- );
- if (status < 0)
- {
- return FALSE;
- }
- // 当前进程的虚地址空间中,复制数据到输出缓冲区
- ::memmove(pvVirtualAddress, pvDataBuffer,dwLength);
- // 完成访问,取消地址映射
- status = ZwUnmapViewOfSection((HANDLE)-1, (PVOID)pvVirtualAddress);
- return (status >= 0);
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////
#include "windows.h" #include "Aclapi.h" #include "PhysicalMemory.h" //初始化OBJECT_ATTRIBUTES类型的变量 #define InitializeObjectAttributes( p, n, a, r, s ) { (p)->Length = sizeof( OBJECT_ATTRIBUTES );(p)->RootDirectory = r; (p)->Attributes = a; (p)->ObjectName = n; (p)->SecurityDescriptor = s; (p)->SecurityQualityOfService = NULL; } // #define InitializeObjectAttributes( p, n, a, r, s ) { \\ // (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \\ // (p)->RootDirectory = r; \\ // (p)->Attributes = a; \\ // (p)->ObjectName = n; \\ // (p)->SecurityDescriptor = s; \\ // (p)->SecurityQualityOfService = NULL; \\ //} // static variables of class PhysicalMemory PhysicalMemory* PhysicalMemory::sm_pFirstObject = NULL; HMODULE PhysicalMemory::sm_hNtdllModule = NULL; ZwOpenSectionProc PhysicalMemory::ZwOpenSection = NULL; ZwMapViewOfSectionProc PhysicalMemory::ZwMapViewOfSection = NULL; ZwUnmapViewOfSectionProc PhysicalMemory::ZwUnmapViewOfSection = NULL; RtlInitUnicodeStringProc PhysicalMemory::RtlInitUnicodeString = NULL; PhysicalMemory::PhysicalMemory(DWORD dwDesiredAccess) { if(sm_hNtdllModule == NULL) if(!InitPhysicalMemory()) return; m_pNextObject = sm_pFirstObject; sm_pFirstObject = this; // 以下打开内核对象 m_hPhysicalMemory = OpenPhysicalMemory(dwDesiredAccess); return ; } ///////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////// PhysicalMemory::~PhysicalMemory() { if (m_hPhysicalMemory != NULL) { CloseHandle(m_hPhysicalMemory); m_hPhysicalMemory = NULL; } PhysicalMemory *pCurrentObject = sm_pFirstObject; if(pCurrentObject==this) sm_pFirstObject = sm_pFirstObject->m_pNextObject; else{ while(pCurrentObject!=NULL){ if(pCurrentObject->m_pNextObject==this){ pCurrentObject->m_pNextObject=this->m_pNextObject; break; } pCurrentObject = pCurrentObject->m_pNextObject; } } if(sm_pFirstObject == NULL) ExitPhysicalMemory(); } ///////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////// // initialize BOOL PhysicalMemory::InitPhysicalMemory() { if (!(sm_hNtdllModule = LoadLibrary("ntdll.dll"))) { return FALSE; } // 以下从NTDLL获取我们需要的几个函数指针 if (!(ZwOpenSection = (ZwOpenSectionProc)GetProcAddress(sm_hNtdllModule,"ZwOpenSection"))) { return FALSE; } if (!(ZwMapViewOfSection = (ZwMapViewOfSectionProc)GetProcAddress(sm_hNtdllModule, "ZwMapViewOfSection"))) { return FALSE; } if (!(ZwUnmapViewOfSection = (ZwUnmapViewOfSectionProc)GetProcAddress(sm_hNtdllModule, "ZwUnmapViewOfSection"))) { return FALSE; } if (!(RtlInitUnicodeString = (RtlInitUnicodeStringProc)GetProcAddress(sm_hNtdllModule, "RtlInitUnicodeString"))) { return FALSE; } return TRUE; } ///////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////// void PhysicalMemory::ExitPhysicalMemory() { if (sm_hNtdllModule != NULL) { // sm_pFirstObject->~PhysicalMemory(); FreeLibrary(sm_hNtdllModule); } } ///////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////// HANDLE PhysicalMemory::OpenPhysicalMemory(DWORD dwDesiredAccess) { ULONG PhyDirectory; OSVERSIONINFO OSVersion; OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx (&OSVersion); if (5 != OSVersion.dwMajorVersion) return NULL; switch(OSVersion.dwMinorVersion) { case 0: PhyDirectory = 0x30000; break; //2k case 1: PhyDirectory = 0x39000; break; //xp default: return NULL; } WCHAR PhysicalMemoryName[] = L"\\\\Device\\\\PhysicalMemory"; UNICODE_STRING PhysicalMemoryString; OBJECT_ATTRIBUTES attributes; RtlInitUnicodeString(&PhysicalMemoryString, PhysicalMemoryName); InitializeObjectAttributes(&attributes, &PhysicalMemoryString, 0, NULL, NULL); HANDLE hPhysicalMemory ; NTSTATUS status = ZwOpenSection(&hPhysicalMemory, dwDesiredAccess, &attributes ); if(status == STATUS_ACCESS_DENIED) { status = ZwOpenSection(&hPhysicalMemory, READ_CONTROL|WRITE_DAC, &attributes); SetPhyscialMemoryAccess(hPhysicalMemory,dwDesiredAccess); CloseHandle(hPhysicalMemory); status = ZwOpenSection(&hPhysicalMemory, dwDesiredAccess, &attributes); } return ( NT_SUCCESS(status) ? hPhysicalMemory : NULL ); // g_pMapPhysicalMemory = MapViewOfFile(g_hMPM, FILE_MAP_READ|FILE_MAP_WRITE, 0, PhyDirectory, //0x1000); // if( g_pMapPhysicalMemory == NULL ) // return NULL; // return g_hMPM; } ///////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////// VOID PhysicalMemory::SetPhyscialMemoryAccess(HANDLE hPhysicalMemory,//由ZwOpenSection/NtOpenSection返回的物理内存句柄 DWORD dwDesiredAccess//访问权限 ) //设置物理内存的访问权限,成功返回TRUE,错误返回FALSE { PACL pDacl = NULL; PSECURITY_DESCRIPTOR pSD = NULL; PACL pNewDacl = NULL; DWORD dwRes = GetSecurityInfo(hPhysicalMemory, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDacl, NULL, &pSD); if(ERROR_SUCCESS != dwRes) { if(pSD) LocalFree(pSD); if(pNewDacl) LocalFree(pNewDacl); } EXPLICIT_ACCESS ea; RtlZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); ea.grfAccessPermissions = SECTION_MAP_WRITE; ea.grfAccessMode = GRANT_ACCESS; ea.grfInheritance= NO_INHERITANCE; ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME; ea.Trustee.TrusteeType = TRUSTEE_IS_USER; ea.Trustee.ptstrName = "CURRENT_USER"; dwRes = SetEntriesInAcl(1,&ea,pDacl,&pNewDacl); if(ERROR_SUCCESS != dwRes) { if(pSD) LocalFree(pSD); if(pNewDacl) LocalFree(pNewDacl); } dwRes = SetSecurityInfo (hPhysicalMemory,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL); if(ERROR_SUCCESS != dwRes) { if(pSD) LocalFree(pSD); if(pNewDacl) LocalFree(pNewDacl); } } ///////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////// BOOL PhysicalMemory::ReadPhysicalMemory(OUT PVOID pvDataBuffer, //用于保存读取数据的缓冲区首地址 IN DWORD dwAddress, //要读取的数据的首地址,要求4KB对齐 IN DWORD dwLength //读取的长度 ) { if((dwAddress & 0x0fff ))//若地址不是4KB对齐,则返回 { return FALSE; } if(m_hPhysicalMemory == NULL) { return FALSE; } DWORD dwOutLenth; // 输出长度,根据内存分页大小可能大于要求的长度 PVOID pvVirtualAddress; // 映射的虚地址 NTSTATUS status; // NTDLL函数返回的状态 LARGE_INTEGER base; // 物理内存地址 pvVirtualAddress = 0; dwOutLenth = dwLength; base.QuadPart = (ULONGLONG)(dwAddress); // 映射物理内存地址到当前进程的虚地址空间 status = ZwMapViewOfSection(m_hPhysicalMemory, (HANDLE) -1, (PVOID *)&pvVirtualAddress, 0, dwLength, &base, &dwOutLenth, ViewShare, 0, PAGE_READONLY ); if (status < 0) { return FALSE; } // 当前进程的虚地址空间中,复制数据到输出缓冲区 memmove(pvDataBuffer,pvVirtualAddress, dwLength); // 完成访问,取消地址映射 status = ZwUnmapViewOfSection((HANDLE)-1, (PVOID)pvVirtualAddress); return (status >= 0); } ///////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////// BOOL PhysicalMemory::WritePhysicalMemory(IN PVOID pvDataBuffer, //用于保存要写入的数据的缓冲区首地址 IN DWORD dwAddress, //要目标地址,要求4KB对齐 IN DWORD dwLength //写入的长度 ) { if((dwAddress & 0x0fff ))//若地址不是4KB对齐,则返回 { return FALSE; } if(m_hPhysicalMemory == NULL) { return FALSE; } DWORD dwOutLenth; // 输出长度,根据内存分页大小可能大于要求的长度 PVOID pvVirtualAddress; // 映射的虚地址 NTSTATUS status; // NTDLL函数返回的状态 LARGE_INTEGER base; // 物理内存地址 pvVirtualAddress = 0; dwOutLenth = dwLength; base.QuadPart = (ULONGLONG)(dwAddress); // 映射物理内存地址到当前进程的虚地址空间 status = ZwMapViewOfSection(m_h以上是关于windows 物理内存获取的主要内容,如果未能解决你的问题,请参考以下文章
如何像 Windows 任务管理器中显示的那样获得可用的物理内存