Announcement

Collapse
No announcement yet.

Q: selbst-extrahierende Datei

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Q: selbst-extrahierende Datei

    Hallo *.*

    ihr kennt doch sicher Alle die selbstentpackenden Dateien diverser Packer (WinZip, ...)?

    Meine Frage dazu: Wie bekommt man soetwas selber hin?

    Ich bräuchte dies für ein Verschlüsselungs-Tool das ich programmiere. Optinal soll der User die Möglichkeit haben eine verschlüsselte, selbst-extrahierende Datei zu erzeugen. So ist er beim Entschlüsseln nicht auf das Tool angewiesen.

    Hoffe mein Anliegen ist rübergekommen!

    greetz && thx
    Manuel

  • #2
    <pre><p>
    <b>#define</b> WIN32_LEAN_AND_MEAN
    <p>
    <b>#include</b> <Windows.h>
    <p>
    <i>// Some linker stuf to combine all possible sections</i>
    <b>#pragma comment</b>(linker,"/FILEALIGN:0x00000200")
    <b>#pragma comment</b>(linker,"/MERGE:.rdata=.data")
    <b>#pragma comment</b>(linker,"/MERGE:.data=.text")
    <b>#pragma comment</b>(linker,"/SECTION:.text,EWR")
    <b>#pragma comment</b>(linker,"/IGNORE:4078")
    <b>#pragma comment</b>(linker,"/ENTRY:WinMain")
    <p>
    <i>//</i>
    <i>// Types and structs</i>
    <i>//</i>
    <p>
    <b>typedef struct</b> _OVERLAY_DATA {
    UCHAR Data[ANYSIZE_ARRAY];
    } OVERLAY_DATA, *POVERLAY_DATA;
    <p>
    <i>//</i>
    <i>// Utilities</i>
    <i>//</i>
    <p>
    <i>// Calculate the offset of the attached data</i>
    DWORD GetOverlayOffset(PIMAGE_DOS_HEADER pImage)
    {
    DWORD Result = 0;
    PIMAGE_NT_HEADERS pHeader;
    PIMAGE_SECTION_HEADER pSection;
    DWORD uSectionEnd;
    INT i;
    <p>
    <b>if</b> (pImage->e_magic == IMAGE_DOS_SIGNATURE)
    {
    pHeader = (PIMAGE_NT_HEADERS)((DWORD)pImage + pImage->e_lfanew);
    <b>if</b> (pHeader->Signature == IMAGE_NT_SIGNATURE)
    {
    pSection = IMAGE_FIRST_SECTION(pHeader);
    <b>for</b> (i = pHeader->FileHeader.NumberOfSections; i > 0; i--)
    {
    uSectionEnd = pSection->PointerToRawData + pSection->SizeOfRawData;
    <b>if</b> (uSectionEnd > Result) Result = uSectionEnd;
    pSection++;
    }
    }
    }
    <b>return</b> Result;
    }
    <p>
    <i>// Show error message with Win32 error code</i>
    <b>void</b> ShowError(LPCTSTR lpText, DWORD dwError)
    {
    TCHAR Buffer[4096];
    LPVOID ErrBuffer;
    <p>
    lstrcpyn(Buffer, lpText, sizeof(Buffer) - 2048);
    lstrcat(Buffer, TEXT("\r\r\rLastError: "));
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&ErrBuffer, 0, NULL);
    <b>if</b> (ErrBuffer)
    {
    lstrcat(Buffer, (LPTSTR)ErrBuffer);
    LocalFree(ErrBuffer);
    }
    MessageBox(0, Buffer, TEXT("NicoSFX"), MB_ICONERROR);
    }
    <p>
    <i>//</i>
    <i>// Data handling</i>
    <i>//</i>
    <p>
    <i>// Save data to file</i>
    BOOL SaveFile(LPCTSTR lpFilename, POVERLAY_DATA pData, DWORD dwSize )
    {
    BOOL Result = FALSE;
    HANDLE hFile;
    DWORD dwWritten = 0;
    DWORD dwError;
    <p>
    hFile = CreateFile(lpFilename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    <b>if</b> (hFile == INVALID_HANDLE_VALUE) ShowError(TEXT("Error on creating file!"), GetLastError());
    <b>else</b>
    {
    Result = (WriteFile(hFile, &pData->Data, dwSize, &dwWritten, NULL) && (dwWritten == dwSize));
    dwError = GetLastError();
    CloseHandle(hFile);
    <b>if</b> (!Result) ShowError("Error on writing file!", dwError);
    }
    <b>return</b> Result;
    }
    <p>
    <i>// "Extract" attached data</i>
    BOOL ExtractFiles(LPVOID pOverlay, DWORD dwSize)
    {
    POVERLAY_DATA pData = (POVERLAY_DATA)pOverlay;
    <p>
    <b>return</b> SaveFile(TEXT("_test.txt"), pData, dwSize);
    }<p></pre&gt

    Comment


    • #3
      <pre><p>
      <pre><p><i>//</i>
      <i>// Loading</i>
      <i>//</i>
      <p>
      <i>// Maps itselfs into memory, detect overlay, process data or show info</i>
      <b>void</b> MapAndRun()
      {
      TCHAR FileName[MAX_PATH];
      HANDLE hFile;
      HANDLE hMapp;
      LPVOID pView;
      DWORD dwOffset;
      DWORD dwSize;
      <p>
      <b>if</b> (GetModuleFileName(NULL, FileName, sizeof(FileName)) > 0)
      {
      hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
      <b>if</b> (hFile == INVALID_HANDLE_VALUE) ShowError(TEXT("Error on open package!"), GetLastError());
      <b>else</b>
      {
      hMapp = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
      <b>if</b> (hMapp == 0) ShowError(TEXT("Error on loading package into memory!"), GetLastError());
      <b>else</b>
      {
      pView = MapViewOfFile(hMapp, FILE_MAP_READ, 0, 0, 0);
      <b>if</b> (pView == NULL) ShowError(TEXT("Error on mapping package into memory!"), GetLastError());
      <b>else</b>
      {
      dwOffset = GetOverlayOffset((PIMAGE_DOS_HEADER)pView);
      dwSize = GetFileSize(hFile, NULL);
      <p>
      <b>if</b> (dwSize > dwOffset) ExtractFiles((POVERLAY_DATA)((DWORD)pView + dwOffset), dwSize - dwOffset);
      <b>else</b> MessageBox(0, TEXT("Hello World!"), TEXT("NicoSFX"), MB_ICONINFORMATION);
      <p>
      UnmapViewOfFile(pView);
      }
      CloseHandle(hMapp);
      }
      CloseHandle(hFile);
      }
      }
      }
      <p>
      //
      // WinMain
      //
      <p>
      <b>int</b> WINAPI WinMain(HINSTANCE <i>/*hInstance*/</i>, HINSTANCE <i>/*hPrevInstance*/</i>, LPSTR <i>/*lpCmdLine*/</i>, <b>int</b> <i>/*nCmdShow*/</i>)
      {
      MapAndRun();
      <b>return</b> 0;
      }<p></pre>

      Gruß Nico

      PS: Erläuterung folgt..

      Comment


      • #4
        Dies ist ein komplettes Beispiel für ein selbstextrahierendes Programm.

        (1) In MapAndRun öffnet sich die Datei selbst und legt von sich ein MMF (memory Mapped File) -Objekt an<br>
        (2) GetOverlayOffset wird der Anfang des Mappings übergeben. Diese geht durch im PE-Datei-Header durch alle Sektionen -- das Ende der letzten ist auch das Ende der originalen Datei, alles was danach folgt wurde angehängt.<br>
        (3) ExtractFiles, SaveFile speichern nur noch die Daten in einer Datei (_test.txt), wenn keine Daten angehängt sind erscheint eine Info-Message

        Dieses Verfahren hat den Vorteil, das man das Programm (den Stub) nachträglich komprimieren kann, und _nicht_ vorher wissen muß, wie groß es ist...

        (Anhängen von Datei zum testen ist ziemlich einfach in einer Konsole mit "copy /B test.exe + test.txt _test.exe" (_test.exe sollte dann _test.txt "entpacken", wobei test.exe die Info anzeigt...)

        Das Beipsiel wurde mit VC++ 6.0 SP5 geschrieben. (kommt absolut ohne Standard-Libs aus, und ist bei mir 2KB groß, unkomprimiert =)

        Gruß Nico

        PS: ist natürlich nur ein einfaches Beispiel, und diverse Feinheiten sind noch zu verbessern, aber funzt erstmal
        &#10

        Comment


        • #5
          Was Du jetzt an die Datei anhängst (zB die ersten 4096 Bytes sind der Krypto-Schlüssel für's Paßwort... und/oder ganze Verzeichnisse statt nur einer Datei...) bleibt Dir überlassen.

          Gruß nic

          Comment

          Working...
          X