exe-datei erstellen



  • hi,

    ist es möglich, eine einfach exe-datei zu erstellen mit einem selbstgeschriebenem programm?? ich meine, mit funktionen, die der benutzer zuerst eingegeben hat; ein einfaches beispiel wäre: Der Benutzer gibt einen Text in ein Editfeld des Hauptprogramms ein, und lässt mit einem Klick auf "OK" oder irgendsowas halt eine exe-datei in einem ausgewähltem ordner erstellen. Wenn er dann diese datei startet, kommt eine messagebox mit dem von ihm vorher einegegebenen text. Das wäre nur ein beispiel! Geht das irgendwie??



  • Klar, wenn du Maschinencode kannst...



  • au ok danke für den hinweis! aber ich glaub des wird nix bei mir...^^ 🙄



  • WebFritzi schrieb:

    Klar, wenn du Maschinencode kannst...

    Nö muss er nicht mal.

    Du schreibst einfach ein Programm das eine Textbox mit dem Text aus einem char Array ausgibt:

    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    
    char text[1024] = {
    'M','E','I','N',' ','T','E','X','T',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    
    int APIENTRY WinMain(HINSTANCE,HINSTANCE,char*,int)
    {
       MessageBox(0,text,"Eine Nachricht",MB_OK|MB_ICONINFORMATION);
       return 0;
    }
    

    Wie du siehst ist das Array größer als man für den Textbrauchen würde, aber genau das ist wichtig. Denn den Platz lässt dir der Linker dann auch in deiner Exe.

    Dann kompilierst du das und schaust dir deine Datei im Hexviewer an. Da findest du dann deinen Text. Merk dir das Offset von dem Text, das heißt das von da an + 1024 Bytes dein Text reinkommen kann.
    Das heißt du kannst 1023 Zeichen speichern und musst ein Zeichen frei lassen als Nullterminierung.

    Bei mir ist das Offset 0x1000 (4096 Bytes vom Anfang der Datei weg)

    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    
    DWORD offset = 0x1000;
    char mein_neuer_text[] = "Hallo dies ist ein Test ob das ganze auch wirklich funktioniert!";
    
    int main(){
        HANDLE hFile = CreateFile("test.exe",GENERIC_READ|GENERIC_WRITE,0,0,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
        if(hFile == INVALID_HANDLE_VALUE)
        {
            printf("Konnte die Datei nicht zum patchen oeffnen. Error: %u\n",GetLastError());
            return 0;
        }
        HANDLE hMapping = CreateFileMapping(hFile,0,PAGE_READWRITE,0,0,0);
        if(!hMapping)
        {
            printf("Konnte die Datei nicht mappen. Error: %u\n",GetLastError());
            CloseHandle(hFile);
            return 0;
        }
        char* data = (char*)MapViewOfFile(hMapping,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
    
        if(!data)
        {
            printf("MapViewOfFile fehlgeschlagen. Error: %u\n",GetLastError());
            CloseHandle(hMapping);
            CloseHandle(hFile);
            return 0;
        }
    
        memcpy(data+offset,mein_neuer_text,sizeof(mein_neuer_text));
    
        UnmapViewOfFile(data);
        CloseHandle(hMapping);
        CloseHandle(hFile);
    }
    

    Vielleicht gibt dir das einen kleinen Eindruck wie das gehen könnte.

    BR
    Vinzenz

    // Btw. ich gebe keine Garantie für diesen Code :p



  • OK, bei solch einfachen Programmen mag das gehen. 😉

    @evilissimo: Hast du's denn mal ausprobiert?



  • WebFritzi schrieb:

    OK, bei solch einfachen Programmen mag das gehen. 😉

    @evilissimo: Hast du's denn mal ausprobiert?

    Ja und ich weiß das es geht 😉

    Nur übernehme ich keine Haftung für das was er damit anstellt. Darauf wollte ich hinaus.

    BR.

    Vinzenz



  • vor ein paar Wochen gab's das hier schonmal: mit Resourcen.
    z.B. beim Start fragt Dein Programm ab ob Bilder,Texte, Sounds... in den Resourcen vorhanden sind.
    Wenn ja abspielen oder was weis ich.
    Wenn nicht Kopie erstellen und vom Benutzer gewünschte Daten als Resource einbauen. Wenn die veränderte Kopie gestartet wird spielt sie das Zeug ab.

    Oder etwas eleganter: einen Abspiel-Stub als Resource einbinden und daraus die neue Datei erstellen.



  • also ich hab das jetzt mal ausprobiert und es hat auch perfekt funktioniert nachdem ich das mit einem Hex-Viewer angeschaut hab... Allerdings war jetz des Offset natürlich an meinem PC woanders und ich musste den Code logischwerweise ändern damit es funktioniert... Aber wie mach ich des jetzt eben, wenn ich das an einem ganz anderen PC ausführen will ohne immer einen Hex-Viewer mitzunehmen oder so??



  • Ist das Offset nicht eher compilerspezifisch als computerspezifisch?

    Klappt aber echt gut. Hab das direkt im Hex-Editor geändert. Mein Offset ist bei 0x9720.



  • kingofmovies schrieb:

    also ich hab das jetzt mal ausprobiert und es hat auch perfekt funktioniert nachdem ich das mit einem Hex-Viewer angeschaut hab... Allerdings war jetz des Offset natürlich an meinem PC woanders und ich musste den Code logischwerweise ändern damit es funktioniert... Aber wie mach ich des jetzt eben, wenn ich das an einem ganz anderen PC ausführen will ohne immer einen Hex-Viewer mitzunehmen oder so??

    Du musst keinen Hexviewer mitnehmen. Du musst den offset nur nach jedem mal, wenn du die Anwendung die manipuliert werden soll neu erstellst anpassen. 😉

    WebFritzi schrieb:

    Ist das Offset nicht eher compilerspezifisch als computerspezifisch?

    Könnte man sagen, wohl eher Linker spezifisch. Weil es drauf ankommt wo der Linker deine Daten hinpackt 😉

    BR
    Vinzenz



  • also danke mal für die vielen antworten bei mir funktioniert des jetz alles genau so wies gehen soll. dann hätt ich gleich mal die nächste frage^^ und zwar ob es möglich ist, eine EXE-datei in mein programm einzubinden und dann nacher zu extrahieren aus diesem programm? Oder gibt es Programme, womit ich zwei EXEs zusammenfügen kann, wobei die eine automatisch an einen bestimmten ort extrahiert wird? Weil eigentlich hatte ich vor ein Programm zu schreiben, in dem man dann bestimmte funktionen selbst bestimmen bzw verändern kann. Dazu bräuchte ich aber eben das Grundgerüst von der selbst "editierbaren" Datei, damit ich dieses dann verändern kann.



  • kingofmovies schrieb:

    ob es möglich ist, eine EXE-datei in mein programm einzubinden und dann nacher zu extrahieren aus diesem programm?

    Ja, ist möglich - mit Resourcen. Schau dich mal ein wenig in der MSDN um. Stichworte: LoadResource, LockResource.



  • Als wenn das nicht schon mal irgendwo stand 😉
    btw. 'UpdateResource' dürfte m.E. den besten Einstieg abgeben





  • danke des is genau das was ich brauch!! Jetz hab ich halt nur das Problem dass ich noch nicht so viel erfahrung mit ressourcen und den zugehörigen befehlen hab, das heißt ich schaffs irgendwie die exe-datei in mein prog einzubinden über die resourcen (ich hab nur rumprobiert und irgendwann hatte meine datei halt 300 kb, so viel wie die 2. exe braucht, mehr^^) aber wenn ich das programm ausführ und halt eigentlich die datei extrahiert werden sollte hauts ihn gleich bei "FindResource" raus... ich hab des jetz einfach mal so ausprobiert:

    Ressource:

    BIN IDR_BIN1 "datei.exe"
    

    Main:

    #include <windows.h>
    
    #define IDR_BIN1 100
    
    [...]
    
    char szMsg[50];
    char szNewFile[] = "file.exe";
    
    // Extrahiere die neue Datei aus den Resourcen:
      HRSRC hRes = FindResource(NULL, MAKEINTRESOURCE(IDR_BIN1), "BIN");
      if (hRes == NULL)
      {
        {
          wsprintf(szMsg, "Internal error (1: resource not found)!");
          MessageBox(NULL, szMsg, "Aborted", MB_ICONHAND | MB_OK);
        }
        return 1;  // error
      }
    
      HGLOBAL hResLoaded = LoadResource(NULL, hRes);
      if (hResLoaded == NULL)
      {
        {
          wsprintf(szMsg, "Internal error (2: resource not found)!");
          MessageBox(NULL, szMsg, "Aborted", MB_ICONHAND | MB_OK);
        }
        return 1;  // error
      }
    
      DWORD dwResSize = SizeofResource(NULL, hRes);
      if (dwResSize == 0)
      {
        {
          wsprintf(szMsg, "Internal error (3: resource not found)!");
          MessageBox(NULL, szMsg, "Aborted", MB_ICONHAND | MB_OK);
        }
        return 1;  // error
      }
    
      LPVOID pData = LockResource(hResLoaded);
      if (pData == NULL)
      {
        {
          wsprintf(szMsg, "Internal error (4: resource not found)!");
          MessageBox(NULL, szMsg, "Aborted", MB_ICONHAND | MB_OK);
        }
        return 1;  // error
      }
    
      HANDLE hTemp = CreateFile(szNewFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
      if (hTemp == INVALID_HANDLE_VALUE)
      {
        {
          wsprintf(szMsg, "Could not create new-file (%s)!", szNewFile);
          MessageBox(NULL, szMsg, "Aborted", MB_ICONHAND | MB_OK);
        }
        return 1;  // error
      }
    
      DWORD dwBytesWritten;
      if (WriteFile(hTemp, pData, dwResSize, &dwBytesWritten, NULL) == FALSE)
      {
        {
          wsprintf(szMsg, "Could not write new-file (%s)!", szNewFile);
          MessageBox(NULL, szMsg, "Aborted", MB_ICONHAND | MB_OK);
        }
        CloseHandle(hTemp);
        UnlockResource(hResLoaded);
        DeleteFile(szNewFile);
        return 1;  // error
      }
      CloseHandle(hTemp);
      UnlockResource(hResLoaded);
    


  • #define IDR_BIN1 100
    IDR_BIN1   BINARY   "datei.exe"
    
    FindResource(hInstance, MAKEINTRESOURCE(IDR_BIN1), "BINARY")
    


  • sorry ich hab das jetzt mal exakt so ausprobiert wie du geschrieben hast aber ... es geht einfach nicht... Ihn hauts immer noch bei "FindResource" raus. ich post hier jetzt einfach mal den ganzen code vielleicht liegts ja am compiler. ich verwend DevCpp 4.9.9.2.

    res.rc:

    IDR_BIN1   BINARY   "datei.exe"
    

    main.h:

    #define IDR_BIN1 100
    

    main.cpp:

    #include <windows.h>
    #include "main.h"
    
    HINSTANCE hInstance;
    
    /*  Declare Windows procedure  */
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    
    /*  Make the class name into a global variable  */
    char szClassName[ ] = "ExtractFile";
    
    int WINAPI WinMain (HINSTANCE hThisInstance,
                        HINSTANCE hPrevInstance,
                        LPSTR lpszArgument,
                        int nFunsterStil)
    
    {
        HWND hwnd;               /* This is the handle for our window */
        MSG messages;            /* Here messages to the application are saved */
        WNDCLASSEX wincl;        /* Data structure for the windowclass */
    
        hInstance = hThisInstance;
    
        /* The Window structure */
        wincl.hInstance = hThisInstance;
        wincl.lpszClassName = szClassName;
        wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
        wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
        wincl.cbSize = sizeof (WNDCLASSEX);
    
        /* Use default icon and mouse-pointer */
        wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
        wincl.lpszMenuName = NULL;                 /* No menu */
        wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
        wincl.cbWndExtra = 0;                      /* structure or the window instance */
        /* Use Windows's default color as the background of the window */
        wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    
        /* Register the window class, and if it fails quit the program */
        if (!RegisterClassEx (&wincl))
            return 0;
    
        /* The class is registered, let's create the program*/
        hwnd = CreateWindowEx (
               0,                   /* Extended possibilites for variation */
               szClassName,         /* Classname */
               "Datei extrahieren",       /* Title Text */
               WS_OVERLAPPEDWINDOW, /* default window */
               CW_USEDEFAULT,       /* Windows decides the position */
               CW_USEDEFAULT,       /* where the window ends up on the screen */
               544,                 /* The programs width */
               375,                 /* and height in pixels */
               HWND_DESKTOP,        /* The window is a child-window to desktop */
               NULL,                /* No menu */
               hThisInstance,       /* Program Instance handler */
               NULL                 /* No Window Creation data */
               );
    
        /* Make the window visible on the screen */
        ShowWindow (hwnd, nFunsterStil);
    
        /* Run the message loop. It will run until GetMessage() returns 0 */
        while (GetMessage (&messages, NULL, 0, 0))
        {
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&messages);
            /* Send message to WindowProcedure */
            DispatchMessage(&messages);
        }
    
        /* The program return-value is 0 - The value that PostQuitMessage() gave */
        return messages.wParam;
    }
    
    /*  This function is called by the Windows function DispatchMessage()  */
    
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
            static char szMsg[50];
            static char szNewFile[] = "file.exe";
        switch (message)                  /* handle the messages */
        {
            case WM_DESTROY:
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
            case WM_KEYDOWN:
                 {
                            // Extrahiere die neue Datei aus den Resourcen:
      HRSRC hRes = FindResource(hInstance, MAKEINTRESOURCE(IDR_BIN1), "BINARY");
      if (hRes == NULL)
      {
        {
          wsprintf(szMsg, "Internal error (1: resource not found)!");
          MessageBox(NULL, szMsg, "Aborted", MB_ICONHAND | MB_OK);
        }
        return 1;  // error
      }
    
      HGLOBAL hResLoaded = LoadResource(hInstance, hRes);
      if (hResLoaded == NULL)
      {
        {
          wsprintf(szMsg, "Internal error (2: resource not found)!");
          MessageBox(NULL, szMsg, "Aborted", MB_ICONHAND | MB_OK);
        }
        return 1;  // error
      }
    
      DWORD dwResSize = SizeofResource(hInstance, hRes);
      if (dwResSize == 0)
      {
        {
          wsprintf(szMsg, "Internal error (3: resource not found)!");
          MessageBox(NULL, szMsg, "Aborted", MB_ICONHAND | MB_OK);
        }
        return 1;  // error
      }
    
      LPVOID pData = LockResource(hResLoaded);
      if (pData == NULL)
      {
        {
          wsprintf(szMsg, "Internal error (4: resource not found)!");
          MessageBox(NULL, szMsg, "Aborted", MB_ICONHAND | MB_OK);
        }
        return 1;  // error
      }
    
      HANDLE hTemp = CreateFile(szNewFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
      if (hTemp == INVALID_HANDLE_VALUE)
      {
        {
          wsprintf(szMsg, "Could not create new-file (%s)!", szNewFile);
          MessageBox(NULL, szMsg, "Aborted", MB_ICONHAND | MB_OK);
        }
        return 1;  // error
      }
    
      DWORD dwBytesWritten;
      if (WriteFile(hTemp, pData, dwResSize, &dwBytesWritten, NULL) == FALSE)
      {
        {
          wsprintf(szMsg, "Could not write new-file (%s)!", szNewFile);
          MessageBox(NULL, szMsg, "Aborted", MB_ICONHAND | MB_OK);
        }
        CloseHandle(hTemp);
        UnlockResource(hResLoaded);
        DeleteFile(szNewFile);
        return 1;  // error
      }
      CloseHandle(hTemp);
      UnlockResource(hResLoaded);
      break;
    }
            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }
    


  • Also gibt er dir den Fehler 1 aus, ja?

    Inkludierst du die main.h auch in res.rc?

    Versuch's mal mit RCDATA statt BINARY im Resource-File und RT_RCDATA statt "BINARY" in FindResource.



  • Hi,

    Was heißt denn bitte genau:

    kingofmovies schrieb:

    hauts ihn gleich bei "FindResource" raus

    Programmabsturz, Funktionsaufruf verläuft fehlerhaft....oder wie ?

    Die Fehlerbeschreibung ist n bissl ungenau...finde ich 💡



  • Bei einem Absturz wüsste er wohl die Stelle nicht, oder ?
    Neben dem Vorschlag von Webfritzi würde ich auch nochmal mit einem externen Werkzeug ala 'resourcehacker' nachschauen ob es mit der Einbindung geklppt hat.


Anmelden zum Antworten