概述:远程加载和释放DLL,仅记录学习笔记,无参考意义。

CreateRemoteThread 的用法参考文章 CreateRemoteThread的简单使用

说明

主要就是在目标进程中调用 LoadLibraryFreeLibrary 这两个函数。没有什么技术含量,会以下几个API就可以

  • CreateRemoteThread
  • LoadLibrary
  • Freelibrary
  • OpenProcess
  • VirtualAllocEx
  • GetProcAddress
  • CreateToolhelp32Snapshot

注意点

卸载dll时需要判断dll是否存在。

需要调用 CreateToolhelp32Snapshot 通过 MODULEENTRY32 枚举进程加载的模块有哪些。MODULEENTRY32 结构体如下所示

  • szModule:模块名
  • szExePath:模块加载的路径
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
typedef struct tagMODULEENTRY32
{
DWORD dwSize;
DWORD th32ModuleID; // This module
DWORD th32ProcessID; // owning process
DWORD GlblcntUsage; // Global usage count on the module
DWORD ProccntUsage; // Module usage count in th32ProcessID's context
BYTE * modBaseAddr; // Base address of module in th32ProcessID's context
DWORD modBaseSize; // Size in bytes of module starting at modBaseAddr
HMODULE hModule; // The hModule of this module in th32ProcessID's context
char szModule[MAX_MODULE_NAME32 + 1];
char szExePath[MAX_PATH];
} MODULEENTRY32;
typedef MODULEENTRY32 * PMODULEENTRY32;
typedef MODULEENTRY32 * LPMODULEENTRY32;

Code

代码部分分别封装了两个函数 InjectDllFreeDll

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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#pragma comment(lib,"Advapi32.lib")

BOOL InjectDll(UINT32 ProcessId, char *DllPath)
{
if (strstr(DllPath, "\\\\") != 0)
{
printf("[!]Wrong Dll path\n");
return FALSE;
}
if (strstr(DllPath, "\\") == 0)
{
printf("[!]Need Dll full path\n");
return FALSE;
}

size_t len = strlen(DllPath) + 1;

LPVOID pThreadData = NULL;
HANDLE ProcessHandle = NULL;
HANDLE hThread = NULL;
BOOL bRet = FALSE;

__try
{
ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
if (ProcessHandle == NULL)
{
printf("[!]OpenProcess error\n");
__leave;
}

pThreadData = VirtualAllocEx(ProcessHandle, NULL, len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (pThreadData == NULL)
{
CloseHandle(ProcessHandle);
printf("[!]VirtualAllocEx error\n");
__leave;
}

BOOL bWriteOK = WriteProcessMemory(ProcessHandle, pThreadData, DllPath, len, NULL);
if (!bWriteOK)
{
CloseHandle(ProcessHandle);
printf("[!]WriteProcessMemory error\n");
__leave;
}

LPTHREAD_START_ROUTINE LoadLibraryAddress = NULL;
HMODULE Kernel32Module = GetModuleHandle("Kernel32");
LoadLibraryAddress = (LPTHREAD_START_ROUTINE)GetProcAddress(Kernel32Module, "LoadLibraryA");
hThread = CreateRemoteThread(ProcessHandle, NULL, 0, LoadLibraryAddress, pThreadData, 0, NULL);
if (hThread == NULL)
{
CloseHandle(ProcessHandle);
printf("[!]CreateRemoteThread error\n");
__leave;
}

WaitForSingleObject(hThread, INFINITE);
bRet = TRUE;

}
__finally
{
if (pThreadData != NULL)
VirtualFreeEx(ProcessHandle, pThreadData, 0, MEM_RELEASE);

if (hThread != NULL)
CloseHandle(hThread);
if (ProcessHandle != NULL)
CloseHandle(ProcessHandle);
}
return bRet;

}

BOOL FreeDll(UINT32 ProcessId, char *DllFullPath)
{
BOOL bMore = FALSE, bFound = FALSE;
HANDLE hSnapshot;
HMODULE hModule = NULL;
MODULEENTRY32 me = { sizeof(me) };
BOOL bSuccess = FALSE;
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessId);
bMore = Module32First(hSnapshot, &me);
for (; bMore; bMore = Module32Next(hSnapshot, &me)) {
if (!_tcsicmp((LPCTSTR)me.szModule, DllFullPath) || !_tcsicmp((LPCTSTR)me.szExePath, DllFullPath))
{
bFound = TRUE;
break;
}
}
if (!bFound) {
CloseHandle(hSnapshot);
return FALSE;
}

BOOL bRet = FALSE;
HANDLE ProcessHandle = NULL;

__try
{
ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
if (ProcessHandle == NULL)
{
printf("[!]OpenProcess error\n");
__leave;
}

LPTHREAD_START_ROUTINE FreeLibraryAddress = NULL;
HMODULE Kernel32Module = GetModuleHandle("Kernel32");
FreeLibraryAddress = (LPTHREAD_START_ROUTINE)GetProcAddress(Kernel32Module, "FreeLibrary");

HANDLE hThread = NULL;
hThread = CreateRemoteThread(ProcessHandle, NULL, 0, FreeLibraryAddress, me.modBaseAddr, 0, NULL);
if (hThread == NULL)
{
CloseHandle(ProcessHandle);
printf("[!]CreateRemoteThread error\n");
__leave;
}

WaitForSingleObject(hThread, INFINITE);
bRet = TRUE;
}
__finally
{
if (ProcessHandle != NULL)
CloseHandle(ProcessHandle);
}
return bRet;
}

BOOL EnableDebugPrivilege(BOOL fEnable)
{
BOOL fOk = FALSE;
HANDLE hToken;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
fOk = (GetLastError() == ERROR_SUCCESS);
CloseHandle(hToken);
}
return(fOk);
}

int main(int argc, char *argv[])
{
if (argc != 3)
{
printf("Use CreateRemoteThread to inject dll,usually used under XP.\n\n");
printf("Usage:\n");
printf("%s <PID> <Dll Path>\n", argv[0]);
return 0;
}

if (!EnableDebugPrivilege(TRUE))
{
printf("[!]AdjustTokenPrivileges Failed.<%d>\n", GetLastError());
}

if (!InjectDll((DWORD)atoi(argv[1]), argv[2]))
{
printf("[!]InjectDll error \n");
return 1;
}

if (!FreeDll((DWORD)atoi(argv[1]), argv[2]))
{
printf("[!]FreeDll error \n");
return 1;
}
printf("[+]InjectDll success\n");

return 0;
}