这一篇拖了比较久,因为之前不理解进程的权限令牌的作用,看逆向工程核心原理的时候发现注入不需要权限但是卸载却需要,书里面还没详细说,就一直搁置了,前几周学了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); }
|