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

  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. Java面试常见问题汇总

    1 String,StringBuffer与StringBuilder的区别??   String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非 ...

  2. ASP.NET vNext on CentOS 7

    第一步是在Linux上安装.Net的运行时Mono VNext要求Mono最小版本3.4.1,可怜的centos连低版本的mono都不含.我们只能通过编译来安装.目前最新的版本为3.12 源码下载:h ...

  3. Linux 从零开始

    从Windows进入linux有太多不适应,对代码一无所知,接触Linux,从简单的开始垒砌. 加油最好的自己!

  4. C# Async, Await and using statements

    Async, Await 是基于 .NEt 4.5架构的, 用于处理异步,防止死锁的方法的开始和结束, 提高程序的响应能力.比如: Application area           Support ...

  5. ubuntu 12.04 LTS 64位兼容运行32位程序

    安装完Goagent,运行的时候出现了问题,在网络上翻看一些关于ubuntu的文档时,突然记起自己安装的是64位版,而goagent应该是32位的,于是通过sudo apt-get install i ...

  6. Python中函数、类、模块和包的调用

    初学python阶段,大多数人对函数.类.模块和包的调用都搞得不是很清楚,这篇随笔就简单的进行说明. (1)函数 当函数定义好之后,可以直接调用. 比如:def summ(add1,add2),那么 ...

  7. ASP.NET中Ajax的用法

    在ASP.NET中应用Ajax的格式如下: 前台代码(用JQuery库) $.ajax({ type: "POST", async: true, url: "../Aja ...

  8. Baseadapter与Simpleadapter之争

    作者:andyrat,联系方式:andyrat@qq.com

  9. C++基础知识面试精选100题系列(11-20题)[C++ basics]

    [原文链接] http://www.cnblogs.com/hellogiser/p/100-interview-questions-of-cplusplus-basics-11-20.html [题 ...

  10. php二进制安全的含义

    PHP里,有string的概念.string里,每个字符的大小为byte(与PHP相比,Java的每个字符为Character,是UTF8字符,C语言的每个字符可以在编译时选择). byte里,有AS ...