[C++] Стандартный файрволл на Windows не байпассится

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by id01, 12 Jul 2017.

  1. id01

    id01 New Member

    Joined:
    12 Jul 2017
    Messages:
    6
    Likes Received:
    0
    Reputations:
    0
    Кодю на плюсиках. Есть вот такая функция:

    Code:
    int SetFirewallException(HWND alertwindow)
    {
        if (alertwindow != NULL) {
            if (BringWindowToTop(alertwindow)) {
                DWORD dwCurrentThread = GetCurrentThreadId();
                DWORD dwFGTThread = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
                AttachThreadInput(dwCurrentThread, dwFGTThread, TRUE);
                SetForegroundWindow(alertwindow);
                int x = 0;
                INPUT ip;
                    ip.type = INPUT_KEYBOARD;
                    ip.ki.wScan = 0;
                    ip.ki.time = 0;
                    ip.ki.dwExtraInfo = 0;
                for (; x < 6; x++){
                    ip.ki.wVk = 0x09;
                    ip.ki.dwFlags = 0;
                    SendInput(1, &ip, sizeof(INPUT));
                    ip.ki.dwFlags = KEYEVENTF_KEYUP;
                    SendInput(1, &ip, sizeof(INPUT));
                }
                if (x == 6){
                    ip.ki.wVk = 0x0D;
                    ip.ki.dwFlags = 0;
                    SendInput(1, &ip, sizeof(INPUT));
                    ip.ki.dwFlags = KEYEVENTF_KEYUP;
                    SendInput(1, &ip, sizeof(INPUT));
                }
            }
            else return 1;
        }
        else return 1;
        return 0;
    }
    
    При запуске приложения все срабатывает и исключение добавляется. Но есть одно маленькое но. По умолчанию в окошке брандмауэра отмечена только одна галочка (тестирую на десятке), что надо бы поправить. Если я переписываю функцию вот так:

    Code:
    int SetFirewallException(HWND alertwindow)
    {
        if (alertwindow != NULL) {
            if (BringWindowToTop(alertwindow)) {
                DWORD dwCurrentThread = GetCurrentThreadId();
                DWORD dwFGTThread = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
                AttachThreadInput(dwCurrentThread, dwFGTThread, TRUE);
                SetForegroundWindow(alertwindow);
                int x = 0;
                INPUT ip;
                    ip.type = INPUT_KEYBOARD;
                    ip.ki.wScan = 0;
                    ip.ki.time = 0;
                    ip.ki.dwExtraInfo = 0;
                for (; x < 4; x++){
                    ip.ki.wVk = 0x09;
                    ip.ki.dwFlags = 0;
                    SendInput(1, &ip, sizeof(INPUT));
                    ip.ki.dwFlags = KEYEVENTF_KEYUP;
                    SendInput(1, &ip, sizeof(INPUT));
                }
                if (x == 4){
                    ip.ki.wVk = 0x0D;
                    ip.ki.dwFlags = 0;
                    SendInput(1, &ip, sizeof(INPUT));
                    ip.ki.dwFlags = KEYEVENTF_KEYUP;
                    SendInput(1, &ip, sizeof(INPUT));
                }
                for (; x < 6; x++){
                    ip.ki.wVk = 0x09;
                    ip.ki.dwFlags = 0;
                    SendInput(1, &ip, sizeof(INPUT));
                    ip.ki.dwFlags = KEYEVENTF_KEYUP;
                    SendInput(1, &ip, sizeof(INPUT));
                }
                if (x == 6){
                    ip.ki.wVk = 0x0D;
                    ip.ki.dwFlags = 0;
                    SendInput(1, &ip, sizeof(INPUT));
                    ip.ki.dwFlags = KEYEVENTF_KEYUP;
                    SendInput(1, &ip, sizeof(INPUT));
                }
            }
            else return 1;
        }
        else return 1;
        return 0;
    }
    
    То магическим образом сразу нихрена не работает. То есть если заставить программу нажимать на галку, то все, капут. Так не каеф. Поможете нерадивому кодеру?
     
    #1 id01, 12 Jul 2017
    Last edited: 12 Jul 2017
  2. binarymaster

    binarymaster Elder - Старейшина

    Joined:
    11 Dec 2010
    Messages:
    4,717
    Likes Received:
    10,195
    Reputations:
    126
    Не проще ли вместо всех этих извращений с эмуляцией ввода с клавиатуры просто сделать новую запись исключения брандмауэра в реестр?
     
    id01 and #colorblind like this.
  3. id01

    id01 New Member

    Joined:
    12 Jul 2017
    Messages:
    6
    Likes Received:
    0
    Reputations:
    0
    Пффффффффф, научите
     
  4. binarymaster

    binarymaster Elder - Старейшина

    Joined:
    11 Dec 2010
    Messages:
    4,717
    Likes Received:
    10,195
    Reputations:
    126
  5. id01

    id01 New Member

    Joined:
    12 Jul 2017
    Messages:
    6
    Likes Received:
    0
    Reputations:
    0
    Ну хорошо, это возможно и даже вполне неплохая идея. Но как насчет перезагрузки? Для применения ведь придется перезагрузить пк? Или я не прав?
     
  6. binarymaster

    binarymaster Elder - Старейшина

    Joined:
    11 Dec 2010
    Messages:
    4,717
    Likes Received:
    10,195
    Reputations:
    126
    Недавно проверял, срабатывает сразу.
     
    id01 likes this.
  7. id01

    id01 New Member

    Joined:
    12 Jul 2017
    Messages:
    6
    Likes Received:
    0
    Reputations:
    0
    Ну, написал я, значит, что надо.

    Code:
    int SetFirewallExceptionByReg(const char* pathToExe)
    {
        string value = "v2.10|Action=Allow|Active=TRUE|Dir=In|Protocol=6|Profile=Private|Profile=Public|App=";
        value += Quotes(pathToExe);
        value += "|Name=run|Desc=run|Defer=User|";
     
        cout << "value: " << value << endl;
     
        int res;
        HKEY hKey;
     
        res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\FirewallRules", 0, KEY_SET_VALUE, &hKey);
        cout << "res: " << res << endl;
     
        res = RegSetValueEx(hKey, "TCP Query User Run.exe", 0, REG_SZ, (BYTE*)value.c_str(), (DWORD) ((lstrlen(value.c_str())+1)*sizeof(TCHAR)));
        cout << "res 2: " << res << endl;
     
        RegCloseKey(hKey);
    }
    
    res выдает 5 - Access is denied. (Что есть печально)
    res 2 выдает 6 - The handle is invalid. (Что есть логично)

    Говорите, у вас работало? А как быть без админских прав? Пока что проект вполне прилично работал и без них, не хотелось впихивать повышение прав... Теперь извращение с эмуляцией ввода смотрится вполне прилично, по сравнению с неработающим примером.

    P.s. А что это за лабуда: "{302A64E1-C42D-4819-A94C-535740A8F0FF}"? Находилось в середине имени ключа в реестре. Если этот метод заработает, то имя не важно, или придется как-то такое вот лепить?
     
  8. binarymaster

    binarymaster Elder - Старейшина

    Joined:
    11 Dec 2010
    Messages:
    4,717
    Likes Received:
    10,195
    Reputations:
    126
    Гуглите UAC bypass, вроде до сих пор не закрыли эту дыру, даже в Win 10.
    Вроде имя может быть любым, и даже не обязательно уникальным. CLSID нужен.
     
  9. id01

    id01 New Member

    Joined:
    12 Jul 2017
    Messages:
    6
    Likes Received:
    0
    Reputations:
    0
    Дык при чем тут UAC? Вроде же прав не хватает. У вас точно нет идей на счет эмуляции ввода? :)

    То есть вот это вот лепить надо - {302A64E1-C42D-4819-A94C-535740A8F0FF}. А где его брать или как он генерируется?
     
  10. binarymaster

    binarymaster Elder - Старейшина

    Joined:
    11 Dec 2010
    Messages:
    4,717
    Likes Received:
    10,195
    Reputations:
    126
    Если запущено под админом, то нехватка прав может быть только из-за UAC.

    В противном случае (под простым пользователем) правила добавлять не получится.
    Сейчас не помню, ответ должен быть в реестре.