Advertisement
Inquisitor

easy_spawner source

Jul 2nd, 2019
520
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.55 KB | None | 0 0
  1. // Замена для hidcon, функциональный аналог + возврат PID дочернего процесса в STDOUT, без блокировки основного потока
  2. #define _CRT_SECURE_NO_WARNINGS
  3. #include <Windows.h>
  4.  
  5. #include <algorithm>
  6. #include <iterator>
  7. #include <string>
  8. #include <sstream>
  9. #include <vector>
  10.  
  11. bool fileExist(const char* path) {
  12.   if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(path) && GetLastError() == ERROR_FILE_NOT_FOUND) {
  13.     return false;
  14.   }
  15.  
  16.   return true;
  17. }
  18.  
  19. std::vector<std::string> getSystemPath() {
  20.   std::vector<std::string> result;
  21.  
  22.   char* path = getenv("PATH");
  23.   std::stringstream ss(path);
  24.   std::string token;
  25.   while (std::getline(ss, token, ';')) {
  26.     result.push_back(token);
  27.   }
  28.  
  29.   return result;
  30. }
  31.  
  32. std::string getAppName(int argc, char* argv[]) {
  33.   if (argc <= 0) {
  34.     return "";
  35.   }
  36.  
  37.   std::string appName = argv[0];
  38.   const size_t i = appName.find_last_of("\\/");
  39.   if (i != std::string::npos) {
  40.     appName.erase(0, i + 1);
  41.   }
  42.  
  43.   return appName;
  44. }
  45.  
  46. std::string getTargetPath(int argc, char* argv[]) {
  47.   if (argc <= 1) {
  48.     return "";
  49.   }
  50.  
  51.   if (fileExist(argv[1])) {
  52.     return argv[1];
  53.   }
  54.  
  55.   std::string targetPath = argv[1];
  56.   std::vector<std::string> systemPath = getSystemPath();
  57.   for (size_t i = 0; i < systemPath.size(); i++) {
  58.     std::string newPath = systemPath[i] + "\\" + targetPath;
  59.     if (fileExist(newPath.c_str())) {
  60.       return newPath;
  61.     }
  62.   }
  63.  
  64.   return argv[1];
  65. }
  66.  
  67. std::string getTargetArgs(int argc, char* argv[]) {
  68.   if (argc <= 2) {
  69.     return "";
  70.   }
  71.  
  72.   std::string targetArgs = argv[2];
  73.   for (int i = 3; i < argc; i++) {
  74.     targetArgs += " ";
  75.     targetArgs += argv[i];
  76.   }
  77.  
  78.   return targetArgs;
  79. }
  80.  
  81. bool recursion(const std::string &appName, const std::string &targetPath) {
  82.   std::string targetName = targetPath;
  83.   const size_t i = targetName.find_last_of("\\/");
  84.   if (i != std::string::npos) {
  85.     targetName.erase(0, i + 1);
  86.   }
  87.  
  88.   if (appName == targetName) {
  89.     return true;
  90.   }
  91.  
  92.   return false;
  93. }
  94.  
  95. bool spawnProcess(const std::string& targetPath, const std::string& targetArgs) {
  96.   // additional information
  97.   STARTUPINFO si;
  98.   PROCESS_INFORMATION pi;
  99.  
  100.   // set the size of the structures
  101.   ZeroMemory(&si, sizeof(si));
  102.   si.cb = sizeof(si);
  103.   ZeroMemory(&pi, sizeof(pi));
  104.  
  105.   std::string command = "\"" + targetPath + "\" " + targetArgs;
  106.   // start the program up
  107.   if (CreateProcess(NULL,                    // the path
  108.     const_cast<LPSTR>(command.c_str()),    // Command line
  109.     NULL,                                  // Process handle not inheritable
  110.     NULL,                                  // Thread handle not inheritable
  111.     FALSE,                                 // Set handle inheritance to FALSE
  112.     CREATE_NO_WINDOW | DETACHED_PROCESS,   // No creation flags
  113.     NULL,                                  // Use parent's environment block
  114.     NULL,                                  // Use parent's starting directory
  115.     &si,                                   // Pointer to STARTUPINFO structure
  116.     &pi                                    // Pointer to PROCESS_INFORMATION structure
  117.   )) {
  118.     fprintf(stdout, "%lu\n", pi.dwProcessId);
  119.     fflush(stdout);
  120.  
  121.     // Close process and thread handles.
  122.     CloseHandle(pi.hProcess);
  123.     CloseHandle(pi.hThread);
  124.  
  125.     return true;
  126.   } else {
  127.     DWORD errorMessageID = GetLastError();
  128.     LPSTR messageBuffer = nullptr;
  129.     size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  130.       NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)& messageBuffer, 0, NULL);
  131.  
  132.     std::string message(messageBuffer, size);
  133.     LocalFree(messageBuffer);
  134.  
  135.     fprintf(stderr, "%lu\nProblem with spawning process: %s\n", errorMessageID, message.c_str());
  136.  
  137.     return false;
  138.   }
  139. }
  140.  
  141. int main(int argc, char* argv[]) {
  142.   std::string appName = getAppName(argc, argv);
  143.   if (appName.empty()) {
  144.     fprintf(stderr, "0\nOoops, can't determine app name, something really wrong here!\n");
  145.     return 1;
  146.   }
  147.  
  148.   std::string targetPath = getTargetPath(argc, argv);
  149.   if (targetPath.empty()) {
  150.     fprintf(stderr, "0\nTarget app path empty, nothing to start.\n");
  151.     return 1;
  152.   }
  153.   if (recursion(appName, targetPath)) {
  154.     fprintf(stderr, "0\nPossible recursion detected, aborting.\n");
  155.     return 1;
  156.   }
  157.  
  158.   std::string targetArgs = getTargetArgs(argc, argv);
  159.   if (!spawnProcess(targetPath, targetArgs)) {
  160.     return 1;
  161.   }
  162.  
  163.   return 0;
  164. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement