Auf Beendigung des letzten Threads warten...



  • Naja, das argc ist eh wackelig.
    Was, wenn 1 Argument übergeben wird, d.h. argc==2.

    Dann: n1 == (2-1)/2 == 1/2 == 0

    VLAs der Größe 0 sind doch nicht erlaubt, oder? Aber auch egal, denn:
    for (int i = 1; i < argc; i += 2) ist dann 1 < 2 im ersten Durchlauf, also true, und dann crasht es eben danach - sowohl beim atoi(argv[i + 1]); als auch beim handles[0] = ....


  • Gesperrt

    Vielen Dank für eure Ideen und Vorschläge, ich werde das nachher miteinbeziehen und eine neue Version posten. @SeppJ Sorry, dass ich dich angemault hatte, das wollte ich nicht.

    Schönen Abend. 🙂


  • Gesperrt

    Btw. die eigene, ausführbare exe Datei kreidet mir Windows als Virus an, wenn ich sie ins Internet hochladen, und wieder herunterladen möchte, und verhindert den kompletten Download... Virustotal meldet "sauber".

    Was ist so brisant an diesen Code?

    Kann man in diesem Forum einen Dateianhang hinzufügen?



  • @EinNutzer0 sagte in Auf Beendigung des letzten Threads warten...:

    kreidet mir Windows als Virus an

    Genaue Meldung? Copy&Paste.


  • Mod

    @EinNutzer0 sagte in Auf Beendigung des letzten Threads warten...:

    Kann man in diesem Forum einen Dateianhang hinzufügen?

    Nein. Wenn es wirklich wichtig ist, kannst du einen externen Hoster nutzen und verlinken. Falls dein Plan ist, dass sich jemand deine Executable runterlädt oder gar ausführt: Das wird wahrscheinlich niemand tun.


  • Gesperrt




  • Gesperrt

    Posting here is generally a waste of time, since no one here truly works for Microsoft, especially the more technical security groups involved in the operation and support for Defender itself. We're all mostly either consumer volunteers or contract workers who provide first-level support for Microsoft's products.

    🤪

    Heißt auf Deutsch, der KI, Heuristik oder wie man es nennen möchte, gefällt nicht, was ich tue. Aber ich freue mich, meinen ersten eigenen Virus entworfen zu haben. 🙂 (Sogar schwerwiegend...)


  • Gesperrt

    Jetzt funktioniert's, Freunde:

    #include <windows.h>
    #include <iostream>
    #include <string>
    
    #include <chrono>
    #include <thread>
    
    DWORD WINAPI myThread(LPVOID lpParameter)
    {
        using namespace std;
        char* argv = *((char**)lpParameter);
        chrono::milliseconds ms1 = chrono::duration_cast<chrono::milliseconds>(
            chrono::system_clock::now().time_since_epoch());
    
        SHELLEXECUTEINFO ShExecInfo = { 0 };
        ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
        ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
        ShExecInfo.hwnd = NULL;
        ShExecInfo.lpVerb = NULL;
        ShExecInfo.lpFile = argv;
        ShExecInfo.lpParameters = "";
        ShExecInfo.lpDirectory = NULL;
        ShExecInfo.nShow = SW_SHOW;
        ShExecInfo.hInstApp = NULL;
        ShellExecuteEx(&ShExecInfo);
        WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
    
        chrono::milliseconds ms2 = chrono::duration_cast<chrono::milliseconds>(
            chrono::system_clock::now().time_since_epoch());
        cout << argv << " : ";
        cout << GetProcessId(ShExecInfo.hProcess) << " : ";
        cout << (ms2 - ms1).count() << " Milliseconds" << endl;
        return 0;
    }
    
    int main(int argc, char* argv[])
    {
        if (argc <= 1 || argc % 2 != 1) {
            return 0;
        }
        using namespace std;
        const int n1 = (argc - 1) / 2;
        HANDLE handles[n1];
        for (int i = 1; i < argc; i += 2) {
            int sleepTime = atoi(argv[i + 1]);
            DWORD myThreadID;
            handles[(i - 1) / 2] = CreateThread(0, 0, myThread, &argv[i], 0, &myThreadID);
            this_thread::sleep_for(chrono::seconds(sleepTime));
        }
        WaitForMultipleObjects(n1, handles, TRUE, INFINITE);
        for (int i = 0; i < n1; i++) {
            CloseHandle(handles[i]);
        }
        return 0;
    }
    

    War echt so, dass die garbage collection gegriffen hat... Btw. warum muss ich erst nach char** und dann nach * casten? LPVOID, DWORD und WINAPI ist mir sehr suspekt.



  • @EinNutzer0 sagte in Auf Beendigung des letzten Threads warten...:

    garbage collection

    what?

    @EinNutzer0 sagte in Auf Beendigung des letzten Threads warten...:

    Btw. warum muss ich erst nach char** und dann nach * casten?

    Warum übergibst du überhaupt &argv[i] und nicht argv[i]?


  • Gesperrt

    @Swordfish sagte in Auf Beendigung des letzten Threads warten...:

    Warum übergibst du überhaupt &argv[i] und nicht argv[i]?

    Ja, das frage ich mich auch... Ich habe Teile von diesem myThread example aus einem Blog kopiert, ich glaube, derjenige wusste auch nicht bescheid...


  • Gesperrt

    Also, hier ist der Vollständigkeit halber noch mal das gesamte Programm:

    #include <windows.h>
    #include <iostream>
    #include <string>
    
    #include <chrono>
    #include <thread>
    
    DWORD WINAPI myThread(LPVOID lpParameter)
    {
        using namespace std;
        char* argv = (char*)lpParameter;
        chrono::milliseconds ms1 = chrono::duration_cast<chrono::milliseconds>(
            chrono::system_clock::now().time_since_epoch());
    
        SHELLEXECUTEINFO ShExecInfo = { 0 };
        ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
        ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
        ShExecInfo.hwnd = NULL;
        ShExecInfo.lpVerb = NULL;
        ShExecInfo.lpFile = argv;
        ShExecInfo.lpParameters = "";
        ShExecInfo.lpDirectory = NULL;
        ShExecInfo.nShow = SW_SHOW;
        ShExecInfo.hInstApp = NULL;
        ShellExecuteEx(&ShExecInfo);
        WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
    
        chrono::milliseconds ms2 = chrono::duration_cast<chrono::milliseconds>(
            chrono::system_clock::now().time_since_epoch());
        cout << argv << " : ";
        cout << GetProcessId(ShExecInfo.hProcess) << " : ";
        cout << (ms2 - ms1).count() << " Milliseconds" << endl;
        return 0;
    }
    
    int main(int argc, char* argv[])
    {
        if (argc <= 1 || argc % 2 != 1) {
            return 0;
        }
        using namespace std;
        const int n1 = (argc - 1) / 2;
        HANDLE handles[n1];
        for (int i = 1; i < argc; i += 2) {
            int sleepTime = atoi(argv[i + 1]);
            DWORD myThreadID;
            handles[(i - 1) / 2] = CreateThread(0, 0, myThread, argv[i], 0, &myThreadID);
            this_thread::sleep_for(chrono::seconds(sleepTime));
        }
        WaitForMultipleObjects(n1, handles, TRUE, INFINITE);
        for (int i = 0; i < n1; i++) {
            CloseHandle(handles[i]);
        }
        return 0;
    }
    

    Es funktioniert, aber ist es auch schön?


Anmelden zum Antworten