Auslesen einer binären Datei

Anfängerfragen zum Programmieren mit PureBasic.
Axolotl
Beiträge: 287
Registriert: 31.12.2008 16:34

Re: Auslesen einer binären Datei

Beitrag von Axolotl »

Mein zweites Konzept verwendet die CompareMemoryString() anstelle der CompareMemory(). Ist also durchaus ähnlich.

Ich denke, die Verwendung von Strings ist aufgrund von Unicode (2-Byte) und den byte-orientierten Headern problematisch.
Meine Idee wäre ja eher die Header byteweise (.ASCII) zu finden und dann die "richtigen Stellen" nach Strings zu wandeln...

BTW: Ich möchte ja niemandem den Programmier-Spass nehmen, deshalb (nur) Hilfe zur Selbsthilfe.
Using PureBasic latest stable version and current alpha/beta (x64) on Windows 11 Home
Benutzeravatar
H.Brill
Beiträge: 509
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: Auslesen einer binären Datei

Beitrag von H.Brill »

Ich muß ja nur einmal den richtigen Anfangsoffset finden, da genügt ja der BOM EF BB BF. Und dann noch 4 Bytes dazu zählen.
Der richtige Anfangsoffset ist halt wichtig beim späteren Zerstückeln, damit die später zurückgespielten Dateien vom Gerät
wieder erkannt werden und man auch den Anfangsoffset für den Titel genau trifft.
Man muß sich vorstellen, daß diese Binärdaten hauptsächlich Steuerbefehle für das Gerät sind, das dann wieder
Musik daraus macht. Außer den Musiktiteln an Offset $39B bei jeder Einzeldatei ist da nichts Lesbares drin. Ich brauch da ja nur
Memoryblöcke mit Größe 25752 Bytes. Die sind dann gleichzeitig auch als einzelne Dateien zu speichern. Beim nächsten Lesen
wird der offset dann um 25752 erhöht und mit FileSeek drauf gesetzt und wieder 25752 Bytes eingelesen. Ist ja ziemlich simpel
und müßte ich auch hin bekommen.

Zu den Titeln habe ich noch folgende Infos gefunden :
Diese Dateien sind ein Bitstream, in dem die ASCII Zeichen für den Namen
aber nur 7 Bits belegen.

Man muss halt an der passenden Stelle im Bitstream nach den 7-Bit ASCII
Zeichen suchen.

Beispiel Datei "kneipe_2.UPG" von weiter oben ab Offset 0x39B:

0000039B 65 CE 8B 26 ¦ 84 54 08 10 ¦ 20 40 81 02 ¦ 04 08 10 20
000003AB 40 82 01 80 ¦ AD 52 BA 04 ¦ 08 10 20 40 ¦ 81 02 00 00

65 CE 8B 26 84 54 08

01100101 11001110 10001011 00100110 10000100 01010100 00001000

01 1001011 1001110 1000101 1001001 1010000 1000101 0100000

01001011 01001110 01000101 01001001 01010000 01000101 00100000

0x4B 0x4E 0x45 0x49 0x50 0x45 0x20
K N E I P E <SPACE>


Das passt so auch bei den anderen Beispieldateien, wie lang der Name
maximal sein kann muss man schauen (20 kommt aber wohl gut hin).
Ist halt jetzt die Frage, ob PB 7-Bit Ascii unterstützt. Normalerweise ist ja 1 Byte = 8 Bit.
Ist wohl noch ein Relikt aus den DOS-Zeiten und es steckt im Akkordeon ja bestimmt auch
ein MikroController. Das kennt man ja mittlerweile, z.b. daß Strings kein Nullbyte automatisch am
Ende haben, wenn es der Chip schickt.

Achja, wenn jemand jetzt mit Urheberrechten kommt : Der Graig aus den USA, der maßgeblich
an der Entwicklung betieligt war, hat laut Aussage meines Freundes da schon vor Jahren grünes Licht gegeben.
Er selber möchte aber keine Zeit mehr darin investieren. Von dem stammen auch so manche Informationen zum
Aufbau der Datei. Da brauche ich keine Angst haben.
PB 6.10
Benutzeravatar
HeX0R
Beiträge: 3052
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: Auslesen einer binären Datei

Beitrag von HeX0R »

Ich verstehe nicht wirklich was Du da sagt.
Der BOM kann Dir so hoch wie breit sein, weil er IMMER am Anfang Deiner Datei steht.
Damit kann man keinen Offset ermitteln.
Dann ignorierst Du auch die folgenden 4 Bytes, die Dir aber die Länge des XML Anteils anzeigen.
Über die Zusammensetzung des Datenteils, kann ich jetzt nicht wirklich viel finden in den ganzen Posts, außer, dass die Titel im 7Bit Ascii-Format sind.
Das kann PB nicht von Haus aus, lässt sich aber natürlich umsetzen.
Hier mal ein kleiner Code für den Start:

Code: Alles auswählen

Structure _SWAP_HELPER_
	b.b[0]
EndStructure

Procedure SwapLong(Value)       ;Changes a long from BidEndian to LittleEndian (which PB uses)
		Protected Result, *B._SWAP_HELPER_ = @Value
		Swap *B\b[0], *B\b[3]
		Swap *B\b[1], *B\b[2]
		ProcedureReturn PeekL(*B)
EndProcedure


Procedure InitUPA(File$)
	Protected FID, BOM, XMLPart$, Length
	
	FID = ReadFile(#PB_Any, File$)
	If FID
		BOM = ReadStringFormat(FID) ; <-- wird eh #PB_UTF8 sein, aber Du hast den Lesezeiger schonmal 3 Bytes weiter gebracht
		Length = ReadLong(FID)      ; <-- Länge des XML Anteils, aber in BigEndian Format
		Length = SwapLong(Length)   ; <-- Länge des XML Anteils im LittleEndian Format
		XMLPart$ = ReadString(FID, BOM | #PB_File_IgnoreEOL, Length)
		Debug XMLPart$              ; <-- XML Anteil, und Dein Lesezeiger sitzt jetzt genau dahinter, also am Anfang der Binärdaten
		
		
		CloseFile(FID)
	EndIf
EndProcedure

InitUPA("I:\test\UPG_ALL.UPA")
Benutzeravatar
H.Brill
Beiträge: 509
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: Auslesen einer binären Datei

Beitrag von H.Brill »

Hallo Hexor,
Naja, ich dachte, weil der BOM ja hinter dem XML steht.
Aber dein Code bringt mich ja weiter. Auf das SwapLong() wäre ich nie gekommen.
Dann habe ich ja direkt die Stelle zum blockweisen Weiterlesen mit ReadData().
Danke dafür.
PB 6.10
Axolotl
Beiträge: 287
Registriert: 31.12.2008 16:34

Re: Auslesen einer binären Datei

Beitrag von Axolotl »

So, ich habe noch ein bisschen analysiert. Was dabei herausgekommen ist habe ich hier mal abgespeichert.
Ich bin ganz ehrlich: Ich habe das nur gemacht, weil mich diese Bit-Beißerei total triggert. Ich glaube aber auch, dass das proprietäre Format ohne irgendwelche Doku nicht zu knacken ist. (Jedenfalls nicht von mir)

TIPP: Wenn dein Bekannter einen Gesprächsfaden zu dem (früheren) Entwickler hat, dann sollte er so viel wie möglich aus ihm rauskitzeln. Z.B. Formatbeschreibung und/oder Sourcecode.

Genug philosophiert... Hier mein (finaler/nicht fertiger) Stand der Analyse....
HINWEISE:
1. Der Debugger und der ShowMemoryViewer werden für die Ausgaben verwendet
2. Die unterschiedlichen Analysen können mit CompilerIf 0 ; <== activated by changing this to Non-Zero freigeschaltet werden
3. Um den ShowMemoryViewer sinnvoll zu nutzen, sind an den Stellen (Zeile danach) die Breakpoints zu aktivieren.

Code: Alles auswählen

EnableExplicit 

#FILE_READER = 1 

Structure TSetItems 
  Name$             ; 
  Number.i          ;
  Size.i            ; 
  Offset.i          ; 
EndStructure 

Structure TSets 
  Count.i 
  Size.i 
  List Items.TSetItems() 
EndStructure 

Structure TArray
  a.a[0] 
EndStructure 

Structure _SWAP_HELPER_   ; HexOR style 
	b.b[0]
EndStructure

Procedure SwapLong(Value)       ; Changes a long from BidEndian to LittleEndian (which PB uses)  ; HexOR style 
		Protected Result, *B._SWAP_HELPER_ = @Value 
		Swap *B\b[0], *B\b[3]
		Swap *B\b[1], *B\b[2]
		ProcedureReturn PeekL(*B)
EndProcedure 


; from 8-bit to 7-bit Ascii 
; 
Procedure Convert8to7(*Out.INTEGER, *In.TArray) ; VOID 
  Protected i, idx, shift, offset, outLen, lhs, rhs  
  Protected *res.TArray 

  outLen = MemorySize(*In) * 8 / 7  ; 
  *Out\i = AllocateMemory(outLen)   ; to get the pointer back to the caller 
  *res = *Out\i                     ; to work with the structure element 

  For i = 0 To outLen - 1 
    idx = offset / 8 
    shift = offset % 8  
    lhs = *In\a[idx] & ($FF >> shift) 
    If shift = 0 
      lhs >> 1 
    Else 
      lhs << (shift - 1) 
    EndIf 
    rhs = (*In\a[idx+1] & ($FF << (9 - shift))) >> (9 - shift)
    *res\a[i] = (lhs | rhs) & $7F 
    offset + 7 
  Next i 
EndProcedure 


Procedure AnalyzeFile(FileName$) 
  Protected *Buffer, BufLength, ffmt, length  
  Protected *Cursor.ASCII, *A.TArray 
  Protected t$, Sets.TSets, fp.q, bytes, sum, number, index, bOk  
  Protected *in.TArray, *out.TArray, *search.TArray  

  *Buffer = 0
  If ReadFile(#FILE_READER, FileName$)
    BufLength = Lof(#FILE_READER)
    *Buffer = AllocateMemory(BufLength + 10) ; avoid the 0 size-buffer problem (acc. to the PB source code) 
    If *Buffer 
      ffmt = ReadStringFormat(#FILE_READER)         ; now the pointer is behind the BOM (if any) 

      ; addid this from HexOR's example 
      ; 
      length = ReadLong(#FILE_READER)      ; <-- Länge des XML Anteils, aber in BigEndian Format 
      length = SwapLong(length) 
Debug "Length = 0x" + Hex(length) +" ("+ length + ")"

      ; make absolute position 
      length + Loc(#FILE_READER)                : Debug "StartAddress: " + length 
      
      ; Read the XML Part .....
      ;
      If ffmt = #PB_UTF8 And 1 ; <= I want it 
        Repeat 
          If ReadString(#FILE_READER) = "<Roland_Fr_UPA>" : Break : EndIf 
        ForEver 

        ; read the Sets\Items() 
        Repeat 
          t$ = ReadString(#FILE_READER) 
          If t$ = "</Roland_Fr_UPA>" : Break : EndIf              : Debug "  Add Set  '" + t$ + "'" 

          ; ■ figure out the stuctured details ... further improvement 
          ;   see below the filled structures -- i leave this analysing stuff for others 
        ForEver 
      EndIf 

      ; do another position check ..... 
      ; 
      fp = Loc(#FILE_READER)                      : Debug "New Position: " + fp  

      If fp <> length ; current position is different to calculated from above !!! 
        FileSeek(#FILE_READER, length, #PB_Absolute)        : Debug "New Start Address: " + Loc(#FILE_READER) 
      EndIf 

      ; Read the Binary Data .....
      ;
      bytes = ReadData(#FILE_READER, *Buffer, BufLength)      

    EndIf 
    CloseFile(#FILE_READER) 
  EndIf 

Debug "File Length = " + BufLength 
Debug "Data block  = " + bytes + " ?= " + BufLength + " // same as New Position: " + Str(BufLength-bytes) 

  ; manually filled structure ..... 
  ;
  ; < SET  size = "26038"   number = "1400"     offset="0">'
  ; 	< SC     size = "128"  number = " 1"  offset = "    0"  />
  ; 	< O_R    size = " 86"  number = "26"  offset = "  128"  />
  ; 	< OB_R   size = " 66"  number = " 7"  offset = " 2364"  />
  ; 	< OBC_R  size = " 72"  number = " 8"  offset = " 2826"  />
  ; 	< OFB_R  size = " 72"  number = " 8"  offset = " 3402"  />
  ; 	< TR     size = "304"  number = "16"  offset = " 3978"  />
  ; 	< BR     size = " 84"  number = "16"  offset = " 8842"  />
  ; 	< BCR    size = " 96"  number = "16"  offset = "10186"  />
  ; 	< ORR    size = " 64"  number = "26"  offset = "11722"  />
  ; 	< OBR    size = " 42"  number = " 7"  offset = "13386"  />
  ; 	< OBCR   size = "124"  number = " 8"  offset = "13680"  />
  ; 	< OFBR   size = "118"  number = " 8"  offset = "14672"  />
  ; 	< ORCH1  size = "210"  number = "28"  offset = "15616"  />
  ; 	< ORCH2  size = "152"  number = "28"  offset = "21496"  />
  ; 	< SC2    size = "286"  number = " 1"  offset = "25752"  />
  ; < /SET> 
  ;
  ; <UPLIST size = "131072"  number = "1"  offset = "36453200"/>  ==> ?? 

  Sets\Count = 1400 
  Sets\Size = 26038 
  AddElement(Sets\Items()) : Sets\Items()\Name$ = "SC"    : Sets\Items()\Size = 128 : Sets\Items()\Number =  1 : Sets\Items()\Offset =     0 
  AddElement(Sets\Items()) : Sets\Items()\Name$ = "O_R"   : Sets\Items()\Size =  86 : Sets\Items()\Number = 26 : Sets\Items()\Offset =   128 
  AddElement(Sets\Items()) : Sets\Items()\Name$ = "OB_R"  : Sets\Items()\Size =  66 : Sets\Items()\Number =  7 : Sets\Items()\Offset =  2364 
  AddElement(Sets\Items()) : Sets\Items()\Name$ = "OBC_R" : Sets\Items()\Size =  72 : Sets\Items()\Number =  8 : Sets\Items()\Offset =  2826 
  AddElement(Sets\Items()) : Sets\Items()\Name$ = "OFB_R" : Sets\Items()\Size =  72 : Sets\Items()\Number =  8 : Sets\Items()\Offset =  3402 
  AddElement(Sets\Items()) : Sets\Items()\Name$ = "TR   " : Sets\Items()\Size = 304 : Sets\Items()\Number = 16 : Sets\Items()\Offset =  3978 
  AddElement(Sets\Items()) : Sets\Items()\Name$ = "BR   " : Sets\Items()\Size =  84 : Sets\Items()\Number = 16 : Sets\Items()\Offset =  8842 
  AddElement(Sets\Items()) : Sets\Items()\Name$ = "BCR  " : Sets\Items()\Size =  96 : Sets\Items()\Number = 16 : Sets\Items()\Offset = 10186 
  AddElement(Sets\Items()) : Sets\Items()\Name$ = "ORR  " : Sets\Items()\Size =  64 : Sets\Items()\Number = 26 : Sets\Items()\Offset = 11722 
  AddElement(Sets\Items()) : Sets\Items()\Name$ = "OBR  " : Sets\Items()\Size =  42 : Sets\Items()\Number =  7 : Sets\Items()\Offset = 13386 
  AddElement(Sets\Items()) : Sets\Items()\Name$ = "OBCR " : Sets\Items()\Size = 124 : Sets\Items()\Number =  8 : Sets\Items()\Offset = 13680 
  AddElement(Sets\Items()) : Sets\Items()\Name$ = "OFBR " : Sets\Items()\Size = 118 : Sets\Items()\Number =  8 : Sets\Items()\Offset = 14672 
  AddElement(Sets\Items()) : Sets\Items()\Name$ = "ORCH1" : Sets\Items()\Size = 210 : Sets\Items()\Number = 28 : Sets\Items()\Offset = 15616 
  AddElement(Sets\Items()) : Sets\Items()\Name$ = "ORCH2" : Sets\Items()\Size = 152 : Sets\Items()\Number = 28 : Sets\Items()\Offset = 21496 
  AddElement(Sets\Items()) : Sets\Items()\Name$ = "SC2  " : Sets\Items()\Size = 286 : Sets\Items()\Number =  1 : Sets\Items()\Offset = 25752 

  If *Buffer

CompilerIf 0 ; <== activated by changing this to Non-Zero 
    Debug "Analyse XML data " 
    *Cursor = *Buffer 
    sum = 0 
    number = 0 
    ForEach Sets\Items() 
      sum + (Sets\Items()\Number * Sets\Items()\Size) 
      number + Sets\Items()\Number 

      Debug ">> " + Sets\Items()\Name$ + "  => " + Sets\Items()\Number + " Items." 

      *Cursor + Sets\Items()\Offset 
      For index = 1 To Sets\Items()\Number 
        Debug "  " + index + ".  Start Address: 0x" + Hex(*Cursor) + " (" + *Cursor + ")" 

;       ShowMemoryViewer(*Cursor, Sets\Items()\Size)        ; << Look at this by using a breakpoint on the next line  
        *Cursor + Sets\Items()\Size                         ; << set Breakpoint here !! 
      Next index 
      Debug "" 
    Next 
    Debug "End of Analyse XML data " 
    Debug "" 
    Debug "Total Number = " + number + "  == " + Sets\Count + " ?" 
    Debug "Total Size   = " + sum    + "  == " + Sets\Size  + " ?" 
CompilerEndIf 

CompilerIf 0 ; <== activated by changing this to Non-Zero 

    ; Looking for this...  internal names ?? 
    ; 
    ; upg_all 001 "UsrPrg DALE ON"
    ; upg_all 002 "Classic 8"
    ; upg_all 003 "ALPINE"
    ; upg_all 004 "Mandolin"
    ; upg_all 005 "TRUMPET"
    ; upg_all 006 "CLARINET"
    ; upg_all 007 "Low BRASS"
    ; upg_all 008 "MASTER"
    ; upg_all 009 "Sax Ensemble)Muss"
    ; .... 

    *In = AllocateMemory(Sets\Size + 1) ; trailing zero-char 
    If *In 
      CopyMemory(*Buffer, *In, Sets\Size + 1) 
      Convert8to7(@*Out, *In) 
      If *Out 
        ShowMemoryViewer(*out, MemorySize(*out))  ; << set Breakpoint to see any block !! 
        FreeMemory(*out) 
      EndIf 
      FreeMemory(*In) 
    EndIf 
CompilerEndIf 

CompilerIf 10  ; <== activated by changing this to Non-Zero 

    *A = *Buffer 
    ForEach Sets\Items() 
      *A + Sets\Items()\Offset  ; <= offset is additional 

      For number = 1 To Sets\Items()\Number 
        *In = AllocateMemory(Sets\Items()\Size + 1) 
        If *In 
          CopyMemory(*A, *In, Sets\Items()\Size + 1) 
          Convert8to7(@*Out, *In) 
          If *Out 
            ShowMemoryViewer(*out, MemorySize(*out))  ; << to see this in every loop use breakpoint on next line 
            FreeMemory(*out)                          ; << set Breakpoint 
          EndIf 
          FreeMemory(*In) 
        EndIf 
        *A + Sets\Items()\Size 
      Next number 
    Next 
CompilerEndIf 

    FreeMemory(*Buffer)
  EndIf 
  Debug "Done." 
EndProcedure 

; start is here 
AnalyzeFile("UPG_ALL.UPA") 
Using PureBasic latest stable version and current alpha/beta (x64) on Windows 11 Home
Benutzeravatar
H.Brill
Beiträge: 509
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: Auslesen einer binären Datei

Beitrag von H.Brill »

Mehr Doku, als ich hier schon geschrieben hatte, habe ich nicht.
Und die Macher (der Graig aus USA und der Udo aus Österreich)
rücken da auch nicht mehr raus, auch den Quellcode des Kommandozeilen-
Tools nicht. Das einzige, was ich weiß, ist, daß es in C geschrieben ist.

Aber das binäre Format (Steuerbefehle für das Gerät) muß man ja auch nicht kennen.
Das andere steht im XML-Vorspann : number=1400 und bei SC2 offset=25752. Das einzige,
das man wissen muß : Bei den 1400 Registrierungen sind es 100 Bänke a 14 Registrierungen.
Man kann aber auch ab dem richtigen Start-Offset 1400 mal 25752 Bytes große Blöcke in einen
Memoryblock einlesen und sofort wieder schreiben. Wenn man dann noch bei jedem Block den
20 Bytes langen 7Bit-Ascii-String an offset $39B rausbekommt und in Ansi dekodiert und irgendwie
in einer Liste festhält, ist ja schon alles getan.
Wie man an den Startoffset gelangt, hat ja HEXOR geschrieben. Bleibt also nur noch das Ascii-Problem
bei den Musiktiteln. Vielleicht bekomme ich das auch noch gebacken.
Da PB das von Haus aus nicht kann, müßte man da selber Hand anlegen. Im Netz gefunden :
Um einen 7-Bit-ASCII-Code zu dekodieren, ordnen Sie jedem 7-Bit-Binärcode das
entsprechende Zeichen aus der ASCII-Tabelle zu. Sie können die binären Werte der
Stellen, an denen eine 1 steht, addieren, um die Dezimalzahl zu ermitteln, welche dem
entsprechenden ASCII-Zeichen in der Tabelle entspricht.
Dekodierungsschritte:
Binärcode aufteilen: Ein 7-Bit-ASCII-Code besteht aus 7 Bits. Ermitteln Sie die 7-Bit-Binärsequenz
für das zu dekodierende Zeichen.
Dezimalwert berechnen:

Weisen Sie jedem Bit einen Stellenwert zu:
2^0 (1), 2^1 (2), 2^2 (4), 2^3 (8), 2^4 (16), 2^5 (32) und 2^6 (64).

Addieren Sie die Stellenwerte, an denen eine '1' steht, um die Dezimalzahl zu erhalten.Beispiel:
Für den Binärcode 1000001 (A) ergibt sich die Summe aus 64+1=65
Zeichen zuordnen:
Suchen Sie die berechnete Dezimalzahl in der ASCII-Tabelle. Die entsprechende Dezimalzahl
gibt das Zeichen an.In unserem Beispiel wäre das Zeichen für die Dezimalzahl 65 der Großbuchstabe 'A'. 
Wäre doch auch eine schöne Bitbeißerei.
PB 6.10
Benutzeravatar
HeX0R
Beiträge: 3052
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: Auslesen einer binären Datei

Beitrag von HeX0R »

Das 7Bit Ascii ist kein Problem, das Problem ist eher das hier aus Deinem Beispiel:
Beispiel Datei "kneipe_2.UPG" von weiter oben ab Offset 0x39B:

0000039B 65 CE 8B 26 ¦ 84 54 08 10 ¦ 20 40 81 02 ¦ 04 08 10 20
000003AB 40 82 01 80 ¦ AD 52 BA 04 ¦ 08 10 20 40 ¦ 81 02 00 00

65 CE 8B 26 84 54 08

01100101 11001110 10001011 00100110 10000100 01010100 00001000

01 1001011 1001110 1000101 1001001 1010000 1000101 0100000
Wieso bitte werden hier die ersten beiden Bits des Streams weggeschmissen?
Das lässt darauf schließen, dass da relativ vieles im 7Bit Format vorliegt, und wenn Du nicht genau weißt, was da vorher oder hinterher ist, kannst Du Dir einen Wolf suchen, um an die Titel zu kommen.
Der nächste steht vielleicht erst ab dem 4. Bit, ein anderer ab dem 6. oder was weiss ich?
Ich würde eher das Tool einbinden, da kommst Du ja nicht mal per Reverse Engineering weiter sonst.

Direkt nach dem XML steht übrigens "FR-7FR7X0001 DALE ON" (als 7bit Ascii Gemurkse)
Axolotl hat geschrieben: 12.10.2025 16:30

Code: Alles auswählen

; HexOR style
:mrgreen: :allright:
Benutzeravatar
H.Brill
Beiträge: 509
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: Auslesen einer binären Datei

Beitrag von H.Brill »

Das stammt aus dem Elektronik-Forum und das ist schon eine fertig zerstückelte Datei.
Dort kann man nicht nach dem XML gehen. Der Autor hat einfach die originale XML bei
jeder zerstückelten Datei vorne dran gepackt. Das Gerät scheint den XML-Teil wohl zu
überlesen. Der scheint nur für den Output vom Gerät zu sein.

Obwohl du da schon nahe dran bist, der Titel ist
UsrPrg DALE ON

Mag aber jetzt auch Zufall sein, daß du gerade ein Stück erwischt hast.
Da können am Ende der Originaldatei auch mal mehrere leere Titel stehen, wenn der
Musiker auf dem Gerät halt keine angibt. Das sind halt 20 Bytes (Keine Bits), die halt
mit einem Titel belegt sein können oder aber auch nicht.
Für meinen Teil würde ich den Titel aus dem Memoryblock lesen, was sich auch anbietet,
wenn man einen Memoryblock (25752 Bytes groß) aus der Originaldatei gelesen hat.
Das geht dann in einem Rutsch.
PB 6.10
Benutzeravatar
H.Brill
Beiträge: 509
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: Auslesen einer binären Datei

Beitrag von H.Brill »

Also, es hat mir ja keine Ruhe gelassen. ich habe mal die original .upa Datei mit dem stinknormalen Windowseditor geöffnet und nach
der Zeichenfolge "�Ikxԛ�`" gesucht. Nur einen kleine Teil davon. Da kommt das schon zig-mal vor. Ich denke mal, daß ich diese Sequenz
1400 mal finden werde, also genausoviel, wie es Registrierungen gibt. Das war wohl ein Mißverständnis im Elektronik-Forum bzw. von Graig.
Die gingen inklusive XML-Vorspann aus, ich aber nicht. Die Zeichenfolge "�Ikxԛ�`" scheint wohl so eine Art Erkennungs-Sequenz zu sein, damit
das Gerät erkennt, wann eine neue Registrierung anfängt. Wenn ich mir nun dein "FR-7FR7X0001 DALE ON" anschaue, erkenne ich, das das
"FR-7FR" die sechs Bytes für den Gerätetyp und "7X0001 DALE ON" der Musiktitel direkt hinten dran sein muß. Das 7X0001 würde ja genau zu
"UsrPrg" der Länge nach passen. Das ganze kommt dann auch mit den 20 Bytes Länge hin. Da werde ich morgen früh mal schauen und mal 10 Blöcke
auslesen. Vielleicht bin ich da auf dem richtigen Weg.
Wie schon gesagt : Die Krücke mit dem Aufruf des Konsolenprogramm aus einer Windows-Anwendung habe ich ja schon durch. Da aber das Konsolenprogramm keine Statusmeldungen auf Konsole zurückgibt, ist halt entweder Warten mit der Sanduhr oder eine Ordnerüberwachung
und Statusbar angesagt. Man weiß ja nicht, wie lange MS noch Konsolenanwendungen unterstützt.
PB 6.10
Axolotl
Beiträge: 287
Registriert: 31.12.2008 16:34

Re: Auslesen einer binären Datei

Beitrag von Axolotl »

In den 8-bit (kodierten) Daten zu suchen führen nicht zum Ziel. Es ist so wie HeXOR schon geschrieben hat, musst du die Stellen finden, an denen die 8-bit in 7-bit umgewandelt werden müssen.
Ich habe das nur für den ersten eintrag geschafft. (BTW: im o.g. code ist noch ein denkfehler drin).
Nur so zur Info: Meine umwandlungsroutine (s.o.) funktioniert.

Über das Konsolenprogramm hasste dich ja schon mit deinen XProfan Jungs unterhalten.
Ich bin allerdings der Meinung, dass das Tool so schnell ist, dass eine Statusmeldung nicht erforderlich ist.

Hier mal die Titelliste in einer Listbox....

Code: Alles auswählen

If OpenWindow(0, 0, 0, 270, 140, "ListViewGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ListViewGadget(0, 10, 10, 250, 120)

  P = RunProgram("RolandFrxSettings.exe", "-l UPG_ALL.UPA", "", #PB_Program_Open | #PB_Program_Read)
  If P
    While ProgramRunning(P)
      If AvailableProgramOutput(P)
        AddGadgetItem (0, -1, ReadProgramString(P)) 
      EndIf
    Wend
    CloseProgram(P) ; Close the connection to the program 
  EndIf
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Ich denke mal, ich habe fertig.
Using PureBasic latest stable version and current alpha/beta (x64) on Windows 11 Home
Antworten