由于我一般使用的虚拟内存, 有时我们需要获取到物理内存中的数据(也就是内存条中的真实数据), 按理说是很简单,打开物理内存,读取就可以了.但似乎没这么简单:

  1. #include "windows.h"
  2. //定义相应的变量类型,见ntddk.h
  3. typedef LONG    NTSTATUS;
  4. #define NT_SUCCESS(Status)((NTSTATUS)(Status) >= 0)
  5. #define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
  6. typedef struct _UNICODE_STRING
  7. {
  8. USHORT Length;
  9. USHORT MaximumLength;
  10. PWSTR Buffer;
  11. } UNICODE_STRING, *PUNICODE_STRING;
  12. typedef enum _SECTION_INHERIT
  13. {
  14. ViewShare = 1,
  15. ViewUnmap = 2
  16. } SECTION_INHERIT, *PSECTION_INHERIT;
  17. typedef struct _OBJECT_ATTRIBUTES
  18. {
  19. ULONG Length;
  20. HANDLE RootDirectory;
  21. PUNICODE_STRING ObjectName;
  22. ULONG Attributes;
  23. PVOID SecurityDescriptor;
  24. PVOID SecurityQualityOfService;
  25. } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
  26. // Interesting functions in NTDLL
  27. typedef NTSTATUS (WINAPI *ZwOpenSectionProc)
  28. (
  29. PHANDLE SectionHandle,
  30. DWORD DesiredAccess,
  31. POBJECT_ATTRIBUTES ObjectAttributes
  32. );
  33. typedef NTSTATUS (WINAPI *ZwMapViewOfSectionProc)
  34. (
  35. HANDLE SectionHandle,
  36. HANDLE ProcessHandle,
  37. PVOID *BaseAddress,
  38. ULONG ZeroBits,
  39. ULONG CommitSize,
  40. PLARGE_INTEGER SectionOffset,
  41. PULONG ViewSize,
  42. SECTION_INHERIT InheritDisposition,
  43. ULONG AllocationType,
  44. ULONG Protect
  45. );
  46. typedef NTSTATUS (WINAPI *ZwUnmapViewOfSectionProc)
  47. (
  48. HANDLE ProcessHandle,
  49. PVOID BaseAddress
  50. );
  51. typedef VOID (WINAPI *RtlInitUnicodeStringProc)
  52. (
  53. IN OUT PUNICODE_STRING DestinationString,
  54. IN PCWSTR SourceString
  55. );
  56. class PhysicalMemory
  57. {
  58. public:
  59. PhysicalMemory(DWORD dwDesiredAccess = SECTION_MAP_READ);
  60. ~PhysicalMemory();
  61. HANDLE OpenPhysicalMemory(DWORD dwDesiredAccess = SECTION_MAP_READ);
  62. VOID SetPhyscialMemoryAccess(HANDLE hPhysicalMemory,//由ZwOpenSection/NtOpenSection返回的物理内存句柄
  63. DWORD dwDesiredAccess//访问权限
  64. );
  65. BOOL ReadPhysicalMemory(OUT PVOID pvDataBuffer, //用于保存读取数据的缓冲区首地址
  66. IN DWORD dwAddress, //要读取的数据的首地址,要求4KB对齐
  67. IN DWORD dwLength //读取的长度
  68. );
  69. BOOL WritePhysicalMemory(IN PVOID pvDataBuffer, //用于保存要写入的数据的缓冲区首地址
  70. IN DWORD dwAddress, //要目标地址,要求4KB对齐
  71. IN DWORD dwLength //写入的长度
  72. );
  73. private:
  74. static BOOL InitPhysicalMemory() ;
  75. static void ExitPhysicalMemory() ;
  76. private:
  77. HANDLE m_hPhysicalMemory ;
  78. static HMODULE sm_hNtdllModule ;
  79. static ZwOpenSectionProc ZwOpenSection;
  80. static ZwMapViewOfSectionProc ZwMapViewOfSection;
  81. static ZwUnmapViewOfSectionProc ZwUnmapViewOfSection;
  82. static RtlInitUnicodeStringProc RtlInitUnicodeString;
  83. static PhysicalMemory * sm_pFirstObject;
  84. PhysicalMemory * m_pNextObject;
  85. }; ...
#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;
}; ...
  1. #include "windows.h"
  2. #include "Aclapi.h"
  3. #include "PhysicalMemory.h"
  4. //初始化OBJECT_ATTRIBUTES类型的变量
  5. #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; }
  6. // #define InitializeObjectAttributes( p, n, a, r, s ) { \
  7. //  (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
  8. //    (p)->RootDirectory = r; \
  9. //   (p)->Attributes = a; \
  10. //    (p)->ObjectName = n; \
  11. //    (p)->SecurityDescriptor = s; \
  12. //    (p)->SecurityQualityOfService = NULL; \
  13. //}
  14. // static variables of class PhysicalMemory
  15. PhysicalMemory* PhysicalMemory::sm_pFirstObject = NULL;
  16. HMODULE PhysicalMemory::sm_hNtdllModule  = NULL;
  17. ZwOpenSectionProc PhysicalMemory::ZwOpenSection = NULL;
  18. ZwMapViewOfSectionProc PhysicalMemory::ZwMapViewOfSection = NULL;
  19. ZwUnmapViewOfSectionProc PhysicalMemory::ZwUnmapViewOfSection = NULL;
  20. RtlInitUnicodeStringProc PhysicalMemory::RtlInitUnicodeString = NULL;
  21. PhysicalMemory::PhysicalMemory(DWORD dwDesiredAccess)
  22. {
  23. if(sm_hNtdllModule == NULL)
  24. if(!InitPhysicalMemory())
  25. return;
  26. m_pNextObject = sm_pFirstObject;
  27. sm_pFirstObject = this;
  28. // 以下打开内核对象
  29. m_hPhysicalMemory = OpenPhysicalMemory(dwDesiredAccess);
  30. return ;
  31. }
  32. /////////////////////////////////////////////////////////////////////////////////////////////
  33. /////////////////////////////////////////////////////////////////////////////////////////////
  34. PhysicalMemory::~PhysicalMemory()
  35. {
  36. if (m_hPhysicalMemory != NULL)
  37. {
  38. CloseHandle(m_hPhysicalMemory);
  39. m_hPhysicalMemory = NULL;
  40. }
  41. PhysicalMemory *pCurrentObject = sm_pFirstObject;
  42. if(pCurrentObject==this)
  43. sm_pFirstObject = sm_pFirstObject->m_pNextObject;
  44. else{
  45. while(pCurrentObject!=NULL){
  46. if(pCurrentObject->m_pNextObject==this){
  47. pCurrentObject->m_pNextObject=this->m_pNextObject;
  48. break;
  49. }
  50. pCurrentObject = pCurrentObject->m_pNextObject;
  51. }
  52. }
  53. if(sm_pFirstObject == NULL)
  54. ExitPhysicalMemory();
  55. }
  56. /////////////////////////////////////////////////////////////////////////////////////////////
  57. /////////////////////////////////////////////////////////////////////////////////////////////
  58. // initialize
  59. BOOL PhysicalMemory::InitPhysicalMemory()
  60. {
  61. if (!(sm_hNtdllModule = LoadLibrary("ntdll.dll")))
  62. {
  63. return FALSE;
  64. }
  65. // 以下从NTDLL获取我们需要的几个函数指针
  66. if (!(ZwOpenSection = (ZwOpenSectionProc)GetProcAddress(sm_hNtdllModule,"ZwOpenSection")))
  67. {
  68. return FALSE;
  69. }
  70. if (!(ZwMapViewOfSection = (ZwMapViewOfSectionProc)GetProcAddress(sm_hNtdllModule, "ZwMapViewOfSection")))
  71. {
  72. return FALSE;
  73. }
  74. if (!(ZwUnmapViewOfSection = (ZwUnmapViewOfSectionProc)GetProcAddress(sm_hNtdllModule, "ZwUnmapViewOfSection")))
  75. {
  76. return FALSE;
  77. }
  78. if (!(RtlInitUnicodeString = (RtlInitUnicodeStringProc)GetProcAddress(sm_hNtdllModule, "RtlInitUnicodeString")))
  79. {
  80. return FALSE;
  81. }
  82. return TRUE;
  83. }
  84. /////////////////////////////////////////////////////////////////////////////////////////////
  85. /////////////////////////////////////////////////////////////////////////////////////////////
  86. void PhysicalMemory::ExitPhysicalMemory()
  87. {
  88. if (sm_hNtdllModule != NULL)
  89. {
  90. //      sm_pFirstObject->~PhysicalMemory();
  91. FreeLibrary(sm_hNtdllModule);
  92. }
  93. }
  94. /////////////////////////////////////////////////////////////////////////////////////////////
  95. /////////////////////////////////////////////////////////////////////////////////////////////
  96. HANDLE PhysicalMemory::OpenPhysicalMemory(DWORD dwDesiredAccess)
  97. {
  98. ULONG PhyDirectory;
  99. OSVERSIONINFO OSVersion;
  100. OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  101. GetVersionEx (&OSVersion);
  102. if (5 != OSVersion.dwMajorVersion)
  103. return NULL;
  104. switch(OSVersion.dwMinorVersion)
  105. {
  106. case 0:
  107. PhyDirectory = 0x30000;
  108. break; //2k
  109. case 1:
  110. PhyDirectory = 0x39000;
  111. break; //xp
  112. default:
  113. return NULL;
  114. }
  115. WCHAR PhysicalMemoryName[] = L"\\Device\\PhysicalMemory";
  116. UNICODE_STRING PhysicalMemoryString;
  117. OBJECT_ATTRIBUTES attributes;
  118. RtlInitUnicodeString(&PhysicalMemoryString, PhysicalMemoryName);
  119. InitializeObjectAttributes(&attributes, &PhysicalMemoryString, 0, NULL, NULL);
  120. HANDLE hPhysicalMemory ;
  121. NTSTATUS status = ZwOpenSection(&hPhysicalMemory, dwDesiredAccess, &attributes );
  122. if(status == STATUS_ACCESS_DENIED)
  123. {
  124. status = ZwOpenSection(&hPhysicalMemory, READ_CONTROL|WRITE_DAC, &attributes);
  125. SetPhyscialMemoryAccess(hPhysicalMemory,dwDesiredAccess);
  126. CloseHandle(hPhysicalMemory);
  127. status = ZwOpenSection(&hPhysicalMemory, dwDesiredAccess, &attributes);
  128. }
  129. return ( NT_SUCCESS(status) ? hPhysicalMemory : NULL );
  130. //    g_pMapPhysicalMemory = MapViewOfFile(g_hMPM, FILE_MAP_READ|FILE_MAP_WRITE, 0, PhyDirectory,
  131. //0x1000);
  132. //    if( g_pMapPhysicalMemory == NULL )
  133. //        return NULL;
  134. //    return g_hMPM;
  135. }
  136. /////////////////////////////////////////////////////////////////////////////////////////////
  137. /////////////////////////////////////////////////////////////////////////////////////////////
  138. VOID PhysicalMemory::SetPhyscialMemoryAccess(HANDLE hPhysicalMemory,//由ZwOpenSection/NtOpenSection返回的物理内存句柄
  139. DWORD dwDesiredAccess//访问权限
  140. )
  141. //设置物理内存的访问权限,成功返回TRUE,错误返回FALSE
  142. {
  143. PACL pDacl                    = NULL;
  144. PSECURITY_DESCRIPTOR pSD    = NULL;
  145. PACL pNewDacl = NULL;
  146. DWORD dwRes = GetSecurityInfo(hPhysicalMemory, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL,
  147. NULL, &pDacl, NULL, &pSD);
  148. if(ERROR_SUCCESS != dwRes)
  149. {
  150. if(pSD)
  151. LocalFree(pSD);
  152. if(pNewDacl)
  153. LocalFree(pNewDacl);
  154. }
  155. EXPLICIT_ACCESS ea;
  156. RtlZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
  157. ea.grfAccessPermissions = SECTION_MAP_WRITE;
  158. ea.grfAccessMode = GRANT_ACCESS;
  159. ea.grfInheritance= NO_INHERITANCE;
  160. ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
  161. ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
  162. ea.Trustee.ptstrName = "CURRENT_USER";
  163. dwRes = SetEntriesInAcl(1,&ea,pDacl,&pNewDacl);
  164. if(ERROR_SUCCESS != dwRes)
  165. {
  166. if(pSD)
  167. LocalFree(pSD);
  168. if(pNewDacl)
  169. LocalFree(pNewDacl);
  170. }
  171. dwRes = SetSecurityInfo
  172. (hPhysicalMemory,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL);
  173. if(ERROR_SUCCESS != dwRes)
  174. {
  175. if(pSD)
  176. LocalFree(pSD);
  177. if(pNewDacl)
  178. LocalFree(pNewDacl);
  179. }
  180. }
  181. /////////////////////////////////////////////////////////////////////////////////////////////
  182. /////////////////////////////////////////////////////////////////////////////////////////////
  183. BOOL PhysicalMemory::ReadPhysicalMemory(OUT PVOID pvDataBuffer, //用于保存读取数据的缓冲区首地址
  184. IN DWORD dwAddress, //要读取的数据的首地址,要求4KB对齐
  185. IN DWORD dwLength //读取的长度
  186. )
  187. {
  188. if((dwAddress & 0x0fff ))//若地址不是4KB对齐,则返回
  189. {
  190. return FALSE;
  191. }
  192. if(m_hPhysicalMemory == NULL)
  193. {
  194. return FALSE;
  195. }
  196. DWORD dwOutLenth;            // 输出长度,根据内存分页大小可能大于要求的长度
  197. PVOID pvVirtualAddress;          // 映射的虚地址
  198. NTSTATUS status;         // NTDLL函数返回的状态
  199. LARGE_INTEGER base;      // 物理内存地址
  200. pvVirtualAddress = 0;
  201. dwOutLenth = dwLength;
  202. base.QuadPart = (ULONGLONG)(dwAddress);
  203. // 映射物理内存地址到当前进程的虚地址空间
  204. status = ZwMapViewOfSection(m_hPhysicalMemory,
  205. (HANDLE) -1,
  206. (PVOID *)&pvVirtualAddress,
  207. 0,
  208. dwLength,
  209. &base,
  210. &dwOutLenth,
  211. ViewShare,
  212. 0,
  213. PAGE_READONLY
  214. );
  215. if (status < 0)
  216. {
  217. return FALSE;
  218. }
  219. // 当前进程的虚地址空间中,复制数据到输出缓冲区
  220. memmove(pvDataBuffer,pvVirtualAddress, dwLength);
  221. // 完成访问,取消地址映射
  222. status = ZwUnmapViewOfSection((HANDLE)-1, (PVOID)pvVirtualAddress);
  223. return (status >= 0);
  224. }
  225. /////////////////////////////////////////////////////////////////////////////////////////////
  226. /////////////////////////////////////////////////////////////////////////////////////////////
  227. BOOL PhysicalMemory::WritePhysicalMemory(IN PVOID pvDataBuffer, //用于保存要写入的数据的缓冲区首地址
  228. IN DWORD dwAddress, //要目标地址,要求4KB对齐
  229. IN DWORD dwLength //写入的长度
  230. )
  231. {
  232. if((dwAddress & 0x0fff ))//若地址不是4KB对齐,则返回
  233. {
  234. return FALSE;
  235. }
  236. if(m_hPhysicalMemory == NULL)
  237. {
  238. return FALSE;
  239. }
  240. DWORD dwOutLenth;            // 输出长度,根据内存分页大小可能大于要求的长度
  241. PVOID pvVirtualAddress;          // 映射的虚地址
  242. NTSTATUS status;         // NTDLL函数返回的状态
  243. LARGE_INTEGER base;      // 物理内存地址
  244. pvVirtualAddress = 0;
  245. dwOutLenth = dwLength;
  246. base.QuadPart = (ULONGLONG)(dwAddress);
  247. // 映射物理内存地址到当前进程的虚地址空间
  248. status = ZwMapViewOfSection(m_hPhysicalMemory,
  249. (HANDLE) -1,
  250. (PVOID *)&pvVirtualAddress,
  251. 0,
  252. dwLength,
  253. &base,
  254. &dwOutLenth,
  255. ViewShare,
  256. ,0
  257. FILE_MAP_WRITE//PAGE_READWRITE
  258. );
  259. if (status < 0)
  260. {
  261. return FALSE;
  262. }
  263. // 当前进程的虚地址空间中,复制数据到输出缓冲区
  264. ::memmove(pvVirtualAddress, pvDataBuffer,dwLength);
  265. // 完成访问,取消地址映射
  266. status = ZwUnmapViewOfSection((HANDLE)-1, (PVOID)pvVirtualAddress);
  267. return (status >= 0);
  268. }
  269. /////////////////////////////////////////////////////////////////////////////////////////////
  270. /////////////////////////////////////////////////////////////////////////////////////////////
#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);
}
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////

jpg改rar

windows 物理内存获取的更多相关文章

  1. windows下获取IP地址的两种方法

    windows下获取IP地址的两种方法: 一种可以获取IPv4和IPv6,但是需要WSAStartup: 一种只能取到IPv4,但是不需要WSAStartup: 如下: 方法一:(可以获取IPv4和I ...

  2. Windows下获取本机IP地址方法介绍

    Windows下获取本机IP地址方法介绍 if((hostinfo = gethostbyname(name)) != NULL) { #if 1 ; printf("IP COUNT: % ...

  3. Windows下获取高精度时间注意事项

    Windows下获取高精度时间注意事项 [转贴 AdamWu]   花了很长时间才得到的经验,与大家分享. 1. RDTSC - 粒度: 纳秒级 不推荐优势: 几乎是能够获得最细粒度的计数器抛弃理由: ...

  4. golang windows程序获取管理员权限(UAC ) via gocn

    golang windows程序获取管理员权限(UAC ) 在windows上执行有关系统设置命令的时候需要管理员权限才能操作,比如修改网卡的禁用.启用状态.双击执行是不能正确执行命令的,只有右键以管 ...

  5. windows phone 获取手机图片库中图片(4)

    原文:windows phone 获取手机图片库中图片(4) 前置条件:手机和电脑未连接或连接电脑Zune软件关闭(与Zune软件连接时不允许访问图片库): 版本7.1 获取手机图片库图片的两种方式: ...

  6. Windows Phone获取WiFi BSSID

    原文:Windows Phone获取WiFi BSSID BSSID,一种特殊的Ad-hoc LAN的应用,也称为Basic Service Set (BSS),一群计算机设定相同的BSS名称,即可自 ...

  7. C/C++ Windows API——获取计算机信息 转

    转自:http://blog.csdn.net/chy555chy/article 函数 头文件 作用 GetVersionEx <windows.h> 获取系统版本信息(deprecat ...

  8. c和c++在windows下获取时间和计算时间差的方法总结

    c/c++在windows下获取时间和计算时间差的几种方法总结 一.标准C和C++都可用 1.获取时间用time_t time( time_t * timer ),计算时间差使用double diff ...

  9. Windows密码获取和破解(初探)

    Windows密码获取和破解 本文只是简单的讲明密码获取和破解 具体的操作细节均以模糊或具体代码混淆等方式避开 如有兴趣请自行研究,本文不做细说~~~ 获取思路: Windows密码一般是以" ...

随机推荐

  1. Web.xml详解(转)

    这篇文章主要是综合网上关于web.xml的一些介绍,希望对大家有所帮助,也欢迎大家一起讨论. ---题记 一.            Web.xml详解: (一)  web.xml加载过程(步骤) 首 ...

  2. 异常详细信息: System.ComponentModel.Win32Exception: 拒绝访问。

    本地win7 本地正常,服务器win2008r2,服务器报错! 异常详细信息: System.ComponentModel.Win32Exception: 拒绝访问. 拒绝访问. 说明: 执行当前 W ...

  3. 查询EBS中LOV的SQL语句

    1.帮助->关于:查找会话 SID : 507: 2.点一下LOV右边的三点,触发LOV事件: 3.运行如下代码段: DECLARE  l_sid NUMBER := :SID;BEGIN  F ...

  4. PHP中::、-&gt;、self、$this操作符的区别

    在访问PHP类中的成员变量或方法时,如果被引用的变量或者方法被声明成const(定义常量)或者static(声明静态),那么就必须使用操作符::,反之如果被引用的变量或者方法没有被声明成const或者 ...

  5. 使用Docker Mysql 5.7

    Mysql已经提供了Docker image,可以很方便开启一个mysql服务器.官方介绍了两种连接方式, 在其他App Docker 容器中通过--link访问Mysql服务端容器 启动另外一个My ...

  6. C# 3种方法连接MySql

    转   http://wenku.baidu.com/view/d0cf34708e9951e79b8927c7.html C# 连接MYSQL数据库的方法及示例 连接MYSQL数据库的方法及示例 方 ...

  7. 【Android自学日记】两种适配器的使用

    ArrayAdapter适配器: (1)用于显示基本的文字内容 (2)基本使用过程:新建适配器---创建或加载数据源---适配器加载数据源---视图加载适配器 ArrayAdapter(上下文,当前L ...

  8. Java Native Interface 五 JNI里的多线程与JNI方法的注册

    本文是<The Java Native Interface Programmer's Guide and Specification>读书笔记 JNI里的多线程 在本地方法里写有关多线程的 ...

  9. The difference between QA, QC, and Test Engineering

    Tuesday, March 06, 2007 Posted by Allen Hutchison, Engineering Manager and Jay Han, Software Enginee ...

  10. iOS 内存管理

    一 . 内存管理 包括内存分配 和 内存清除 1.内存管理的范围 :人和继承于NSObject类的对象都需要进行内存管理,任何非对象类型的对象(基本数据类型 如 int char float doub ...