| 1021 | |
| 1022 | _Success_(return != NULL) |
| 1023 | PVOID WINAPI DetourCopyPayloadToProcessEx(_In_ HANDLE hProcess, |
| 1024 | _In_ REFGUID rguid, |
| 1025 | _In_reads_bytes_(cbData) LPCVOID pvData, |
| 1026 | _In_ DWORD cbData) |
| 1027 | { |
| 1028 | if (hProcess == NULL) { |
| 1029 | SetLastError(ERROR_INVALID_HANDLE); |
| 1030 | return NULL; |
| 1031 | } |
| 1032 | |
| 1033 | DWORD cbTotal = (sizeof(IMAGE_DOS_HEADER) + |
| 1034 | sizeof(IMAGE_NT_HEADERS) + |
| 1035 | sizeof(IMAGE_SECTION_HEADER) + |
| 1036 | sizeof(DETOUR_SECTION_HEADER) + |
| 1037 | sizeof(DETOUR_SECTION_RECORD) + |
| 1038 | cbData); |
| 1039 | |
| 1040 | PBYTE pbBase = (PBYTE)VirtualAllocEx(hProcess, NULL, cbTotal, |
| 1041 | MEM_COMMIT, PAGE_READWRITE); |
| 1042 | if (pbBase == NULL) { |
| 1043 | DETOUR_TRACE(("VirtualAllocEx(%lu) failed: %lu\n", cbTotal, GetLastError())); |
| 1044 | return NULL; |
| 1045 | } |
| 1046 | |
| 1047 | // As you can see in the following code, |
| 1048 | // the memory layout of the payload range "[pbBase, pbBase+cbTotal]" is a PE executable file, |
| 1049 | // so DetourFreePayload can use "DetourGetContainingModule(Payload pointer)" to get the above "pbBase" pointer, |
| 1050 | // pbBase: the memory block allocated by VirtualAllocEx will be released in DetourFreePayload by VirtualFree. |
| 1051 | |
| 1052 | PBYTE pbTarget = pbBase; |
| 1053 | IMAGE_DOS_HEADER idh; |
| 1054 | IMAGE_NT_HEADERS inh; |
| 1055 | IMAGE_SECTION_HEADER ish; |
| 1056 | DETOUR_SECTION_HEADER dsh; |
| 1057 | DETOUR_SECTION_RECORD dsr; |
| 1058 | SIZE_T cbWrote = 0; |
| 1059 | |
| 1060 | ZeroMemory(&idh, sizeof(idh)); |
| 1061 | idh.e_magic = IMAGE_DOS_SIGNATURE; |
| 1062 | idh.e_lfanew = sizeof(idh); |
| 1063 | if (!WriteProcessMemory(hProcess, pbTarget, &idh, sizeof(idh), &cbWrote) || |
| 1064 | cbWrote != sizeof(idh)) { |
| 1065 | DETOUR_TRACE(("WriteProcessMemory(idh) failed: %lu\n", GetLastError())); |
| 1066 | return NULL; |
| 1067 | } |
| 1068 | pbTarget += sizeof(idh); |
| 1069 | |
| 1070 | ZeroMemory(&inh, sizeof(inh)); |
| 1071 | inh.Signature = IMAGE_NT_SIGNATURE; |
| 1072 | inh.FileHeader.SizeOfOptionalHeader = sizeof(inh.OptionalHeader); |
| 1073 | inh.FileHeader.Characteristics = IMAGE_FILE_DLL; |
| 1074 | inh.FileHeader.NumberOfSections = 1; |
| 1075 | inh.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; |
| 1076 | if (!WriteProcessMemory(hProcess, pbTarget, &inh, sizeof(inh), &cbWrote) || |
| 1077 | cbWrote != sizeof(inh)) { |
| 1078 | return NULL; |
| 1079 | } |
| 1080 | pbTarget += sizeof(inh); |
no test coverage detected
searching dependent graphs…