Auslesen einer binären Datei
Re: Auslesen einer binären Datei
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.
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
Re: Auslesen einer binären Datei
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 :
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.
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 :
Ist halt jetzt die Frage, ob PB 7-Bit Ascii unterstützt. Normalerweise ist ja 1 Byte = 8 Bit.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 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
- 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
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:
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")
{Home}.:|:.{Codes}.:|:.{Downloads}.:|:.{History Viewer Online}.:|:.{Bier spendieren}
Re: Auslesen einer binären Datei
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.
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
Re: Auslesen einer binären Datei
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.
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
Re: Auslesen einer binären Datei
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 :
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 :
Wäre doch auch eine schöne Bitbeißerei.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'.
PB 6.10
- 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
Das 7Bit Ascii ist kein Problem, das Problem ist eher das hier aus Deinem Beispiel:
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)
Wieso bitte werden hier die ersten beiden Bits des Streams weggeschmissen?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
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)
{Home}.:|:.{Codes}.:|:.{Downloads}.:|:.{History Viewer Online}.:|:.{Bier spendieren}
Re: Auslesen einer binären Datei
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.
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
Re: Auslesen einer binären Datei
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.
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
Re: Auslesen einer binären Datei
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....
Ich denke mal, ich habe fertig.
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
Using PureBasic latest stable version and current alpha/beta (x64) on Windows 11 Home