2 Stimmen

C++ Verwendung eines Dateiformats

Vor ein paar Tagen habe ich gefragt, wie man ein Dateiformat reverse-engineeren könnte. Obwohl das nicht wirklich geklappt hat, hat mir jemand das Dateiformat gegeben. (Klicke hier) Danke Xadet.

Ich bin immer noch ziemlich neu in diesem Bereich und frage mich, wie es weitergeht. Ich vermute, dass ich Inline-ASM in C++ verwenden muss, um dieses Format zu verwenden, aber ich wüsste nicht, wie ich die Datei tatsächlich öffnen oder Daten einfügen soll.

Also lautet die Frage, wie kann ich das Dateiformat nutzen, um Daten zu erhalten oder einzufügen? Und das Dateiformat sieht wie ASM aus, aber ich möchte nicht damit anfangen, rein in ASM zu programmieren. Ich habe Leute gesehen, die ASM in C++ programmiert haben, deshalb halte ich das für eine gute Wahl.

Jede Hilfe wäre sehr geschätzt.

2voto

Cheers and hth. - Alf Punkte 138555

Die Dateiformatbeschreibung sieht nicht wie asm aus, sondern eher wie Pseudocode.

1voto

Tony Delroy Punkte 98528

Ich gehe davon aus, dass Sie kein C++-Programm haben möchten, das beim Starten jenes Dateiformatdokuments liest und dann die tatsächliche Datendatei auf dieser Grundlage analysiert. Stattdessen möchten Sie einfach ein C++-Programm, das ausschließlich zur Lektüre der aktuellen Version dieses Dateiformats bestimmt ist? (Das ist viel einfacher und wird schneller ausgeführt). Sie müssen kein ASM verwenden. Was Sie tun müssen, ist die C++-Typen herauszufinden, die den in der Formatdatei verwendeten Namen entsprechen. Zum Beispiel denke ich, dass DWORD in Microsoft-Sprachen verwendet wird, um auf eine ganze Zahl einer bestimmten Größe - vielleicht 32 oder 64 Bits - zu verweisen. Finden Sie diese Infos heraus und erstellen Sie dann C++-Strukturen mit entsprechenden Elementen.

Zum Beispiel:

#include  // falls auf Windows, probieren Sie stattdessen __int32, __int64 etc.

typedef int64_t DWORD;  // oder welche Breite Sie auch immer finden
typedef int32_t WORD;
typedef ??? ZSTR;  // recherchieren Sie es...?
typedef float FLOAT;

struct dds
{
    ZSTR path;
    WORD is_skin;
    WORD alpha_enabled;
    WORD two_sided;
    WORD alpha_test_enabled;
    WORD alpha_ref;
    WORD z_write_enabled;
    WORD z_test_enabled;
    WORD blending_mode; // None = 0, Custom = 1, Normal = 2, Lighten = 3
    WORD specular_enabled;
    FLOAT alpha;
    WORD glow_type; // None = 0, NotSet = 1, Simple = 2, Light = 3, Texture = 4, TextureLight = 5, Alpha = 6
    FLOAT red;
    FLOAT green;
    FLOAT blue;
};

// zeige mit p auf den gesamten Eingang, den Sie irgendwo im Speicher geladen haben werden
// (z.B. Dateigröße über f/stat() ermitteln, dann Heap zuweisen und darin lesen oder Mappings vornehmen)
const char* p = input;
DWORD mesh_count = *(const DWORD*)p;
p += sizeof(DWORD);
for (int i = 0; i < mesh_count; ++i)
{
    const dds& d = *(const dds*)p;
    // Sie können d.red, d.alpha usw. hier verwenden, um alles zu tun, was Sie möchten
    p += sizeof dds;
}

// setzte die Verarbeitung des Effektzählers etc. in gleichem Stil fort

MfG, Tony

0voto

ruslik Punkte 14336

Es handelt sich um eine Art von Skriptsprache zur Definition des Datenformats, ähnlich wie XDR. Du musst einfach einen Parser dafür schreiben (versuche nicht, das Skript zur Laufzeit zu verwenden). Schreibe einige Funktionen wie get_WORD_BE() oder get_DWORD_LE(), usw. so dass du dich nicht auf die Endianness verlassen musst.

Ja, und wenn du Tonys Ansatz verwenden möchtest, füge ein #pragma pack(1) hinzu.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X