-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathloadremotelib.cpp
More file actions
137 lines (100 loc) · 2.63 KB
/
Copy pathloadremotelib.cpp
File metadata and controls
137 lines (100 loc) · 2.63 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
124
125
126
127
128
129
130
131
132
133
134
135
136
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
#ifndef PSAPI_VERSION
#define PSAPI_VERSION 1
#endif
#include <winstrct.h>
#include <ntdll.h>
#include <Psapi.h>
#define THREAD_STACK_SIZE (1 << 20)
#ifdef _WIN64
#pragma comment(lib, "psapi.lib")
#endif
HMODULE
WINAPI
LoadRemoteLibrary(HANDLE process, LPCWSTR dllpath)
{
SIZE_T towrite = (wcslen(dllpath) + 1) * sizeof(*dllpath);
LPVOID remote_data_ptr = NULL;
NTSTATUS status = NtAllocateVirtualMemory(process, &remote_data_ptr, 0, &towrite, MEM_COMMIT, PAGE_READWRITE);
if (!NT_SUCCESS(status))
{
SetLastError(RtlNtStatusToDosError(status));
return NULL;
}
SIZE_T written;
if (!WriteProcessMemory(process, remote_data_ptr, dllpath, towrite, &written))
{
SIZE_T region_size = 0;
NtFreeVirtualMemory(process, &remote_data_ptr, ®ion_size, MEM_RELEASE);
return NULL;
}
DWORD tid;
HANDLE thread = CreateRemoteThread(process, NULL, THREAD_STACK_SIZE, (LPTHREAD_START_ROUTINE)LoadLibraryW, remote_data_ptr, 0, &tid);
if (thread == NULL)
{
SIZE_T region_size = 0;
NtFreeVirtualMemory(process, &remote_data_ptr, ®ion_size, MEM_RELEASE);
return NULL;
}
WaitForSingleObject(thread, INFINITE);
SIZE_T region_size = 0;
NtFreeVirtualMemory(process, &remote_data_ptr, ®ion_size, MEM_RELEASE);
HMODULE module = NULL;
#ifndef _WIN64
if (!GetExitCodeThread(thread, (LPDWORD) & module))
{
CloseHandle(thread);
return NULL;
}
CloseHandle(thread);
#else
CloseHandle(thread);
DWORD length = 4096;
WHeapMem<HMODULE> modules;
for (;;)
{
modules.ReAlloc(length, HEAP_GENERATE_EXCEPTIONS);
BOOL rc = EnumProcessModules(process, modules, (DWORD)modules.GetSize(), &length);
if (length > (DWORD)modules.GetSize())
{
continue;
}
if (!rc)
{
return NULL;
}
break;
}
int items = length / sizeof(HMODULE);
LPCWSTR dll_base_path = wcsrchr(dllpath, '\\');
if (dll_base_path == NULL)
{
dll_base_path = dllpath;
}
else
{
dll_base_path++;
}
WCHAR modname[MAX_PATH];
for (int i = 0; i < items; i++)
{
DWORD rc = GetModuleBaseName(process, modules[i], modname, _countof(modname));
modname[rc] = 0;
if (_wcsicmp(modname, dll_base_path) == 0)
{
module = modules[i];
break;
}
}
#endif
if (module == NULL)
{
SetLastError(ERROR_NOT_FOUND);
}
return module;
}