Memory.cpp
上传用户:kittypts
上传日期:2018-02-11
资源大小:241k
文件大小:8k
源码类别:

PlugIns编程

开发平台:

Visual C++

  1. #include "Memory.h"
  2. ///
  3. /// Helpers:
  4. ///
  5. #define P_ACCESS_WRITE (PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE)
  6. #define P_ACCESS_READ (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_OPERATION)
  7. #define ARRAY_LEN(_array) (sizeof(_array)/sizeof(_array[0]))
  8. template <class T>
  9. SIZE_T GetStringLength(const NktMemory& mem, SIZE_T offset);
  10. ///
  11. /// Constructors / Destructor
  12. ///
  13. NktMemory::NktMemory()
  14. {
  15. _ptr = NULL;
  16. _pid = 0;
  17. }
  18. NktMemory::NktMemory(const NktMemory& r)
  19. {
  20. _ptr = r._ptr;
  21. _pid = r._pid;
  22. }
  23. NktMemory::NktMemory(DV_PTR ptr, DWORD pid)
  24. {
  25. _ptr = (void*)ptr;
  26. _pid = pid;
  27. }
  28. NktMemory::NktMemory(void* ptr, DWORD pid)
  29. {
  30. _ptr = ptr;
  31. _pid = pid;
  32. }
  33. ///
  34. /// CMemory::Read
  35. ///
  36. SIZE_T NktMemory::Read(SIZE_T offset, SIZE_T size, OUT DV_PTR buffer) const
  37. {
  38. DWORD oldProt = 0;
  39. DWORD dummie = -1;
  40. char* addr = (char*)_ptr + offset;
  41. SIZE_T bytesRead = 0;
  42. HRESULT hr = S_OK;
  43. wchar_t* errMsg = NULL;
  44. MEMORY_BASIC_INFORMATION memInfo;
  45. HANDLE hProc = OpenProcess(P_ACCESS_READ, FALSE, _pid);
  46. ZeroMemory(&memInfo, sizeof(memInfo));
  47. //Check handle:
  48. if (hProc == NULL)
  49. {
  50. errMsg = L"Memory Read: failed to obtain process handle.";
  51. hr = E_ACCESSDENIED;
  52. }
  53. else
  54. {
  55. //Check & obtain permissions:
  56. VirtualQueryEx(hProc, addr, &memInfo, size);
  57. if ((memInfo.Protect < PAGE_READONLY) && !VirtualProtectEx(hProc, addr, size, PAGE_EXECUTE_READWRITE, &oldProt))
  58. {
  59. OutputDebugStringW(L"Memory: Read: not enough permissions. Trying anyway...");
  60. hr = S_FALSE;
  61. }
  62. //Read memory:
  63. if (ReadProcessMemory(hProc, addr, (LPVOID)buffer, size, &bytesRead) == 0)
  64. {
  65. errMsg = L"Memory: Read: failed to read page.";
  66. hr = E_FAIL;
  67. }
  68. //If necessary, restore permissions.
  69. if (oldProt != 0 && !VirtualProtectEx(hProc, addr, size, oldProt, &dummie))
  70. {
  71. if(hr == S_OK)
  72. {
  73. OutputDebugStringW(L"Memory: Read: failed to restore memory previous protection.");
  74. hr = S_FALSE;
  75. }
  76. }
  77. CloseHandle(hProc);
  78. }
  79. if (FAILED(hr))
  80. {
  81. OutputDebugStringW(errMsg);
  82. bytesRead = 0;
  83. }
  84. return bytesRead;
  85. }
  86. SIZE_T NktMemory::Read(SIZE_T offset, SIZE_T size, OUT void* buffer) const
  87. return Read(offset, size, (DV_PTR) buffer); 
  88. }
  89. ///
  90. /// CMemory::Write
  91. ///
  92. SIZE_T NktMemory::Write(SIZE_T offset, SIZE_T size, const DV_PTR src)
  93. {
  94. DWORD oldProt = 0;
  95. DWORD dummie = -1;
  96. char* addr = (char*)_ptr + offset;
  97. HANDLE hProc = OpenProcess(P_ACCESS_WRITE, FALSE, _pid);
  98. HRESULT hr = S_OK;
  99. wchar_t* errMsg = NULL;
  100. SIZE_T bytesWritten = 0;
  101. //Check handle:
  102. if (hProc == NULL)
  103. {
  104. errMsg = L"Memory Read: failed to obtain process handle.";
  105. hr = E_ACCESSDENIED;
  106. }
  107. else
  108. {
  109. //Set write protection:
  110. if(VirtualProtectEx(hProc, addr, size, PAGE_READWRITE, &oldProt) == FALSE)
  111. {
  112. errMsg = (L"Memory: Write: failed to set page protection.");
  113. hr = E_ACCESSDENIED;
  114. }
  115. //Write memory:
  116. else if (WriteProcessMemory(hProc, addr, (LPCVOID)src, size, &bytesWritten) == FALSE)
  117. {
  118. errMsg = (L"Memory: Write: failed to write page.");
  119. hr = E_FAIL;
  120. }
  121. //Restore protection:
  122. else if (VirtualProtectEx(hProc, addr, size, oldProt, &dummie) == FALSE)
  123. {
  124. OutputDebugStringW(L"Memory: Write: failed to restore previous page protection.");
  125. hr = S_FALSE;
  126. }
  127. CloseHandle(hProc);
  128. }
  129. if (FAILED(hr))
  130. {
  131. OutputDebugStringW(errMsg);
  132. bytesWritten = 0;
  133. }
  134. return bytesWritten;
  135. }
  136. SIZE_T NktMemory::Write(SIZE_T offset, SIZE_T size, IN const void* src)
  137. return Write(offset, size, (DV_PTR) src);
  138. }
  139. ///
  140. /// CMemory::GetStringLength
  141. ///
  142. SIZE_T NktMemory::GetStringLengthA(SIZE_T offset) const
  143. {
  144. return GetStringLength<CHAR>(*this, offset);
  145. }
  146. SIZE_T NktMemory::GetStringLengthW(SIZE_T offset) const
  147. {
  148. return GetStringLength<WCHAR>(*this, offset);
  149. }
  150. ///
  151. /// CMemory::GetAddress
  152. ///
  153. DV_PTR NktMemory::GetAddress() const
  154. {
  155. return (DV_PTR)_ptr;
  156. }
  157. ///
  158. /// CMemory::SetAddress
  159. ///
  160. void NktMemory::SetAddress(DV_PTR ptr)
  161. {
  162. _ptr = (void *)ptr;
  163. }
  164. ///
  165. /// CMemory::SetProcessId
  166. ///
  167. void NktMemory::SetProcessId(DWORD pid)
  168. _pid = pid;
  169. }
  170. ///
  171. /// CMemory::GetPID
  172. ///
  173. DWORD NktMemory::GetProcessId() const
  174. {
  175. return _pid;
  176. }
  177. ///
  178. /// CMemory::GetMemoryInfo
  179. ///
  180. void NktMemory::GetMemoryInfo(SIZE_T offset, OUT MEMORY_BASIC_INFORMATION* pMemInfo) const
  181. {
  182. SIZE_T memInfoSize = sizeof(*pMemInfo);
  183. ZeroMemory(pMemInfo, memInfoSize);
  184. DV_PTR addr = (DV_PTR)_ptr + offset;
  185. // Get process handler
  186. HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, _pid);
  187. // Check hProc:
  188. if(hProc == NULL)
  189. {
  190. OutputDebugStringW(L"Memory::GetMemoryInfo() : Failed to obtain process handle");
  191. pMemInfo = NULL;
  192. return;
  193. }
  194. VirtualQueryEx(hProc, (void*)addr, pMemInfo, memInfoSize);
  195. CloseHandle(hProc);
  196. }
  197. ///
  198. /// CMemory::MapProtectionFlag
  199. ///
  200. DWORD NktMemory::MapProtectionFlag( DWORD win32Protection ) const
  201. {
  202. DWORD nktProtection = 0;
  203. if( win32Protection & PAGE_EXECUTE )
  204. {
  205. nktProtection = NktMemoryProtectionExecute;
  206. }
  207. else if( win32Protection & PAGE_EXECUTE_READ )
  208. {
  209. nktProtection = NktMemoryProtectionExecute | NktMemoryProtectionRead;
  210. }
  211. else if( win32Protection & PAGE_EXECUTE_READWRITE )
  212. {
  213. nktProtection = NktMemoryProtectionExecute | NktMemoryProtectionRead | NktMemoryProtectionWrite;
  214. }
  215. else if( win32Protection & PAGE_EXECUTE_WRITECOPY )
  216. {
  217. nktProtection = NktMemoryProtectionExecute | NktMemoryProtectionRead | NktMemoryProtectionWrite | NktMemoryProtectionWriteCopy;
  218. }
  219. else if( win32Protection & PAGE_NOACCESS )
  220. {
  221. nktProtection = NktMemoryProtectionNoAccess;
  222. }
  223. else if( win32Protection & PAGE_READONLY )
  224. {
  225. nktProtection = NktMemoryProtectionRead;
  226. }
  227. else if( win32Protection & PAGE_READWRITE )
  228. {
  229. nktProtection = NktMemoryProtectionRead | NktMemoryProtectionWrite;
  230. }
  231. else if( win32Protection & PAGE_WRITECOPY )
  232. {
  233. nktProtection = NktMemoryProtectionRead | NktMemoryProtectionWrite | NktMemoryProtectionWriteCopy;
  234. }
  235. // these are modifiers
  236. if( win32Protection & PAGE_GUARD )
  237. {
  238. nktProtection = nktProtection | NktMemoryProtectionGuard;
  239. }
  240. if( win32Protection & PAGE_NOCACHE )
  241. {
  242. nktProtection = nktProtection | NktMemoryProtectionNoCache;
  243. }
  244. if( win32Protection & PAGE_WRITECOMBINE )
  245. {
  246. nktProtection = nktProtection | NktMemoryProtectionWriteCombine;
  247. }
  248. return nktProtection;
  249. }
  250. ///
  251. /// CMemory::GetProtection
  252. ///
  253. DWORD NktMemory::GetProtection(SIZE_T offset, BOOL allocated /*= TRUE*/) const
  254. {
  255. MEMORY_BASIC_INFORMATION memInfo;
  256. GetMemoryInfo(offset, &memInfo);
  257. DWORD protection;
  258. if( allocated )
  259. {
  260. protection = MapProtectionFlag( memInfo.AllocationProtect );
  261. }
  262. else
  263. {
  264. protection = MapProtectionFlag( memInfo.Protect );
  265. }
  266.     
  267. return protection;
  268. }
  269. ///
  270. /// CMemory::IsExecutable
  271. ///
  272. BOOL NktMemory::IsExecutable(SIZE_T offset, BOOL allocated /*= TRUE*/) const
  273. {
  274. BOOL exec;
  275. try
  276. {
  277. exec = GetProtection( offset, allocated ) & NktMemoryProtectionExecute;
  278. }
  279. catch ( ... )
  280. {
  281. exec = FALSE;
  282. }
  283. return exec;
  284. }
  285. /************************************************************************/
  286. /* Helpers                                                              */
  287. /************************************************************************/
  288. template <class T>
  289. SIZE_T GetStringLength(const NktMemory& mem, SIZE_T offset)
  290. {
  291. T ch = NULL;
  292. T buffer[0x80];
  293. bool parsing = true;
  294. SIZE_T len = 0;
  295. while (parsing)
  296. {
  297. mem.Read(offset, sizeof(buffer), buffer);
  298. for (int i = 0; i < ARRAY_LEN(buffer); i++, len++)
  299. {
  300. if (buffer[i] == 0)
  301. {
  302. parsing = false;
  303. break;
  304. }
  305. }
  306. offset += sizeof(buffer);
  307. }
  308. return len;
  309. }