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

PlugIns编程

开发平台:

Visual C++

  1. #include "ntapi.h"
  2. #include "NtUnDoc.h"
  3. #include <tchar.h>
  4. #include <stdio.h>
  5. #include <stdarg.h>
  6. #pragma warning(disable:4005)
  7. #include <ntstatus.h>
  8. #include <crtdbg.h>
  9. #include <malloc.h>
  10. ///
  11. /// Types:
  12. ///
  13. typedef ULONG_PTR KPRIORITY;
  14. typedef struct _THREAD_BASIC_INFORMATION {
  15. NTSTATUS                ExitStatus;
  16. PVOID                   TebBaseAddress;
  17. ClientId               ClientId;
  18. KAFFINITY               AffinityMask;
  19. KPRIORITY               Priority;
  20. KPRIORITY               BasePriority;
  21. } THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
  22. ///
  23. /// Helpers:
  24. ///
  25. void SetUnicodeString(UNICODE_STRING& ustr, LPCWSTR txt);
  26. #define InitializeObjectAttributes( p, n, a, r, s ) { 
  27. (p)->Length = sizeof( OBJECT_ATTRIBUTES );          
  28. (p)->RootDirectory = r;                             
  29. (p)->Attributes = a;                                
  30. (p)->ObjectName = n;                                
  31. (p)->SecurityDescriptor = s;                        
  32. (p)->SecurityQualityOfService = NULL;               
  33. }
  34. #define ANSI_TO_WIDE(_ansi, _wide) 
  35. size_t l = strlen(_ansi); 
  36. size_t wl = MultiByteToWideChar(CP_ACP, 0, _ansi, (int)l, NULL,0); 
  37. _wide = static_cast<LPWSTR>(alloca(++wl*sizeof(WCHAR))); 
  38. if (::MultiByteToWideChar(CP_ACP, 0, _ansi, (int)l, _wide, (int)wl) == 0) 
  39. _wide = NULL;
  40. /**
  41. NtApiInitializer
  42. */
  43. class NktNtApiInitializer
  44. {
  45. public:
  46. NktNtApiInitializer()
  47. {
  48. NktNtApi::Initialize();
  49. }
  50. } NtApiInitializerInst;
  51. ///
  52. /// NtApi: Statics
  53. ///
  54. bool NktNtApi::initialized = false;
  55. NktNtApi::LdrGetProcedureAddress NktNtApi::getProcAddress = NULL;
  56. NktNtApi::NtSuspendThread NktNtApi::suspendThread = NULL;
  57. NktNtApi::DbgPrint NktNtApi::dbgPrint = NULL;
  58. NktNtApi::RtlInitAnsiString NktNtApi::initAnsiString = NULL;
  59. NktNtApi::RtlInitUnicodeString NktNtApi::initUnicodeString = NULL;
  60. NktNtApi::NtCurrentTeb NktNtApi::ntCurrentTeb = NULL;
  61. NktNtApi::NtSetEvent NktNtApi::ntSetEvent = NULL;
  62. NktNtApi::NtPulseEvent NktNtApi::ntPulseEvent = NULL;
  63. NktNtApi::NtResetEvent NktNtApi::ntResetEvent = NULL;
  64. NktNtApi::NtClose NktNtApi::ntClose = NULL;
  65. NktNtApi::NtCreateEvent NktNtApi::ntCreateEvent = NULL;
  66. NktNtApi::NtOpenEvent NktNtApi::ntOpenEvent = NULL;
  67. NktNtApi::NtQueryInformationThread NktNtApi::ntQueryInformationThread = NULL;
  68. NktNtApi::NtLdrGetDllHandle NktNtApi::ntLdrGetDllHandle = NULL;
  69. SYSTEM_INFO NktNtApi::systemInfo = { 0 };
  70. ///
  71. /// Helpers:
  72. ///
  73. void GetClientID(ClientId& cid)
  74. {
  75. PUndocTeb teb = NULL;
  76. // calculate the offset of the clientId (it should work in 64b
  77. SIZE_T offset = (INT_PTR) &teb->Cid - (INT_PTR) teb;
  78. INT_PTR cteb = (SIZE_T)NktNtApi::CurrentTEB();
  79. memcpy(&cid, (const void*)(cteb + offset), sizeof(ClientId));
  80. }
  81. ///
  82. /// Constructors / Destructor
  83. ///
  84. void NktNtApi::Initialize()
  85. {
  86. if (initialized)
  87. return;
  88. HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll"); _ASSERT(hMod);
  89. initAnsiString = (RtlInitAnsiString) ::GetProcAddress(hMod, "RtlInitAnsiString");
  90. initUnicodeString = (RtlInitUnicodeString) ::GetProcAddress(hMod, "RtlInitUnicodeString");
  91. getProcAddress = (LdrGetProcedureAddress)::GetProcAddress(hMod, "LdrGetProcedureAddress");
  92. suspendThread = (NtSuspendThread)::GetProcAddress(hMod, "NtSuspendThread");
  93. dbgPrint = (DbgPrint)::GetProcAddress(hMod, "DbgPrint");
  94. ntCurrentTeb = (NtCurrentTeb)::GetProcAddress(hMod, "NtCurrentTeb");
  95. ntSetEvent = (NtSetEvent)::GetProcAddress(hMod, "NtSetEvent");
  96. ntResetEvent = (NtResetEvent)::GetProcAddress(hMod, "NtPulseEvent");
  97. ntPulseEvent = (NtPulseEvent)::GetProcAddress(hMod, "NtResetEvent");
  98. ntClose = (NtClose)::GetProcAddress(hMod, "NtClose");
  99. ntCreateEvent = (NtCreateEvent) ::GetProcAddress(hMod, "NtCreateEvent");
  100. ntOpenEvent = (NtOpenEvent) ::GetProcAddress(hMod, "NtOpenEvent");
  101. ntQueryInformationThread = (NtQueryInformationThread) ::GetProcAddress(hMod, "NtQueryInformationThread");
  102. ntLdrGetDllHandle = (NtLdrGetDllHandle) ::GetProcAddress(hMod, "LdrGetDllHandle");
  103. ZeroMemory(&systemInfo, sizeof(SYSTEM_INFO));
  104. ::GetSystemInfo(&systemInfo);
  105. initialized = true;
  106. }
  107. ///
  108. /// NktNtApi::CloseHandle
  109. ///
  110. BOOL NktNtApi::CloseHandle(HANDLE h)
  111. {
  112. NTSTATUS st = ntClose(h);
  113. return st == 0;
  114. }
  115. ///
  116. /// NktNtApi::SuspendThread
  117. ///
  118. void NktNtApi::SuspendThread(HANDLE hthread)
  119. {
  120. _ASSERT(initialized);
  121. suspendThread(hthread, NULL);
  122. }
  123. ///
  124. /// NktNtApi::GetCurrentThreadId
  125. ///
  126. DWORD NktNtApi::GetCurrentThreadId()
  127. {
  128. _ASSERT(initialized);
  129. ClientId cid;
  130. GetClientID(cid);
  131. return cid.UniqueThreadId;
  132. }
  133. ///
  134. /// NktNtApi::GetCurrentProcessId
  135. ///
  136. DWORD NktNtApi::GetCurrentProcessId()
  137. {
  138. _ASSERT(initialized);
  139. ClientId cid;
  140. GetClientID(cid);
  141. return cid.UniqueProcessId;
  142. }
  143. ///
  144. /// NktNtApi::GetProcAddress
  145. ///
  146. FARPROC NktNtApi::GetProcAddress(IN HMODULE hModule, IN LPCSTR lpProcName)
  147. {
  148. _ASSERT(initialized);
  149. FARPROC ret = NULL;
  150. char buffer[256];
  151. STRING ntString;
  152. ntString.Buffer = buffer;
  153. initAnsiString(&ntString, lpProcName);
  154. getProcAddress(hModule, &ntString, 0, (PVOID*)&ret);
  155. return ret;
  156. }
  157. ///
  158. /// NktNtApi::CurrentTEB
  159. ///
  160. PTEB NktNtApi::CurrentTEB()
  161. {
  162. _ASSERT(initialized);
  163. return ntCurrentTeb();
  164. }
  165. ///
  166. /// NktNtApi::GetThreadTEB
  167. ///
  168. PTEB NktNtApi::GetThreadTEB(DWORD tid)
  169. {
  170. THREAD_BASIC_INFORMATION tbInfo;
  171. PTEB teb = NULL;
  172. HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, tid);
  173. if (!hThread) return teb;
  174. NTSTATUS ret = ntQueryInformationThread(hThread, (THREADINFOCLASS)0, &tbInfo, sizeof(tbInfo), NULL);
  175. if (ret == STATUS_SUCCESS)
  176. teb = (PTEB)tbInfo.TebBaseAddress;
  177. CloseHandle(hThread);
  178. return teb;
  179. }
  180. ///
  181. /// NktNtApi::GetPageSize
  182. ///
  183. DWORD NktNtApi::GetPageSize()
  184. {
  185. _ASSERT(initialized);
  186. return systemInfo.dwPageSize;
  187. }
  188. ///
  189. /// NktNtApi::CreateEvent
  190. ///
  191. HANDLE NktNtApi::CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName)
  192. {
  193. EVENT_TYPE type = (bManualReset)? NotificationEvent : SynchronizationEvent;
  194. HANDLE hEvent = 0;
  195. OBJECT_ATTRIBUTES obj;
  196. UNICODE_STRING uname, *puname = NULL;
  197. if (lpName)
  198. {
  199. SetUnicodeString(uname, lpName);
  200. puname = &uname;
  201. }
  202. InitializeObjectAttributes(&obj, &uname, 0, 0, 0);
  203. NTSTATUS ret = ntCreateEvent(&hEvent, EVENT_ALL_ACCESS, &obj, type, bInitialState);
  204. return hEvent;
  205. }
  206. HANDLE NktNtApi::CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName)
  207. {
  208. LPWSTR wname = NULL;
  209. if (lpName)
  210. {
  211. ANSI_TO_WIDE(lpName, wname);
  212. if (wname == NULL)
  213. {
  214. OutputDebugStringW(L"NtApi: CreateEvent: Can't create event with provided name.");
  215. return INVALID_HANDLE_VALUE;
  216. }
  217. }
  218. return CreateEvent(lpEventAttributes, bManualReset, bInitialState, wname);
  219. }
  220. ///
  221. /// NktNtApi::OpenEvent
  222. ///
  223. HANDLE NktNtApi::OpenEvent(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
  224. {
  225. _ASSERT(bInheritHandle == FALSE);
  226. HANDLE hEvent = 0;
  227. OBJECT_ATTRIBUTES obj;
  228. UNICODE_STRING uname, *puname = NULL;
  229. if (lpName)
  230. {
  231. SetUnicodeString(uname, lpName);
  232. puname = &uname;
  233. }
  234. InitializeObjectAttributes(&obj, puname, 0, 0, 0);
  235. NTSTATUS ret = ntOpenEvent(&hEvent, dwDesiredAccess, &obj); //_ASSERT(ret == STATUS_SUCCESS);
  236. return hEvent;
  237. }
  238. HANDLE NktNtApi::OpenEvent(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
  239. {
  240. LPWSTR wname = NULL;
  241. if (lpName)
  242. {
  243. ANSI_TO_WIDE(lpName, wname);
  244. }
  245. return OpenEvent(dwDesiredAccess, bInheritHandle, wname);
  246. }
  247. ///
  248. /// NktNtApi::SetEvent
  249. ///
  250. BOOL NktNtApi::SetEvent(IN HANDLE hEvent)
  251. {
  252. _ASSERT(initialized);
  253. NTSTATUS ret = ntSetEvent(hEvent, 0);
  254. return ret == STATUS_SUCCESS;
  255. }
  256. ///
  257. /// NktNtApi::SetEvent
  258. ///
  259. BOOL NktNtApi::PulseEvent(IN HANDLE hEvent)
  260. {
  261. _ASSERT(initialized);
  262. NTSTATUS ret = ntPulseEvent(hEvent, 0);
  263. return ret == STATUS_SUCCESS;
  264. }
  265. ///
  266. /// NktNtApi::SetEvent
  267. ///
  268. BOOL NktNtApi::ResetEvent(IN HANDLE hEvent)
  269. {
  270. _ASSERT(initialized);
  271. NTSTATUS ret = ntResetEvent(hEvent, 0);
  272. return ret == STATUS_SUCCESS;
  273. }
  274. ///
  275. /// NktNtApi::DebugPrint
  276. ///
  277. void __declspec(naked) NktNtApi::DebugPrint(IN LPCSTR msg, ...)
  278. {
  279. _ASSERT(initialized);
  280. _asm {
  281. jmp [NktNtApi::dbgPrint]
  282. }
  283. }
  284. ///
  285. /// NktNtApi::GetModuleHandle
  286. ///
  287. HMODULE NktNtApi::RawGetModuleHandle(IN LPCWSTR modName)
  288. {
  289. HANDLE handle;
  290. UNICODE_STRING ustr;
  291. SetUnicodeString(ustr, modName);
  292. NTSTATUS status = ntLdrGetDllHandle(0, 0, &ustr, &handle);
  293. return (status == STATUS_SUCCESS)? (HMODULE)handle : NULL;
  294. }
  295. HMODULE NktNtApi::RawGetModuleHandle(IN LPCSTR modName)
  296. {
  297. size_t l = strlen(modName);
  298. WCHAR* buffer = (WCHAR*)alloca((l+1)*sizeof(WCHAR));
  299. int conv = MultiByteToWideChar(CP_ACP, 0, modName, (int)l+1, buffer, (int)(l+1)*sizeof(WCHAR));
  300. return (conv != 0)? GetModuleHandle(buffer) : NULL;
  301. }
  302. /************************************************************************/
  303. /* Helpers                                                              */
  304. /************************************************************************/
  305. void SetUnicodeString(UNICODE_STRING& ustr, LPCWSTR txt)
  306. {
  307. ustr.Buffer = (PWSTR)txt;
  308. ustr.Length = static_cast<USHORT>(wcslen(ustr.Buffer) << 1);
  309. ustr.MaximumLength = ustr.Length + sizeof(WCHAR);
  310. }