该程序首先查找自己的父进程,如果父进程是cmd或者powershell,则向父进程注入一个dll,让父进程输出“Hello World!”。
dllmain.cpp
1 #include <Windows.h> 2 #include <cstdio> 3 4 BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID) 5 { 6 if (fdwReason == DLL_PROCESS_ATTACH) 7 { 8 HANDLE hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); 9 DWORD dwOutputMode; 10 if (!GetConsoleMode(hStdOutput, &dwOutputMode)) 11 { 12 puts("GetConsoleMode() fail."); 13 } 14 dwOutputMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; 15 if (!SetConsoleMode(hStdOutput, dwOutputMode)) 16 { 17 puts("SetConsoleMode() fail."); 18 } 19 puts("\x1b[31mHello World!\x1b[0m"); 20 } 21 return TRUE; 22 }
main.cpp
1 #include <Windows.h> 2 #include <TlHelp32.h> 3 #include <cstdio> 4 #include <cstring> 5 #include <process.h> 6 7 DWORD GetParentProcessId(DWORD dwProcessID) 8 { 9 HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 10 if (!hProcessSnap) 11 { 12 puts("CreateToolhelp32Snapshot() fail."); 13 exit(1); 14 } 15 PROCESSENTRY32 pe = { 0 }; 16 pe.dwSize = sizeof(PROCESSENTRY32); 17 if (!Process32First(hProcessSnap, &pe)) 18 { 19 puts("Process32First() fail."); 20 exit(1); 21 } 22 DWORD dwParentProcessID = 0; 23 do 24 { 25 if (pe.th32ProcessID == dwProcessID) 26 { 27 dwParentProcessID = pe.th32ParentProcessID; 28 } 29 } while (Process32Next(hProcessSnap, &pe)); 30 CloseHandle(hProcessSnap); 31 return dwParentProcessID; 32 } 33 34 PTHREAD_START_ROUTINE pLoadLibrary; 35 PTHREAD_START_ROUTINE pFreeLibrary; 36 37 void LoadLibraryRemote(HANDLE hProcess, PCWSTR wcsDllName) 38 { 39 SIZE_T nSize = (wcslen(wcsDllName) + 1) * sizeof(WCHAR); 40 PVOID wcsDllNameRemote = VirtualAllocEx(hProcess, NULL, nSize, MEM_COMMIT, PAGE_READWRITE); 41 if (!wcsDllNameRemote) 42 { 43 puts("VirtualAllocEx() fail."); 44 exit(1); 45 } 46 if (!WriteProcessMemory(hProcess, wcsDllNameRemote, wcsDllName, nSize, NULL)) 47 { 48 puts("WriteProcessMemory() fail."); 49 exit(1); 50 } 51 HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, pLoadLibrary, wcsDllNameRemote, NULL, NULL); 52 if (!hThread) 53 { 54 puts("CreateRemoteThread() fail."); 55 } 56 WaitForSingleObject(hThread, INFINITE); 57 VirtualFreeEx(hProcess, wcsDllNameRemote, 0, MEM_RELEASE); 58 CloseHandle(hThread); 59 } 60 61 void FreeLibraryRemote(HANDLE hProcess, PCWSTR wcsDllName) 62 { 63 DWORD dwProcessID = GetProcessId(hProcess); 64 HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessID); 65 if (!hModuleSnap) 66 { 67 puts("CreateToolhelp32Snapshot() fail."); 68 exit(1); 69 } 70 MODULEENTRY32 me = { 0 }; 71 me.dwSize = sizeof(MODULEENTRY32); 72 if (!Module32First(hModuleSnap, &me)) 73 { 74 puts("Module32First() fail."); 75 exit(1); 76 } 77 PVOID hMod = NULL; 78 do 79 { 80 if (!_wcsicmp(me.szModule, wcsDllName)) 81 { 82 hMod = me.hModule; 83 break; 84 } 85 } while (Module32Next(hModuleSnap, &me)); 86 if (!hMod) 87 { 88 puts("Assertion fail. Module not found."); 89 exit(1); 90 } 91 HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, pFreeLibrary, hMod, NULL, NULL); 92 if (!hThread) 93 { 94 puts("CreateRemoteThread() fail."); 95 exit(1); 96 } 97 WaitForSingleObject(hThread, INFINITE); 98 CloseHandle(hModuleSnap); 99 CloseHandle(hThread); 100 } 101 102 int main() 103 { 104 HMODULE hMod = GetModuleHandle(L"kernel32"); 105 if (!hMod) 106 { 107 puts("GetModuleHandle() fail."); 108 exit(1); 109 } 110 pLoadLibrary = (PTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW"); 111 if (!pLoadLibrary) 112 { 113 puts("GetProcAddress() fail."); 114 exit(1); 115 } 116 pFreeLibrary = (PTHREAD_START_ROUTINE)GetProcAddress(hMod, "FreeLibrary"); 117 if (!pLoadLibrary) 118 { 119 puts("GetProcAddress() fail."); 120 exit(1); 121 } 122 DWORD dwCurrentProcessID = GetCurrentProcessId(); 123 DWORD dwParentProcessID = GetParentProcessId(dwCurrentProcessID); 124 if (dwParentProcessID == 0) 125 { 126 puts("Assertion fail. Parent process not exist."); 127 exit(1); 128 } 129 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwParentProcessID); 130 if (!hProcess) 131 { 132 puts("OpenProcess() fail."); 133 exit(1); 134 } 135 WCHAR wcsImageName[256]; 136 DWORD dwSize; 137 if (!QueryFullProcessImageName(hProcess, 0, wcsImageName, &dwSize)) 138 { 139 puts("QueryFullProcessImageName() fail."); 140 exit(1); 141 } 142 if (!wcsstr(wcsImageName, L"cmd.exe") && !wcsstr(wcsImageName, L"powershell.exe")) 143 { 144 puts("Assertion fail. Parent process neither cmd nor powershell."); 145 exit(1); 146 } 147 WCHAR wcsDllName[] = L"HelloWorld.dll"; 148 LoadLibraryRemote(hProcess, wcsDllName); 149 FreeLibraryRemote(hProcess, wcsDllName); 150 CloseHandle(hProcess); 151 }
编译命令
%CC% -shared dllmain.cpp -o HelloWorld.dll
%CC% main.cpp -o HelloWorld.exe