这一篇拖了比较久,因为之前不理解进程的权限令牌的作用,看逆向工程核心原理的时候发现注入不需要权限但是卸载却需要,书里面还没详细说,就一直搁置了,前几周学了APC注入,才知道进程权限完全就是试的,如果遇到0x5访问权限冲突,那就提升权限就好了。

DLL卸载

DLL之前注入后,再次注入就不会触发attch效果了,如果不想重开进程就需要先卸载之后再注入。另一方面,如果想要让DLL执行完之后就立即卸载(即时效果)也许要卸载它。

流程

找到进程->找进程模块->匹配相同的模块名->执行FreeLibrary

看书的时候发现FreeLibrary没有W且需要传入对应的句柄而不是指针

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
HANDLE Injector::isLoaded(DWORD pid)
{
HANDLE hModule = nullptr;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
if (hSnapshot == INVALID_HANDLE_VALUE || hSnapshot == NULL)
throw std::runtime_error("创建快照失败");
MODULEENTRY32 me;
me.dwSize = sizeof(MODULEENTRY32);
if (Module32First(hSnapshot, &me)) {
do
{
if (!_wcsicmp(PathFindFileNameW(DLLpath), me.szModule) &&
!_wcsicmp(DLLpath, me.szExePath)) {
hModule = me.hModule;
break;
}
} while (Module32Next(hSnapshot, &me));
}
CloseHandle(hSnapshot);
return hModule;
}
void Injector::eject()
{
auto pfreelibrary = (LPTHREAD_START_ROUTINE)ModuleFuncLoader("kernel32", "FreeLibrary").func();
std::string findMode;
std::cin >> findMode;
toLowerCase(findMode);
HANDLE hProcess = NULL;
if (findMode == "pid") {
DWORD pid;
std::cin >> pid;
hProcess = findtargetHandle(pid);
}
if (findMode == "name") {
std::wstring name;
std::wcin >> name;
LPCWSTR lname = name.c_str();
hProcess = findtargetHandle(lname);
}
if (!hProcess)
throw std::runtime_error("模式匹配失败");

DWORD pid = GetProcessId(hProcess);
HANDLE hModule = isLoaded(pid);
if (hModule == INVALID_HANDLE_VALUE || hModule == NULL)
{
std::cout << "目标进程 " << pid << " 没有该模块" << std::endl;
return;
}

HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, pfreelibrary, hModule, 0, NULL);
if (!hThread) {
throw std::runtime_error("远程线程创建失败");
}
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(hModule);
CloseHandle(hProcess);
}