Wie starte ich eine executable?



  • Mit protablem standard C++ geht das nicht.
    Ansonsten geht es oft so in der Art:

    void loader(char const* path)
    {
        FILE* f = fopen(path, "rb");
        fseek(f, 0, SEEK_END);
        long len = ftell(f);
    
        std::vector<char> code(len);
        fseek(f, 0, SEEK_SET);
        fread(&code[0], 1, len, f);
    
        typedef void voidfun();
        voidfun* funptr = (voidfun*)(&code[0]); // hier 1x dick und fett non-standard C++ (was aber viele compiler unterstützen).
                                                // nämlich einen datenzeiger zu einem funktionszeiger zu casten
        funptr(); // die calling convention und die erwarteten parameter müssen passen, sonst klescht es hier
    }
    

    Natürlich klappt das nur wenn der Code relozierbar ("position independent") ist, und wenn das OS und die CPU es erlauben Bytes in einem Datensegment als Code auszuführen.

    Damit bekommst du die OS-unabhängigen Viren von denen du vermutlich träumst aber auch nicht gebacken 😉



  • danke besonders für den letzten Beitrag!

    läuft so nicht auch ein Emulator ab?
    Nur das er halt den op-Code übersetzt?

    "Natürlich klappt das nur wenn der Code relozierbar ("position independent") ist, und wenn das OS und die CPU es erlauben Bytes in einem Datensegment als Code auszuführen."

    und wenn eines von denen mal nicht zutreffen sollte->gibts dann überhaupt noch Hoffnung, oder ist es um es klar zu sagen selbst für Profis dann so gut wie unmöglich?



  • Um in einem richtigen Betriebssystem Code ausführen zu können muss die Page(s) in welcher der Code steht als ausführbar markiert sein, sonst läuft da gar nichts.

    Benutze einfach die Möglichkeiten des entsprechenden Betriebssystems, die bieten alle die Möglichkeit Code in den speicher zu laden und ihn ausführen.



  • Ich will sichergehen, dass ich nichts falsch verstanden habe...deshalb lies dir bitte folgendes kurz durch und korrigier mich:

    std::vector<char> code(len);
    fseek(f, 0, SEEK_SET);
    fread(&code[0], 1, len, f);

    std::vector<char> code(len);
    du erstellst einen Vector aus char(->also 1Byte groß: aber wieso genau 1byte?)
    in der im ersten Feld die Größe der Datei steht->len
    wieso im ersten vector die Größe der Datei?~

    fseek(f, 0, SEEK_SET);
    was bringt diese Zeile überhaupt?

    fread(&code[0], 1, len, f);
    in den ersten Vektor schreibst du nun len mal 1Byte(wieder->wieso 1Byte?) rein.
    wieso jetzt aber in den ersten vektor den gesamten Code reinschreiben???

    letzter Teil ist ein Funktions-Zeiger->dachte immer, die gehörten zu c++ dazu^^
    naja, so lernt man eben...

    hoffe, du kannst mir diese drei Zeilen näher erleutern 🙂

    EDIT:
    zweite Zeile hat sich beim zweiten durchlesen erledigt;)

    fehlt noch:
    std::vector<char> code(len);
    und
    fread(&code[0], 1, len, f);

    EDIT2:
    man lädt den fertigen Maschinencode in einen vector und führt diesen dann aus?
    ->ddeshalb Konvertierung in eine Funktion?
    ->muss es ein Vektor sein, oder welche besondere Eigenschaft hat er, dass man nicht bspw. ein Array aus char hätte verwenden können?

    ->In Windows funktionierts auf die schnelle nicht->war damit zu rechnen oder wäre der Code vielleicht noch ein wenig an Feinabstimmung bedarflich?

    EDIT3:
    achja, und sollte denn nicht eigentlich von der Boot-Address aus angefangen werden, den Maschinen-Code zu lesen?
    Weil Header-Informationen etc. sind ja eigentlich nicht für die CPU direkt gedacht, sondern sowas wie Zusatz-Informationen(mitunter halt auch wichtige...)



  • *push*



  • Dark_DanI schrieb:

    *push*

    Lern besser mal richtig Fragen stellen und auch den Quote-Button. So kommt niemand draus, was du willst.
    Dann kriegst du auch Antworten, aber bei dem Gewurst dort oben vergeht einem die Lust gleich wieder. 😉



  • drakon schrieb:

    Dark_DanI schrieb:

    *push*

    Lern besser mal richtig Fragen stellen und auch den Quote-Button. So kommt niemand draus, was du willst.
    Dann kriegst du auch Antworten, aber bei dem Gewurst dort oben vergeht einem die Lust gleich wieder. 😉

    tut mir leid 😞

    hier die Fragen einzeln aufgelistet:

    std::vector<char> code(len); //zur 1. Frage
    fread(&code[0], 1, len, f); //zur 2. Frage

    -wieso im ersten Vektor die Größe der Datei?~
    -wieso in den ersten Vektor den gesamten Code reinschreiben???
    -Muss es ein Vektor sein, oder wäre ein char-Array auch ausreichend?
    -gehören Funktions-Zeiger nicht zu c++(oder zu c)?

    -Wird alles in Allem der Maschinen-Code in eine Funktion konvertiert?
    -Das das in Windows mit einer normalen exe nicht funktioniert, war doch klar, oder?
    ->hätte ich nicht die ganze exe einlesen sollen, sondern nur AB DEM BOOT-Code?
    ->oder lässt Windows sowas einfach nicht zu?



  • hallo

    -wieso im ersten Vektor die Größe der Datei?

    da ist nur ein vector und mit der größe wird der speicehrplatz reserviert

    -wieso in den ersten Vektor den gesamten Code reinschreiben???

    wohin den sonst ? mann muss ja irgentwie den code in den speicher bekommen

    -Muss es ein Vektor sein, oder wäre ein char-Array auch ausreichend?

    ein char array wäre ausreichend aber die vectorklasse ist leichter zu benutzen

    -gehören Funktions-Zeiger nicht zu c++(oder zu c)?

    doch zu C (und damit auch zu c++)

    -Wird alles in Allem der Maschinen-Code in eine Funktion konvertiert?

    ja

    -Das das in Windows mit einer normalen exe nicht funktioniert, war doch klar, oder?

    weil in einer .exe nichtnur code sondern auch daten wie stringliterale oder
    importierte funktionen stehen + header am anfang. in einer .com würden nur
    die daten stehen

    ->hätte ich nicht die ganze exe einlesen sollen, sondern nur AB DEM BOOT-Code?

    du müsstest dich über den aufbau einer exe informieren, ab da laden

    ->oder lässt Windows sowas einfach nicht zu?

    doch man kann datensegmente auch ausführen, das geht (habs schon getestet)
    aber das problem sind die relocationen. das sind die stellen wo das programm
    eine funktion aufruft, die nicht im eigenen code steht (runtime, winapi...)

    an der stelle steht im code nur ein dummycall (glaub 0xffffffff). an diese
    stelle (wo das ist steht auch in der exe) wird dann die entgültige addresse
    hingeschrieben.

    das problem liegt einfach daran, dass das programm im speicher wenn es läuft
    nicht das selbe ist, was auf der platte liegt.

    windows macht es zum beispiel so (ungefähr)

    -programm in den speicher kopieren
    -alle importierten addressen durch die entgültigen funktionen ersetzen.
    -alle angeforderten DLLs laden
    -CS:IP auf den codebegin setzen
    -dann wird es auseführt



  • hat mir sehr geholfen, danke:)

    hab noch ne Frage vergessen:

    Wieso ausgerechnet ein char->1Byte?
    Sind die Anweisungen genau ein Byte groß, oder weshalb?

    PS:
    Bei der command.com funktionierts schonmal nicht:(



  • push

    ich bekomme beim Starten->egal, was ich auch probiere immer Fehler beim Ausführen der Funktion->Die Anweisung xyz verweist auf bablabla

    liegts vielleicht an der com-Datei?
    hat jemand zufällig sowas wie ne HelloWorld als com da?


Anmelden zum Antworten