2016-11-27 8 views
0

Итак, код, который я не могу изменить, вызывает исполняемый файл, и мне нужно дать ему разные аргументы командной строки, чем код черного кода. Я понял, что могу сделать исполняемый файл, чтобы служить в качестве прокси. proc.exe сидит там, где ожидает область черного ящика, принимает аргументы командной строки, изменяет их, а затем вызывает procReal.exe, исходный файл.CreateProcess Fails - Ошибка 183

К сожалению, CreateProcess, похоже, не запускается, возвращая статус 183. Я искал все, что мог, и не могу много узнать об этом. Попробовали перевернуть вещи, установив наследование дескриптора true, вручную указав рабочий каталог, не делая ни одной из этих вещей. Не повезло. Я предполагаю, что здесь что-то происходит, наследуя надлежащий контекст безопасности вызывающего приложения, поэтому обертка работает как правильная сквозная прослойка, но я не могу понять, как это сделать ...

Код ниже, нерелевантные разделы обрезаны ,

EDIT Поставьте полный код здесь после запроса. Это уже не имеет никакого смысла. Теперь он будет работать частично, но только если раздел fopen для traceFile не существует. Даже fprintfs не удалены, особенно весь раздел должен быть вырезан.

Я попытался ответить на комментарии каждого, и я думаю, что я исключил большинство из этих вещей как проблему, но я остался с текущим аномальным поведением. Что еще немного я мог прочитать, это говорит о том, что некоторые формы копирования строк могут привести к переполнению памяти, возможно ли это вообще?

#include <iostream> 
#include <fstream> 
#include <windows.h> 
#include <string> 
#include <vector> 
#include <stdio.h> 
#include <tchar.h> 
#include <algorithm> 
#include <string> 

using namespace std; 

bool caseInsensitiveStringCompare(const std::string& str1, const std::string& str2); 

int main(int argc, char* argv[]) { 

    const string path = "E:\\util\\bin\\"; 
    const string procName = "procReal.exe"; 
    const string argToFilter = "-t"; 


    string origValue; 
    string passedValue; 

    for(int i = 1; i < argc; i++) 
    { 
     origValue.append(" ").append(argv[i]); 
    } 

    for(int i = 1; i < argc; i++) 
    { 
     if (!caseInsensitiveStringCompare(argv[i],argToFilter)) 
     { 
      passedValue.append(" ").append(argv[i]); 
     } 
     else 
     { 
      i++; // skip over argument and it's value 
     } 

    } 

    const LPCTSTR exeModule = (path+procName).c_str(); 

    std::vector<char> chars(passedValue.c_str(), passedValue.c_str() + passedValue.size() + 1u); 
    LPTSTR exeArgs = &chars[0]; 


    STARTUPINFO si; 
    PROCESS_INFORMATION pi; 

    ZeroMemory(&si, sizeof(si)); 
    si.cb = sizeof(si); 
    ZeroMemory(&pi, sizeof(pi)); 

    GetStartupInfo(&si); 

    FILE* traceFile; 
    traceFile = fopen ((path+"lastRun.txt").c_str(), "w"); // This causes exeModule to change value for unknown reasons??? 
    fprintf(traceFile, "orig: %s%s\n", exeModule, origValue.c_str()); 
    fprintf(traceFile, "%s%s\n", exeModule, exeArgs); 

    SetLastError(0); 

    // Start the child process. 
    if(!CreateProcess(exeModule, // use module name with args for exeArgs 
     exeArgs,  // Command line 
     NULL,   // Process handle not inheritable 
     NULL,   // Thread handle not inheritable 
     TRUE,   // Set handle inheritance to FALSE 
     0,    // No creation flags 
     NULL,   // Use parent's environment block 
     NULL, // use parent's starting directory 
     &si,   // Pointer to STARTUPINFO structure 
     &pi)   // Pointer to PROCESS_INFORMATION structure 
    ) 
    { 
     FILE* myfile; 
     myfile = fopen ((path+"error.txt").c_str(), "w"); 
     fprintf(myfile, "CreateProcess failed (%d).\n", int(GetLastError())); 
     fclose(myfile); 
    } 

    // Wait until child process exits. 
    WaitForSingleObject(pi.hProcess, INFINITE); 

    DWORD exit_code; 
    GetExitCodeProcess(pi.hProcess, &exit_code); 

    fprintf(traceFile, "Exit Code: %d\n", int(exit_code)); 
    fclose(traceFile); 

    // Close process and thread handles. 
    CloseHandle(pi.hProcess); 
    CloseHandle(pi.hThread); 

    return exit_code; 
} 

bool caseInsensitiveStringCompare(const std::string& str1, const std::string& str2) { 
    std::string str1Cpy(str1); 
    std::string str2Cpy(str2); 
    std::transform(str1Cpy.begin(), str1Cpy.end(), str1Cpy.begin(), ::tolower); 
    std::transform(str2Cpy.begin(), str2Cpy.end(), str2Cpy.begin(), ::tolower); 
    return (str1Cpy == str2Cpy); 
} 
+0

код ошибки 183 означает «ERROR_ALREADY_EXISTS» –

+0

ли включен контроль учетных записей на вашем компьютере? нужно ли procReal.exe права администратора? есть ли у proc.exe их? Пробовали ли вы запустить его с отключенным UAC? ​​ – z32a7ul

+0

Базовый proc может запускаться напрямую без администратора ногами, да. – Vigilant

ответ

2

Наиболее очевидная проблема заключается в том, что вы не можете сказать (path+procName).c_str() потому, что временный объект строки, которую он строит отбрасываетесь сразу, недействительности возвращенного указателя. Я также очень сомневаюсь в том, что элементы vector обязательно последовательны.

Исправленная строка кода обработки должна выглядеть примерно так:

string passedValue(procName); // First element of command line MUST be module name 

    ... 

    const string exeModuleString(path + procName); 
    const LPCTSTR exeModule = exeModuleString.c_str(); 

    LPTSTR exeArgs = new char[passedValue.size() + 1]; 
    passedValue.copy(exeArgs, passedValue.size()); 
    exeArgs[passedValue.size()] = '\0'; 

(Это не может быть лучший способ сделать это, я не использую C++ часто Но он должен работать правильно. .)

исправленный код обработки ошибок, гарантируя, что последний код ошибки считывается сразу, должен выглядеть примерно так:

{ 
     DWORD err = GetLastError(); 
     FILE* myfile; 
     myfile = fopen ((path+"error.txt").c_str(), "w"); 
     fprintf(myfile, "CreateProcess failed (%d).\n", int(err)); 
     fclose(myfile); 
    } 

Ваш код сообщает о неправильном коде ошибки, так как вызов fopen() изменяет его. (Когда создается новый файл, который перезаписывает существующий файл, последний код ошибки устанавливается равным ERROR_ALREADY_EXISTS.)

Есть две более широкие проблемы, которые могут иметь значение или не имеют значения в вашем контексте. Во-первых, вы используете argv [] для создания командной строки для нового процесса; это означает, что синтаксический анализ командной строки (как описано в Parsing C Command-Line Arguments) будет применяться дважды (один раз вашим процессом и один раз дочерним), что может вызвать проблемы, если в командной строке содержатся специальные символы, такие как кавычки или обратные слеши. В идеале, в общем случае, вы бы назвали GetCommandLine(). (Конечно, это заставляет синтаксический разбор строки удалять дополнительный аргумент довольно сложнее.)

Во-вторых, вы, очевидно, создаете код в режиме ANSI. Это может вызвать проблемы, если в командной строке когда-либо содержались широкие («Юникод») символы.Общепризнано, что наилучшей практикой является всегда строить в режиме Unicode. Единственное существенное изменение, которое вам нужно внести в код, - это заменить string на wstring, поэтому оно должно быть достаточно простым.

+1

Элементы вектора гарантированы как последовательные, так как C++ 11. – Buster

+0

@Buster: спасибо. Насколько я понимаю, последняя версия Visual Studio * в основном совместима с C++ 11, так что часть исходного кода была, вероятно, ОК. –

+0

Это разобрало все или большинство моих проблем, особенно часть GetCommandLine(), спасибо! – Vigilant

0

У меня такая же проблема. Проблема, кажется, там, когда я вызываю исполняемые файлы без окна. я нашел 2 решения:

1. Создать летучей мыши файл с именем Термическое ехе, за которым следуют аргументы, , а затем запустите файл BAT: CreateProcess ("temp.bat", NULL, .. ..etc

2. использование _spawnl

 Смежные вопросы

  • Нет связанных вопросов^_^