zoukankan      html  css  js  c++  java
  • windows 物理内存获取

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


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


  • 相关阅读:
    SQL SERVER 2005分区表切换
    对SQL SERVER2005中表和索引存储结构的一些理解
    SQL SERVER 2005 DBCC IND命令说明
    面向对象的基本原则
    SQL SERVER 2005 DBCC PAGE命令说明
    Mac 使用ab性能测试工具
    Struts2初始化过程代码分析
    maven开发过程实践之二(配置项与源代码分离 processresources)
    简单之美
    Maven开发过程实践之三—(单元测试报告 test)
  • 原文地址:https://www.cnblogs.com/kuangke/p/6259344.html
Copyright © 2011-2022 走看看