#include <Windows.h> #include "detours.h" #include <string> #include <wchar.h> #include <filesystem> #include <Psapi.h> void ArgvQuote(const std::wstring&, std::wstring&, bool); void ShowError(DWORD); void ShowLastError(); int __stdcall wWinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nShowCmd ) { int retCode = 0; int numArgs = 0; LPWSTR* args = CommandLineToArgvW(lpCmdLine, &numArgs); if (numArgs < 2) { MessageBox(NULL, L"Provide at least a target and a AUMI", L"ERROR", MB_OK); return -1; } LPWSTR aumi = args[0]; LPWSTR cmd = args[1]; numArgs -= 2; if (numArgs == 0) { args = NULL; } else { args += 2; } std::wstring cmdLine; for (int i = 0; i < numArgs; i++) { if (cmdLine.length() > 0) cmdLine.push_back(L' '); ArgvQuote(std::wstring(args[i]), cmdLine, false); } wchar_t* cmdLineC = new wchar_t[cmdLine.length() + 1]; wcscpy_s(cmdLineC, cmdLine.length() + 1, cmdLine.c_str()); std::filesystem::path injectDll = std::filesystem::canonical(std::filesystem::path("InjectAUMI_64.dll")); std::string injectDllStr = injectDll.string(); //MessageBoxA(NULL, injectDllStr.c_str(), "Path", MB_OK); STARTUPINFO startupInfo; PROCESS_INFORMATION processInfo; ZeroMemory(&startupInfo, sizeof(startupInfo)); startupInfo.cb = sizeof(startupInfo); startupInfo.dwFlags |= STARTF_TITLEISAPPID; startupInfo.lpTitle = new wchar_t[5]; wcscpy_s(startupInfo.lpTitle, 5, L"TEST"); ZeroMemory(&processInfo, sizeof(processInfo)); HANDLE process; HMODULE* remoteModuleList; DWORD needed; int numModules; bool found = false; wchar_t* name = new wchar_t[1024]; const char* msg = "TestInjected"; bool requiresResume = false; //if (!DetourCreateProcessWithDllEx(cmd, cmdLineC, NULL, NULL, false, 0, NULL, NULL, &startupInfo, &processInfo, injectDllStr.c_str(), NULL)) if (!CreateProcess(cmd, cmdLineC, NULL, NULL, false, 0, NULL, NULL, &startupInfo, &processInfo/*, injectDllStr.c_str(), NULL*/)) { goto lastError; } process = processInfo.hProcess; /* HMODULE injected = LoadLibraryA(injectDllStr.c_str()); if (injected == NULL) { ShowLastError(); return -1; } FARPROC targetAddr = GetProcAddress(injected, "TestExport"); if (targetAddr == NULL) { ShowLastError(); return -1; } INT_PTR offset = (INT_PTR)targetAddr - (INT_PTR)injected; */ //Sleep(10000); //SuspendThread(processInfo.hThread); remoteModuleList = new HMODULE[1000]; needed = 0; if (!EnumProcessModules(process, remoteModuleList, 1000, &needed)) { goto lastError; } numModules = needed / sizeof(HMODULE); //for (int tries = 5; tries >= 0; tries--) //{ for (int i = 0; i < numModules; i++) { GetModuleFileNameEx(process, remoteModuleList[i], name, 1023); std::wstring modName(name); if (modName.find(L"InjectAUMI") != std::wstring::npos) { //MessageBox(NULL, L"Found", L"Found", MB_OK); const char* msg = "Message from here"; void* remoteMem = VirtualAllocEx(process, NULL, strlen(msg) + 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (remoteMem == NULL) { goto lastError; } else { MessageBox(NULL, L"Got mem", L"Info", MB_OK); } if (!WriteProcessMemory(process, remoteMem, msg, strlen(msg) + 1, NULL)) { goto lastError; } //ResumeThread(processInfo.hThread); /* HANDLE thread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)((INT_PTR)remoteModuleList[i] + offset), remoteMem, 0, NULL); if (thread == NULL) { goto lastError; } WaitForSingleObject(thread, INFINITE); DWORD ret = 0; GetExitCodeThread(thread, &ret); if (ret != 0) { char err[128]; sprintf_s(err, "Error from injected function: %d", ret); MessageBoxA(NULL, err, "Error", MB_OK); goto quitError; } */ found = true; break; } } // if (found) break; // Sleep(1000); //} ResumeThread(processInfo.hThread); if (!found) { MessageBox(NULL, L"Couldn't find injected dll", L"Error", MB_OK); goto quitError; } else { MessageBox(NULL, L"Was Found", L"Info", MB_OK); } MessageBox(NULL, L"Done", L"Done", MB_OK); return 0; lastError: ShowLastError(); quitError: retCode = -1; goto cleanup; cleanup: if (requiresResume) ResumeThread(processInfo.hThread); return retCode; } void ArgvQuote( const std::wstring& Argument, std::wstring& CommandLine, bool Force ) /*++ Routine Description: This routine appends the given argument to a command line such that CommandLineToArgvW will return the argument string unchanged. Arguments in a command line should be separated by spaces; this function does not add these spaces. Arguments: Argument - Supplies the argument to encode. CommandLine - Supplies the command line to which we append the encoded argument string. Force - Supplies an indication of whether we should quote the argument even if it does not contain any characters that would ordinarily require quoting. Return Value: None. Environment: Arbitrary. --*/ { // // Unless we're told otherwise, don't quote unless we actually // need to do so --- hopefully avoid problems if programs won't // parse quotes properly // if (Force == false && Argument.empty() == false && Argument.find_first_of(L" \t\n\v\"") == Argument.npos) { CommandLine.append(Argument); } else { CommandLine.push_back(L'"'); for (auto It = Argument.begin(); ; ++It) { unsigned NumberBackslashes = 0; while (It != Argument.end() && *It == L'\\') { ++It; ++NumberBackslashes; } if (It == Argument.end()) { // // Escape all backslashes, but let the terminating // double quotation mark we add below be interpreted // as a metacharacter. // CommandLine.append((size_t)NumberBackslashes * 2, L'\\'); break; } else if (*It == L'"') { // // Escape all backslashes and the following // double quotation mark. // CommandLine.append((size_t)NumberBackslashes * 2 + 1, L'\\'); CommandLine.push_back(*It); } else { // // Backslashes aren't special here. // CommandLine.append(NumberBackslashes, L'\\'); CommandLine.push_back(*It); } } CommandLine.push_back(L'"'); } } void ShowLastError() { ShowError(GetLastError()); } void ShowError(DWORD error) { LPTSTR err; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, (LPTSTR)&err, 0, NULL); MessageBoxW(NULL, err, L"Error", MB_OK); }