Forum: Fahrzeugelektronik PIN-Code Algorithmus von Blaupunkt Radio


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Olli Z. (z80freak)


Angehängte Dateien:

Bewertung
5 lesenswert
nicht lesenswert
Habe mal wieder was zum tüfteln (vielleicht ließt Dieter ja wieder mit! 
:-)
Und zwar beschäftige ich mich schon länger mit den Blaupunkt 
Navigationssystemen und habe doch so einiges darüber in Erfahrung 
gebracht. U.a. weiss ich wie man das Mainboard-Flash (ein Spansion 
S29GL256 mit 32MB) via JTAG ausliest und programmiert.

Der Pin-Algo des Gerätes ist mir aber noch ein Rätsel. Durch Experimente 
habe ich herausgefunden das sich in Sektor #251 ab Adresse 0x1F60000 
Daten befinden die zur Berechnung verwendet werden. Dabei ist der Sektor 
nur am Anfang mit 0x5C9 Bytes gefüllt, der Rest ist 0xFF:

Hier mal exemplarisch der Bindump von "FX_PIN_8367.bin":
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
01F60000  F0 F0 F0 F0 18 00 02 00 00 00 00 00 00 00 02 00  ðððð............
01F60010  F0 FF 01 00 D1 59 75 E8 A3 3D 55 C5 14 05 12 00  ðÿ..ÑYuè£=UÅ....
01F60020  00 00 FF FF C7 C1 F9 00 2B 01 FF FF 5D 0E EB E0  ..ÿÿÇÁù.+.ÿÿ].ëà
01F60030  15 05 2C 00 00 00 FF FF 70 46 00 00 F9 FF FF FF  ..,...ÿÿpF..ùÿÿÿ
01F60040  CB C9 FF FF FB FF FF FF E2 CA FF FF FC FF FF FF  ËÉÿÿûÿÿÿâÊÿÿüÿÿÿ
01F60050  04 DC 16 0A FA FF FF FF 15 0E 6B F5 00 00 0D 00  .Ü..úÿÿÿ..kõ....
01F60060  00 00 FF FF 01 FF FF FF 3B 21 E4 40 A1 01 0E 00  ..ÿÿ.ÿÿÿ;!ä@¡...
01F60070  00 00 FF FF 0F 00 FF FF 39 D3 2D 65 24 05 24 00  ..ÿÿ..ÿÿ9Ó-e$.$.
01F60080  00 00 FF FF E8 0A 00 00 55 0D 00 00 9A 01 00 00  ..ÿÿè...U...š...
01F60090  6C 0A 00 00 0A 01 00 00 C6 09 00 00 FE 25 41 9A  l.......Æ...þ%Aš
01F600A0  14 01 34 00 00 00 FF FF 5B 71 E6 26 6F 6D 5F 28  ..4...ÿÿ[qæ&om_(
01F600B0  49 ED 89 6A F1 14 7B DD B7 08 0C 28 A5 28 9A 1F  Ií‰jñ.{Ý·..(¥(š.
01F600C0  B2 DA ED 9B 8D 76 AF E7 85 B2 6D D3 FB E3 93 92  ²Úí›.v¯ç…²mÓûã“’
01F600D0  DD E9 5E 4E 15 01 1C 00 00 00 FF FF D6 97 31 AC  Ýé^N......ÿÿÖ—1¬
01F600E0  41 B4 39 77 3D FD ED 11 2B BE 66 02 83 3E 6C 82  A´9w=ýí.+¾f.ƒ>l‚
01F600F0  A0 01 0D 00 00 00 FF FF 00 FF FF FF B3 57 40 D0   .....ÿÿ.ÿÿÿ³W@Ð
01F60100  04 01 14 00 00 00 FF FF C1 2A 9E 96 ED 5F B3 E8  ......ÿÿÁ*ž–í_³è
01F60110  2A 23 8E 9F D2 01 24 00 00 00 FF FF 33 30 37 37  *#ŽŸÒ.$...ÿÿ3077
01F60120  32 36 39 32 20 42 42 00 00 00 00 00 00 00 00 00  2692 BB.........
01F60130  00 00 00 00 BF C9 B8 A2 D1 01 24 00 00 00 FF FF  ....¿É¸¢Ñ.$...ÿÿ
01F60140  38 53 37 54 2D 31 38 4B 39 33 31 2D 41 44 00 00  8S7T-18K931-AD..
01F60150  00 00 00 00 00 00 00 00 42 9B E3 74 D0 01 24 00  ........B›ãtÐ.$.
01F60160  00 00 FF FF 38 53 37 54 2D 31 34 43 32 36 30 2D  ..ÿÿ8S7T-14C260-
01F60170  41 43 00 00 00 00 00 00 00 00 00 00 84 CD B4 D0  AC..........„Í´Ð
01F60180  B1 01 0D 00 00 00 FF FF 06 FF FF FF 46 A5 CC 01  ±.....ÿÿ.ÿÿÿF¥Ì.
01F60190  05 01 16 00 00 00 FF FF 37 36 31 32 33 30 30 35  ......ÿÿ76123005
01F601A0  32 34 FF FF F9 5B FD 43 06 01 13 00 00 00 FF FF  24ÿÿù[ýC......ÿÿ
01F601B0  39 30 33 32 31 34 35 FF C8 72 82 07 07 01 12 00  9032145ÿÈr‚.....
01F601C0  00 00 FF FF 30 35 30 32 30 39 FF FF 5C A2 26 FD  ..ÿÿ050209ÿÿ\¢&ý
01F601D0  00 00 3D 00 00 00 FF FF 05 02 01 01 30 02 01 FF  ..=...ÿÿ....0..ÿ
01F601E0  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
01F601F0  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
01F60200  FF FF FF FF FF FF FF FF FF FF FF FF 49 20 B2 CB  ÿÿÿÿÿÿÿÿÿÿÿÿI ²Ë
01F60210  00 00 3D 00 00 00 FF FF 05 02 01 01 30 02 01 FF  ..=...ÿÿ....0..ÿ
01F60220  FF FF FF FF FF FF FF FF FF FF FF FF FF 02 05 01  ÿÿÿÿÿÿÿÿÿÿÿÿÿ...
01F60230  01 01 01 01 FF FF FF FF FF FF FF FF FF FF FF FF  ....ÿÿÿÿÿÿÿÿÿÿÿÿ
01F60240  FF FF FF FF FF FF FF FF FF FF FF FF 01 F1 90 E1  ÿÿÿÿÿÿÿÿÿÿÿÿ.ñ.á
01F60250  00 00 3D 00 00 00 FF FF 05 02 01 01 30 02 01 03  ..=...ÿÿ....0...
01F60260  01 01 03 00 14 20 FF FF FF FF FF FF FF 02 05 01  ..... ÿÿÿÿÿÿÿ...
01F60270  01 01 01 01 FF FF FF FF FF FF FF FF FF FF FF FF  ....ÿÿÿÿÿÿÿÿÿÿÿÿ
01F60280  FF FF FF FF FF FF FF FF FF FF FF FF 40 39 33 22  ÿÿÿÿÿÿÿÿÿÿÿÿ@93"
01F60290  00 00 3D 00 00 00 FF FF 05 02 01 01 30 02 01 03  ..=...ÿÿ....0...
01F602A0  01 01 03 00 14 20 25 00 03 01 02 01 01 02 05 01  ..... %.........
01F602B0  01 01 01 01 FF FF FF FF FF FF FF FF FF FF FF FF  ....ÿÿÿÿÿÿÿÿÿÿÿÿ
01F602C0  FF FF FF FF FF FF FF FF FF FF FF FF EF 4F 4C FD  ÿÿÿÿÿÿÿÿÿÿÿÿïOLý
01F602D0  00 00 3D 00 00 00 FF FF 05 02 01 01 30 02 01 03  ..=...ÿÿ....0...
01F602E0  01 01 03 00 14 20 25 00 03 01 02 01 01 02 05 01  ..... %.........
01F602F0  01 01 01 01 02 01 01 00 01 00 01 FF FF FF FF FF  ...........ÿÿÿÿÿ
01F60300  FF FF FF FF FF FF FF FF FF FF FF FF 67 FE 6B 2F  ÿÿÿÿÿÿÿÿÿÿÿÿgþk/
01F60310  00 00 3D 00 00 00 FF FF 05 02 01 01 30 02 01 03  ..=...ÿÿ....0...
01F60320  01 01 03 00 14 20 25 00 03 01 02 01 01 02 05 01  ..... %.........
01F60330  01 01 01 01 02 01 01 00 01 00 01 00 01 01 00 01  ................
01F60340  01 01 FF FF FF FF FF FF FF FF FF FF B3 1D 64 84  ..ÿÿÿÿÿÿÿÿÿÿ³.d„
01F60350  00 00 3D 00 00 00 FF FF 05 02 01 01 30 02 01 03  ..=...ÿÿ....0...
01F60360  01 01 03 00 14 20 25 00 03 01 02 01 01 02 05 01  ..... %.........
01F60370  01 01 01 01 02 01 01 00 01 00 01 00 01 01 00 01  ................
01F60380  01 01 00 00 05 00 01 00 00 FF FF FF 7F 84 D0 4E  .........ÿÿÿ.„ÐN
01F60390  00 00 3D 00 00 00 FF FF 05 02 01 01 30 02 01 00  ..=...ÿÿ....0...
01F603A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
01F603B0  00 00 00 00 02 01 01 00 01 00 01 00 01 01 00 01  ................
01F603C0  01 01 00 00 05 00 01 00 00 FF FF FF EA D9 BF F7  .........ÿÿÿêÙ¿÷
01F603D0  00 00 3D 00 00 00 FF FF 05 02 01 01 30 02 01 03  ..=...ÿÿ....0...
01F603E0  01 01 03 00 14 20 00 00 00 00 00 00 00 00 00 00  ..... ..........
01F603F0  00 00 00 00 02 01 01 00 01 00 01 00 01 01 00 01  ................
01F60400  01 01 00 00 05 00 01 00 00 FF FF FF 27 4A 2A C7  .........ÿÿÿ'J*Ç
01F60410  00 00 3D 00 00 00 FF FF 05 02 01 01 30 02 01 03  ..=...ÿÿ....0...
01F60420  01 01 03 00 14 20 25 00 03 01 02 01 01 00 00 00  ..... %.........
01F60430  00 00 00 00 02 01 01 00 01 00 01 00 01 01 00 01  ................
01F60440  01 01 00 00 05 00 01 00 00 FF FF FF B3 1D 64 84  .........ÿÿÿ³.d„
01F60450  00 00 3D 00 00 00 FF FF 05 02 01 01 30 02 01 03  ..=...ÿÿ....0...
01F60460  01 01 03 00 14 20 25 00 03 01 02 01 01 02 05 01  ..... %.........
01F60470  01 01 01 01 02 01 01 00 01 00 01 00 01 01 00 01  ................
01F60480  01 01 00 00 05 00 01 00 00 FF FF FF 9E 5C 5A FF  .........ÿÿÿž\Zÿ
01F60490  00 00 3D 00 00 00 FF FF 00 00 00 00 00 00 00 03  ..=...ÿÿ........
01F604A0  01 01 03 00 14 20 25 00 03 01 02 01 01 00 00 00  ..... %.........
01F604B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
01F604C0  00 00 00 00 00 00 00 00 00 FF FF FF 0A 0B 14 BC  .........ÿÿÿ...¼
01F604D0  00 00 3D 00 00 00 FF FF 00 00 00 00 00 00 00 03  ..=...ÿÿ........
01F604E0  01 01 03 00 14 20 25 00 03 01 02 01 01 02 05 01  ..... %.........
01F604F0  01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00  ................
01F60500  00 00 00 00 00 00 00 00 00 FF FF FF C2 A1 08 D4  .........ÿÿÿ¡.Ô
01F60510  00 00 3D 00 00 00 FF FF 00 00 00 00 00 00 00 03  ..=...ÿÿ........
01F60520  01 01 03 00 14 20 25 00 03 01 02 01 01 02 05 01  ..... %.........
01F60530  01 01 01 01 02 01 01 00 01 00 01 00 00 00 00 00  ................
01F60540  00 00 00 00 00 00 00 00 00 FF FF FF 8C AE 0A 6F  .........ÿÿÿŒ®.o
01F60550  00 00 3D 00 00 00 FF FF 00 00 00 00 00 00 00 03  ..=...ÿÿ........
01F60560  01 01 03 00 14 20 25 00 03 01 02 01 01 02 05 01  ..... %.........
01F60570  01 01 01 01 02 01 01 00 01 00 01 00 01 01 00 01  ................
01F60580  01 01 00 00 05 00 01 00 00 FF FF FF B3 1D 64 84  .........ÿÿÿ³.d„
01F60590  CA 01 3D 00 00 00 FF FF 05 02 01 01 30 02 01 03  Ê.=...ÿÿ....0...
01F605A0  01 01 03 00 14 20 25 00 03 01 02 01 01 02 05 01  ..... %.........
01F605B0  01 01 01 01 02 01 01 00 01 00 01 00 01 01 00 01  ................
01F605C0  01 01 00 00 05 00 01 00 00 FF FF FF FF FF FF FF  .........ÿÿÿÿÿÿÿ
01F605D0  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
...

Ich kann einem Gerät einen Sektor eines anderen übertragen und somit die 
PIN "vererben".

In dem Sektor stecken lesbare Infos wie:
die Ford-Nummer des Gerätes: "8S7T-18K931-AD"
die Ford-Nummer der Firmware: "8S7T-14C260-AC"
die BOSCH-Teilenummer: "7612300524"
die Seriennummer "9032145"

Der Algo könnte(!) in dem beigefügten Firmware-Dump liegen, es könnte 
aber auch sein das dieser in der Firmware des Display-Boards steckt.
Auf dem Mainboard werkelt ein OMAP5948, welcher im Grunde ein 
ARM9-Prozessor mit DSP auf einem Chip ist und eine Sonderanfertigung des 
OMAP5912 darstellt.

von Olli Z. (z80freak)


Bewertung
1 lesenswert
nicht lesenswert
Habe noch vergessen zu erwähnen das sich der PIN-Code wohl über die 
Typen/Seriennummer des Gerätes berechnen lässt. In der Typennummer 
steckt ein Verweis auf dem Algorithmus, es gibt wohl mind. 3 
verschiedene:

https://mk4-wiki.denkdose.de/_media/artikel/audio_navigation/algo_a05_fx_side.jpg
https://mk4-wiki.denkdose.de/_media/artikel/audio_navigation/algo_f07_mca_side.jpg
https://mk4-wiki.denkdose.de/_media/artikel/audio_navigation/algo_f09_mca_side.jpg

Aber das ist mehr "Hörensagen" muss ich gestehen.
Die im o.g. Sektor befindliche Seriennummer kann ich ändern wie ich 
will, das hat erstmal keinen Einfluß auf PIN-Code. Vermutlich wird nicht 
die als ASCII kodierte Nummer zur Codevalidierung genutzt, sondern 
andere Bytes des Sektors. Ich werde mal versuchen mich da ran zu tasten 
um wenigstens die Speicherstellen zu identifizieren. Dann kann man ggf. 
mittels Disassemblierung eine Referenz darauf finden.

Was ich nicht 100% weiss ist, ob die Software aus dem Flash ausgeführt 
wird, oder ob diese beim Systemstart ins ebenfalls am OMAP 
angeschlossene SDRAM (128MB) kopiert wird und dort läuft. Das könnte 
natürlich dann Einfluß auf die Adressen haben.

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Wer eine IDA zuhause hat, kann die Firmware als ARM Little Endian laden 
und in den Processor-options ARMv5TEJ als Befehlsebene einstellen. Die 
erste Instruction in (C)ode wandeln und schon baut sich der gesamte Baum 
auf.

von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hast Du eventuell auch einen vollständigen Flash-Dump von einem Ford 
MCA, der würde mich als Vergleich interessieren?

von Olli Z. (z80freak)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hey Dieter mein Freund! Na klar hab ich den, hängt anbei und ums Rund zu 
machen einer von nem NX gleich mit :-)

Ich habe es inzwischen auch endlich mal geschafft einen QEMU an IDA zu 
kopplen, sodass ich Code ausführen kann... aber ich lerne noch. Obwohl 
ARM(Thumb) relativ wenige Befehle hat ist es halt nicht so einfach 
daraus schlau zu werden. Selbst aus dem Decompilat von IDA in C nicht.

von Olli Z. (z80freak)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Mir ist es heute gelungen das interne Boot-ROM des OMAP5948 via JTAG 
auszulesen. Ich habe ein Dump beigefügt.

Dafür habe ich die Stromversorgung des Flash-Speichers unterbrochen 
(hier war dankenswerter Weise ein 0 Ohm Widerstand auf dem Board 
vorgesehen) und mit J-Flash die Bytes ab Adresse 0x0000 ausgelesen. 
Eigentlich ganz einfach :-)

Evtl. nutzt das ja im weiteren Verlauf der Analyse etwas...

von Petra (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
Gibt es Blaupunkt Autoradios überhaupt noch?
Früher gab es in der Hackerszene Tools mit denen sich der Code berechnen 
lies. Keine Ahnung ob diese Tools noch im Netz auffindbar sind.
Sicherheitstechnisch waren sie heutigen Passworteingaben weit voraus. 
Nach der dritten Fehleingabe wurde die Zeit bis der Code neu eingegeben 
werden konnte, stufenweise erhöht.

von Olli Z. (z80freak)


Bewertung
1 lesenswert
nicht lesenswert
Petra schrieb:
> Gibt es Blaupunkt Autoradios überhaupt noch?
> Früher gab es in der Hackerszene Tools mit denen sich der Code berechnen
> lies. Keine Ahnung ob diese Tools noch im Netz auffindbar sind.

Das Gerät um das es geht ist Baujahr 2008. Hackertools mag es geben, 
interessieren mich aber nicht, dafür würde ich auch kein Geld ausgeben. 
Mir geht es darum das selbst herauszufinden, also mehr so ne Art Rätsel 
:-) und natürlich dabei was zu lernen.

von Dieter (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Olli Z. schrieb:
> und natürlich dabei was zu lernen

Dann mal ein paar Tipps für das weitere Vorgehen: Das gesamte Flash 
Image zu disassemblieren macht in diesem Fall keinen Sinn da im Flash 
verschiedene Dinge gespeichert sind (u.a. ein Filesystem). Auch der 
Bootloader ist für den PIN-Algorithmus ohne Bedeutung. Ein Blick auf den 
Inhalt der Software-Update CD gibt dabei ein paar Hinweise was so alles 
im Flash stehen könnte.

Dabei wird man feststellen dass bestimmte Teil komprimiert sind, die 
muss man vor einer weiteren Analyse also erst entpacken.

Und noch was zu dem PIN-Algorithmus: wie aus der Seriennummer des Geräts 
die dazugehörige PIN bestimmt wird wird man in der Firmware mit großer 
Wahrscheinlichkeit nicht finden sondern nur wie die eigentliche PIN 
obfuskiert wird und dann in dem von Dir schon entdeckten Flash-Bereich 
abgelegt wird.

Ich vermute dass die Berechnung der PIN aus der Geräte-Seriennummer, wie 
es diverse Tools machen, auf einem eventuell geleakten Tool von 
Ford/Blaupunkt basieren, mit dem die Geräte bei der Produktion mit einer 
PIN versehen werden. Dafür spricht auch die entsprechende 
UDS-Funktionalität, mit der man eine neue PIN setzen kann (wenn man die 
alte kennt). Wenn die PIN schon in der Software aus der 
Geräte-Seriennummer berechnet werden würde bräuchte man sie nicht 
obfuskiert im Flash speichern.

von Johann J. (johannjohanson)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Mir geht es darum das selbst herauszufinden, also mehr so ne Art Rätsel
> :-) und natürlich dabei was zu lernen.

Viel Glück damit!

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Olli Z. schrieb:
>> und natürlich dabei was zu lernen
>
> Dann mal ein paar Tipps für das weitere Vorgehen: Das gesamte Flash

Danke für die Hinweise. Das macht Sinn was Du sagst. Zum Vergleich der 
Eingabe und dem Hash-Wert im Flash muss ja eine Berechnung stattfinden. 
Dieser Algorithmus wäre mein Ansatz zu prüfen ob er reversibel ist, 
ähnlich wie beim KM-Stand im Tacho. Gut möglich das er das nicht ist.

Aber Du kennst mich ja, mir geht es nicht darum Radios in großem Stil zu 
knacken, sondern mehr über den inneren Aufbau und die Funktion des 
Gerätes zu erforschen und da wäre Bootprozess und eben auch die 
Pin-Abfrage einfach ein praktisches Beispiel. Im Endeffekt könnte man, 
wenn man weiss wo die Pin-Abfrage stattfindet, diese Routine patchen 
sodass jeder Pin zum Erfolg führt oder die Abfrage garnicht erst 
erscheint. Zumindest für letzteres gibt es im Radio sogar eine 
Einstellung (Diebstahlschutz deaktivieren).

> Ein Blick auf den Inhalt der Software-Update CD gibt dabei ein paar Hinweise was 
so alles im Flash stehen könnte.
> Dabei wird man feststellen dass bestimmte Teil komprimiert sind, die
> muss man vor einer weiteren Analyse also erst entpacken.

Meinst Du? Ich denke da diese Updates keine Vollversionen sondern 
wirklich nur Patches sind und daher keine echten zusammenhängenden 
Blöcke darstellen und man schon garnicht ein "leeres" Radio damit 
grundbetanken könnte. Die App welche das Update durchführt wird dann 
wissen wo welche Bereiche überschrieben werden sollen. Und ja, das kann 
gut sein das die Daten dort gepackt vielleicht sogar verschlüsselt 
vorliegen, aber im Gerät selbst wird das eher nicht der Fall sein. Daher 
hatte ich mich eher an die per JTAG gelesenen Images gehalten...

von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Meinst Du?

Wenn ich etwas nur vermute schreibe ich das explizit. Schau Dir halt den 
Flash-Inhalt und die Update-CD an, dann siehst Du es selber. Auf den 
Update-CDs ist die fast vollständige Software (bis auf den Bootloader 
und teilweise DSP Software) und alles was man braucht um den Algorithmus 
für das Obfuskieren der PIN im Flash herauszufinden.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Bewertung
0 lesenswert
nicht lesenswert
Gibts für den Hauptprozessor keinen Simulator, in den man den 
Flash-Inhalt laden könnte?

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Ben B. schrieb:
> Gibts für den Hauptprozessor keinen Simulator, in den man den
> Flash-Inhalt laden könnte?

Der Hauptprozessor, also die CPU (ARM926) ist ja garnicht das Problem 
dabei. Dafür gibts genug Emulatoren (theoretisch ginge das sogar mit 
QEMU), das Problem ist der "Rest" vom OMAP und damit meine ich noch 
nichtmal den DSP, sondern die ganzen Peripheriebausteine und deren 
Memory-Mapped-IO Addressen.

Das Boot-ROM (PBL) und auch der Boot-Loader (SBL) werden reichlich auf 
diese Hardware zugreifen und entsprechende Rückmeldungen davon erwarten, 
ohne die das Programm nicht weiterlaufen wird. Das fängt mit so 
Kleinigkeiten wie der OMAP_ID an und geht weiter über eine Board-ID die 
über den Adress-Bus ermittelt wird und die Kommunikation mit den 
externen Komponenten wie z.B. dem V850 Radioprozessor.

: Bearbeitet durch User
von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Eine Sache beschäftigt mich auch noch: Wäre es nicht denkbar in den 
Flash des Gerätes einen U-Boot SBL hochzuladen und damit das System mit 
einem Linux-Kernel zu booten? Zumindest um sowas wie eine serielle 
Konsole zu erhalten und mit der Hardware zu experimentieren?
Inzwischen weiss ich ja wie ich auch den ersten Sektor löschen und 
beschreiben kann...
Vielleicht gibt es sogar eine Möglichkeit über das Boot-ROM von einem 
externen USB-Medium zu booten, oder von der SD-Card.

: Bearbeitet durch User
von Olli Z. (z80freak)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Olli Z. schrieb:
>> Meinst Du?
>
> Wenn ich etwas nur vermute schreibe ich das explizit. Schau Dir halt den
> Flash-Inhalt und die Update-CD an, dann siehst Du es selber. Auf den
> Update-CDs ist die fast vollständige Software (bis auf den Bootloader
> und teilweise DSP Software) und alles was man braucht um den Algorithmus
> für das Obfuskieren der PIN im Flash herauszufinden.

Ok. Der Inhalt teilt sich und ich denke das 
dnl/bin/system/arion/ford_hsr der richtige Ordner für mein NX ist. Darin 
finde ich die im Bild angegebenen Dateien.

Zuerst ins Auge springen einem dabei natürlich die boot.bin und 
bootload.bin, welche exakt gleich sind. Vermutlich hat man irgendwann 
mal den Dateinamen geändert und den alten/zweiten aus 
Kompatibilitätsgründen drin gelassen.

Der ist auf jeden Fall unkomprimiert und kann direkt mit IDA 
disassembliert werden. Das Array am Ende finde ich interessant, auch 
wenn ich noch keine Idee hab was das sein könnte:
ROM:000028CC ; _DWORD dword_28CC[53]
ROM:000028CC dword_28CC      DCD 0xCAFEAFFE, 0xAFFEAFFE, 0xAFFECAFE, 0xCAFECAFE, 0xCEADDECE
ROM:000028CC                 DCD 0xABCD0000, 0xABCD, 0xCEADDECE, 0x6E6B6E75, 0x6E776F
ROM:000028CC                 DCD 0x30313930, 0x39313630, 0x4E003235, 0x445F5641, 0x52415F49
ROM:000028CC                 DCD 0x5F4E4F49, 0x5F575350, 0x52415F36, 0x72615F4D, 0x5F6E6F69
ROM:000028CC                 DCD 0x53363835, 0x39305F44, 0x36303031, 0x32353931, 0x5F494400
ROM:000028CC                 DCD 0x4F495241, 0x53505F4E, 0x2E365F57, 0x36385635, 0x4F520000
ROM:000028CC                 DCD 0x54524542, 0x534F4220, 0x47204843, 0x48626D, 0, 0
ROM:000028CC                 DCD 0, 0, 0, 0, 0, 0, 3, 0, 2, 0x28, 0, 0x90A0614, 0x10000
ROM:000028CC                 DCD 0xCEADDECE, 0x31522131, 0x29A0, 0x362A2AC4

Schaut Inhaltlich so aus wie der erste Sektor vom Flash (Bootloader).

Die Datei "replace.btl" mit dem Inhalt "replace" sorgt dafür das der 
Bootloader im Flash des Gerätes ausgetauscht wird.

Die Dateien "fgs.dnl" und "radio.dnl" sind wohl die Images die vom OMAP 
aus in Richtung Graphicsboard (FGS) und Radioprozessor (V850) gesendet 
werden. Somit könnte dann die "system.elf" die Main-Software vom OMAP 
enthalten?!

Was es mit den *.uli Dateien auf sich hat erschließt sich mir noch 
nicht.

Lustig der Text vom Entwickler der am Ende von sdsapp.uli steht (SDS ist 
das Spracherkennungsmodul in der Software):
das ist ein text den ich`...gefügt habe um zu testen ob es mit..m packP...besser geht wenn mehr initialisierte da|..vorliegen "|M.tatsächlt...stimmte meine vermutung:|..gibt k€..fehler¤..beim erzeu`..des .uli-files!!!9¼?...DI_SBN_8.1V2

Hier ist die Rede von "mpack"? Wikipedia sagt darüber "mpack and munpack 
are utilities used to encode and decode binaries for use in mail 
messages following the MIME standard."
Aber was könnte ULI für ein Packformat sein? Da man große Teile des 
Textes lesen kann spricht das eher gegen LZW oder RLE. Hmm....

In der gleichen Datei findet man diesen String 
"X:\di_sbn\products\boot\sdsapp\source.._¬....cpp" der die Vermutung 
nahe legt das es in C++ geschrieben wurde, also kein Java Byte-Code oder 
sowas ist.

Die "system.elf" ist auch nicht komprimiert, die kann IDA öffnen und 
disassemblieren.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Bewertung
0 lesenswert
nicht lesenswert
> 0xCAFEAFFE, 0xAFFEAFFE, 0xAFFECAFE, 0xCAFECAFE
Wie ausführbarer Code sieht das jedenfalls nicht aus, eher wie 
irgendwelche magic quotes.

von grumpel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Die "system.elf" ist auch nicht komprimiert, die kann IDA öffnen und
> disassemblieren.

Das muss nichts heissen. Du kannst auch ein JPEG durch den duisasembler 
jagen und sagen, das sei 8086 code. Rauskommen wird dabei natürlich nur 
Müll, aber wenn der User es so will...

von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Das Array am Ende finde ich interessant, auch
> wenn ich noch keine Idee hab was das sein könnte

Warum lädst Du die Datei in einen Disassembler wenn Du dann diese Frage 
stellst? Schau Dir halt den Code an, dann siehst Du es. Der Bootloader 
ist wirklich einfach, und der ARM Code nicht sehr schwierig zu 
verstehen, an solchen Beispielen kann man gut üben. Wobei das zwar 
nichts dazu beiträgt den PIN Algorithmus zu finden aber man kann an 
einem einfachen Beispiel mal ausprobieren wie Reverse-Engineering 
funktioniert.

Und wenn es immer noch zu kompliziert ist: Der Bootloader lädt im Großen 
und Ganzen lediglich "system.elf" und ist im Prinzip ein einfacher ELF 
Loader, der erste Teil dieser 32-Bit Werte ist ein Marker der in dem 
Image gesucht wird.

von Johann J. (johannjohanson)


Bewertung
1 lesenswert
nicht lesenswert
Ben B. schrieb:
> 0xCAFEAFFE, 0xAFFEAFFE, 0xAFFECAFE, 0xCAFECAFE

Cafe Affe, Affe Affe, Affe Cafe, Cafe Cafe :-)

Accent aigu muss man sich halt denken  ...

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Johann J. schrieb:
> Ben B. schrieb:
>> 0xCAFEAFFE, 0xAFFEAFFE, 0xAFFECAFE, 0xCAFECAFE
> Cafe Affe, Affe Affe, Affe Cafe, Cafe Cafe :-)

Ja, man könnte es für einen Gag der Entwickler halten, aber es ist wohl 
eher so wie Dieter gesagt hat, denn diese Kombi findet man auch im 
"system.elf" wieder.

: Bearbeitet durch User
von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Schau Dir halt den Code an, dann siehst Du es. Der Bootloader
> ist wirklich einfach, und der ARM Code nicht sehr schwierig zu
> verstehen, an solchen Beispielen kann man gut üben. Wobei das zwar

Einfach... für jemand Deines Kalibers vielleicht. Ich hock schon zwei 
Tage vor dem Code und weiss praktisch noch garnichts darüber.

Vielleicht gehe ich es auch falsch an, Vom RESET-Vector aus durchlaufen 
zu wollen? Grundsätzlich sind es ja nur Nebeneffekte die etwas ausmachen 
und die sind für mich aktuell nicht immer leicht zu finden. Daher hatte 
ich ja gehofft etwas zu begreifen wenn man mal ein paar Subs mit mir 
zusammen durchackert. Aber vermutlich hätte ich besser 2-3 Jahre 
Assemblererfahrung haben sollen und überhaupt rückwärts denken zu können 
:-)

von Soul E. (souleye)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:

> Ja, man könnte es für einen Gag der Entwickler halten, aber es ist wohl
> eher so wie Dieter gesagt hat, denn diese Kombi findet man auch im
> "system.elf" wieder.

Sowas nimmt man zum Initialisieren von Speicherbereichen, um dann z.B. 
die maximale Stackgröße bestimmen zu können. 0xDEAD BEEF ist auch 
beliebt, oder klassisch 0x5AA5 A55A.

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
soul e. schrieb:
> Sowas nimmt man zum Initialisieren von Speicherbereichen, um dann z.B.
> die maximale Stackgröße bestimmen zu können. 0xDEAD BEEF ist auch
> beliebt, oder klassisch 0x5AA5 A55A.

Du scheinst das zu kennen. Magst Du mir das Prinzip dahinter erklären? 
Ich kapiers noch nicht.

von Soul E. (souleye)


Bewertung
1 lesenswert
nicht lesenswert
Du schreibst ein markantes Muster ins RAM, dann lässt Du Deins Software 
eine Weile rödeln, und dann guckst Du nach welche Bereiche überschrieben 
wurden und ob das Deinen Erwartungen entspricht.

Aufwendigere Betriebssysteme bringen Funktionen zum Speicherschutz und 
Stack Monitoring mit, da braucht man solche einfachen Tricks nicht mehr.

: Bearbeitet durch User
von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
soul e. schrieb:
> Du schreibst ein markantes Muster ins RAM, dann lässt Du Deins Software
> eine Weile rödeln, und dann guckst Du nach welche Bereiche überschrieben
> wurden und ob das Deinen Erwartungen entspricht.

Ah, ich glaube ich verstehe was Du meinst. Um vielleicht zu erkennen 
wenn eine Funktion sich selbst rekursiv aufruft, oder unerwartet tiefe 
Schachtelungen auftreten und dadurch der verfügbare Speicher immer 
kleiner wird durch den anwachsenden Stack.

Also nehmen wir mal an das würde hier so gemacht werden, dann müsste ja 
irgendwas in dem Bootloader auch darauf prüfen, also sowas in der Art 
wie "if(*(SP-8)==0xCAFEAFFE) { error("Stack overflow"); }" ?

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Bewertung
0 lesenswert
nicht lesenswert
> Du kannst auch ein JPEG durch den duisasembler jagen und sagen,
> das sei 8086 code.
Das wird jede Menge illegaler OpCodes erzeugen und daran sollte man 
recht schnell merken, daß man probiert, Daten zu disassemblieren.

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Also, ich sauge gerad an ARM disassembler-tutorials ein was geht. Ein 
paar Konzepte sind mir inzwischen schon geläufig. Z.B.:
Das zum laden von Speicheradressen häufig referenzierte Konstanten zum 
Einsatz kommen, welche sich "in der Nähe" des nutzenden Codes befinden 
müssen.
Oder das mit BX und einer ungeraden Ziehladresse in Thumb und mit einer 
geraden in den ARM Status gewechselt wird.
Oder das Subroutinen mit BL ausgeführt und mit BX LR zurück.
usw.

Aber, auch die Arbeit mit IDA Pro will gelernt sein ;-)
Sehr schick ist ja die graphische Anzeige, da erkennt man auf einen 
Blick switch-Konditionen. Auch die C Pseudo-Code Generierung ist 
interessant, wenn auch nicht immer so verständlich wie man sich das 
wünschen würde ;-)
Komisch finde ich allerdings das IDA beides nur für Subroutinen 
(Functions) macht und nicht auch für den Linearen Code.

Man darf aber ja auch nicht vergessen das den Assemblercode ein C++ 
Compiler erzeugt hat und kein Mensch. Daher wird man sicher häufiger auf 
komische Dinge stossen, aber es sollten sich auch Muster erkennen 
lassen.

Ich habe mal was über eine Methode gelesen wie man so verwendete 
Bibliotheken ermitteln können soll. Irgendwie logisch, wenn ein ARM 
Executeable statisch gelinkte Libs enthält, müsste man die fast mit 
einer einfachen Bytesuche aufstöbern können!?

Das von Dieter genannte SYSTEM.ELF könnte sowas enthalten, denn die 
Entwickler haben sicher nicht alles neu erfunden. Ich vermute auch das 
hier der Kernel drin steckt, welcher ggf. auch wieder was 
standardmäßiges wie ein RTOS ist.

von Johann J. (johannjohanson)


Bewertung
-1 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Man darf aber ja auch nicht vergessen das den Assemblercode ein C++
> Compiler erzeugt hat

Gibt es nur C++-Compiler? Merkwürdig, ich dachte, es gäbe da viel mehr 
...

Wenn Du Dich mit der Thematik und angewandten Techniken (der 
"Verschleierung") nicht auskennst - vergiss es.

: Bearbeitet durch User
von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Dieter, eine Frage an Dich als Vollblutprofi: Ich weiss das beim Booten 
der Zustand der EMIFS-Adressleitungen einmal eingelesen wird und anhand 
des Musters verschiedene Images gestartet werden können. Das sieht man 
auch im Bootloader anhand der Strings. Auch wird die Board-ID so 
übermittelt wodurch die Software weiss welche Hardware für welches 
Fahrzeug sie darstellt.

Jedoch finde ich diesen Zugriff nicht im SBL. Kan das sein das der im 
PBL des OMAP steckt?

An die EMIFS_A1-A25 Adressleitungen wird mit teils fest verdrahteten, 
teils über PNP-Transistoren geschaltete 4,7k Widerstände gegen Vcc ein 
Muster generiert. Der Widerstand ist so groß das die am Adressbus 
hängenen Chips störungsfrei eine 0 (GND) erzeugen können und dieser 
Umstand nicht weiter ins Gewicht fällt. Die Widerstände wirken eher wie 
Pullups.

Für den normalen Start müsste es so ein Muster sein:

A25..A0
*****100000000001000010**
('*' bedeutet, beliebig)

: Bearbeitet durch User
von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Das sieht man
> auch im Bootloader anhand der Strings

Welche Strings meinst Du, die in "bootload.bin"? Da stehen zum großen 
Teil Namen von Sections des ELF-Image ("system.elf"), die der Loader 
besonders behandelt.

von Philipp K. (philipp_k59)


Bewertung
0 lesenswert
nicht lesenswert
ist das ein Travelpilot FX?

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Olli Z. schrieb:
>> Das sieht man
>> auch im Bootloader anhand der Strings
>
> Welche Strings meinst Du, die in "bootload.bin"? Da stehen zum großen
> Teil Namen von Sections des ELF-Image ("system.elf"), die der Loader
> besonders behandelt.

Genau, da gibt es TEST und andere Dinge.

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Philipp K. schrieb:
> ist das ein Travelpilot FX?

Die hier behandelten Info sind von einem NX, aber grundsätzlich ist das 
beim FX und beim MCA genauso.

von Philipp K. (philipp_k59)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Die hier behandelten Info sind von einem NX, aber grundsätzlich ist das
> beim FX und beim MCA genauso.

Mein FX liegt hier bestimmt noch 10 Tage rum bis die Ram Riegel da 
sind.. zum Flash/Rom auslesen etc hab ich eigentlich alles da wenn ich 
nicht großartig dran rumbraten muss könnte ich da was auslesen.. 
allerdings sind im moment die RAMs ausgelötet.

von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Genau, da gibt es TEST und andere Dinge.

Diesen Namen haben, wie schon geschrieben, nichts mit irgendwelchen 
unterschiedlichen Images zu tun, die in Abhängigkeit der 
Hardware-Konfiguration geladen werden sondern es sind Sections in dem 
ELF Image.

Das sieht man ganz einfach wenn man sich den Bootloader-Code ansieht 
(die Strings werden per memcmp() verglichen) oder man schaut sich die 
Struktur des ELF Image an (dazu muss man noch nicht einmal Assembler 
Code lesen).

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Philipp K. schrieb:
> Mein FX liegt hier bestimmt noch 10 Tage rum bis die Ram Riegel da
> sind.. zum Flash/Rom auslesen etc ha

Flash auslesen geht auch ohne RAM, aber da brauchen wir nichts, wär 
alles verfügbar. FXe hab ich alle Varianten hier rumliegen, mehrfach ;-)

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Ich bin an einen Decoder ran gekommen, in Javascript:
// must be some kind of private key?
var array = [8, 0, 5, 7, 9, 2, 6, 1, 4, 3, 1, 2, 4, 9, 8, 3, 0, 6, 5, 7, 7, 8, 9, 4, 3, 6, 1, 0, 2, 5, 2, 9, 8, 0, 7, 5, 4,
3, 6, 1, 0, 4, 1, 5, 6, 7, 2, 9, 3, 8, 9, 6, 0, 1, 5, 4, 3, 7, 8, 2, 6, 7, 3, 8, 2, 1, 9, 5, 0, 4, 5, 3, 6, 2, 1, 0, 8, 4,
7, 9, 3, 1, 7, 6, 4, 8, 5, 2, 9, 0, 4, 5, 2, 3, 0, 9, 7, 8, 1, 6];
const calc = (a, b) => array[(a * 10) + b];
const calculate = w => [
calc(calc(calc(w[4], calc(w[3], calc(w[2], calc(w[1], w[4])))), calc(w[9], calc(w[8], calc(w[7], calc(w[6], w[9]))))),
calc(w[5], w[0])),
calc(calc(calc(w[3], calc(w[2], calc(w[1], w[4]))), calc(w[8], calc(w[7], calc(w[6], w[9])))), calc(w[5], w[0])),
calc(calc(calc(calc(w[4], calc(w[3], calc(w[2], calc(w[1], w[4])))), calc(w[2], calc(w[1], w[4]))), calc(calc(w[9],
calc(w[8], calc(w[7], calc(w[6], w[9])))), calc(w[7], calc(w[6], w[9])))), calc(w[5], w[0])),
calc(calc(calc(calc(w[3], calc(w[2], calc(w[1], w[4]))), calc(w[1], w[4])), calc(calc(w[8], calc(w[7], calc(w[6],
w[9]))), calc(w[6], w[9]))), calc(w[5], w[0]))
].join("");
const parse = (prefix, serial) => (prefix+serial).split("").map(v => parseInt(v, 10))
// prefixes:
// 7 612 300 5** - 300
// 7 612 330 5** - 330
// 7 612 360 5** - 360
// real codes found online, for tests
console.log(calculate(parse("300", "9106162")), "9223");

Damit kann man PIN codes des "A05" Algorithmus errechnen. Das Array mit 
den Hash-Werten habe ich im Firmwareimage leider nicht finden können.

Habe mir zum testen mal ein kleines Tool in mein Wiki integriert:
https://mk4-wiki.denkdose.de/artikel/nav_fx/pin_code_decryptor

von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Das Array mit
> den Hash-Werten habe ich im Firmwareimage leider nicht finden können.

Die Voraussetzung für eine Suche ist dass die gepackten Teile der 
Firmware vorher entpackt wurden. Aber wie schon früher geschrieben, der 
Algorithmus für die Berechnung des PIN Code aus der Geräte-Seriennummer 
steckt mit ziemlicher Sicherheit nicht in der Firmware. Dort gibt es nur 
den Algorithmus wie die PIN obfuskiert wird um sie im Flash zu 
speichern. Man kann ja auch die PIN im Gerät ändern, dann passt die 
Berechnung aus der Geräte-Seriennummer nicht mehr.

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Die Voraussetzung für eine Suche ist dass die gepackten Teile der
> Firmware vorher entpackt wurden.
Hieran bin ich bislang gescheitert. Ich wüsste nicht was komprimiert ist 
und womit. Und kommt da am Ende was anderes raus als im Firmwareimage 
steht?

Auch den Bootloader hab ich nur zum Teil verstanden.

> den Algorithmus wie die PIN obfuskiert wird um sie im Flash zu
> speichern. Man kann ja auch die PIN im Gerät ändern,
Davon habe ich beim FX (NX und MCA) noch nie gehört. Auch kenne ich 
keine UDS Prozedur (via CAN) dafür. Woher hast Du diese Info?

von Lukasz (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
code

von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Ich wüsste nicht was komprimiert ist
> und womit. Und kommt da am Ende was anderes raus als im Firmwareimage
> steht?

Die ".ULI" Dateien sind komprimiert. Diese Dateien werden auch 
komprimiert im Flash abgelegt und bei Gebrauch in den RAM ausgepackt.

Olli Z. schrieb:
> Davon habe ich beim FX (NX und MCA) noch nie gehört. Auch kenne ich
> keine UDS Prozedur (via CAN) dafür. Woher hast Du diese Info?

Entsprechende UDS Funktionen sind im Code. Sehr wahrscheinlich werden 
die in der Produktion genutzt, eventuell sind die in einer normalen 
Diagnose-Session nicht zu erreichen.

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Lukasz schrieb:
> code

Es stimmt das der jeweilige PIN im Image des Flash (mehrfach) im 
Klartext abgelegt wird. ABER....

a) man muss wissen WO das ist (ich habe in mehr als 10 Images 
nachgeschaut und er liegt jedesmal an anderen Speicherstellen) oder man 
ein eindeutiges Prefix/Kontext hat.

b) wird er dort sicher nur hineinkopiert aber nicht abgeprüft. Die 
Prüfung geschieht über den genannten Sector im Flash und die darin 
enthaltene Seriennummer

c) man muss das Image auslesen können (wer das kann, kann den Sector 
auch mit einer Wunsch-Pin umprogrammieren)

Dennoch interessant fürs Reverse Engineering, denn der ist dort nicht 
von Hause aus, sondern wir von der software dort hingeschrieben. Diesen 
Schreibzugriff müsste man zurückverfolgen um auf die Routine zu gelangen 
die dies macht und da wäre man schon im richtigen Bereich für die Suche 
nach dem Algo.

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Die ".ULI" Dateien sind komprimiert. Diese Dateien werden auch
> komprimiert im Flash abgelegt und bei Gebrauch in den RAM ausgepackt.
Nachdem was ich so finden konnte, könnte das eine LZO-Kompression sein 
(Lempel-Ziv-Oberhumer). Ein Kompressionsverfahren auf Wörterbuch-Basis 
wie z.B. das gute alte GIF. Das wäre dann auch eine Erklärung warum man 
Teile lesen kann.
Leider ist der Header komplett anders als es der LZO-Standard vorsieht, 
wodurch die Packprogramme (habe jetzt mal lzop auf Linux getestet) das 
Format nicht erkennen. Ein Fake-Header hat auch nicht geklappt weil 
darin div. Parameter zur Kompression/Dekompression enthalten sind und 
u.a. auch noch eine Prüfsumme über die gesamte Datei.

> Entsprechende UDS Funktionen sind im Code. Sehr wahrscheinlich werden
> die in der Produktion genutzt, eventuell sind die in einer normalen
> Diagnose-Session nicht zu erreichen.
Sowas konnte ich noch nicht finden weil ich noch keine Idee habe wie ich 
das erkenne. Womöglich müsste man erst die CAN-Handling Routine finden. 
Die wird aber schwer zu finden sein, da vom OMAP kein CAN-Controller 
genutzt wird. Es wird vielmehr der im Radioprozessor (V850) integrierte 
CAN-Controller genutzt (hierhin laufen auch die CAN-Leitungen vom 
Transceiver auf dem Board) und der V850 wiederum ist via SPI mit dem 
OMAP verbunden.

Ich bin wieder einen Schritt weiter, aber stehe nun wieder vor diversen 
Rätseln.

von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Leider ist der Header komplett anders als es der LZO-Standard vorsieht,
> wodurch die Packprogramme (habe jetzt mal lzop auf Linux getestet) das
> Format nicht erkennen.

Stimmt so nicht ganz. Die kleinen ".ULI" Dateien (< 20 kByte) lassen 
sich durch eine triviale Änderung (Tipp: die ersten vier Bytes) mit 
"lzopack" auspacken. Mit diesem Wissen kommt man dann auch bei den 
größeren Dateien mit etwas Kreativität weiter (Tipp: es sind mehrere 
Teile, die getrennt ausgepackt und am Schluss wieder zusammengesetzt 
werden, entsprechend sind mehrere Einträge für die einzelnen Teile im 
Header).

Olli Z. schrieb:
> Sowas konnte ich noch nicht finden weil ich noch keine Idee habe wie ich
> das erkenne.

Man erkennt das ziemlich schnell wenn man den Code für die zuständigen 
Funktionen ausgepackt hat.

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Danke für Deine Hilfe Dieter! Bin grad nicht einsatzfähig, aber teste 
das sobald ich kann. Ich denke Du meinst den Magic header im File. Werde 
mal was ausprobieren... aber das hatte ich mir eigentlich schon alles 
angesehen. In der offiziellen Formatbeschreibung ist ein 7 Byte header 
vorgesehen und in der Source hier 
https://github.com/nemequ/lzo/blob/master/examples/lzopack.c
habe ich in Funktion do_decompress() auch gelesen das dieser explizit in 
Länge und Bytefolge abgefragt wird. Der Start der plattapp.uli ist 
jedoch nicht nur in den ersten 4 Bytes unterschiedlich. Womöglich ist 
der Header dieser Datei nicht der Start eines LZO-Archives, sondern 
mehrerer in einem ULI-Container gesammelter (ähnlich tar)..

Aber ich knobel nochmal etwas, zumindest gut zu wissen auf der richtigen 
Spur zu sein...

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Ich hab jetzt einiges mit LZO rumprobiert, komme aber zu keinen rechten 
Ergebnis. Zunächst habe ich mit ein lzop.exe heruntergeladen und damit 
eine Minimaldatei erzeugt um ein funktionierendes, echtes Archiv zu 
untersuchen. Dies hier ist der Hexdump aus einer nur mit drei Zeichen 
("LZO") bestehenden Textdatei welche ich comprimiert habe:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000  89 4C 5A 4F 00 0D 0A 1A 0A 10 30 20 40 09 40 01  ‰LZO......0 @.@.
00000010  05 0E 30 00 31 00 00 81 B6 5D A2 1E DD 5D A2 1E  ..0.1...¶]¢.Ý]¢.
00000020  DD 08 74 65 73 74 2E 74 78 74 80 21 09 E0 00 00  Ý.test.txt€!.à..
00000030  00 03 00 00 00 03 01 EA 00 F6 4C 5A 4F 00 00 00  .......ê.öLZO...
00000040  00                                               .

Wie schon erwähnt besteht das Magic von LZO aus 9 Zeichen:
Offset(h) 00 01 02 03 04 05 06 07 08 
00000000  89 4C 5A 4F 00 0D 0A 1A 0A  ‰LZO.....

Hier habe ich die gesamte Header-Info eines LZO-Archivs her 
https://gist.github.com/jledet/1333896
Magic: 9 bytes (0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a)
Version: 2 bytes
Lib version: 2 bytes
Version needed: 2 bytes
Method: 1 byte
Level: 1 byte
Flags: 4 byte
Filter: 4 bytes (only if flags & F_H_FILTER)
Mode: 4 bytes
Mtime: 4 bytes
GMTdiff: 4 bytes
File name length: 1 byte
Name: 0-255 bytes
Checksum, original data: 4 bytes (CRC32 if flags & F_H_CRC32 else Adler32)
Uncompressed size: 4 bytes
Compressed size: 4 bytes
Checksum, uncompressed data: 4 bytes
Checksum, compressed data: 4 bytes (only if flags & F_ADLER32_C or flags & F_CRC32_C)
Compressed data: 0-xxx bytes

Der Header der kleinen "basereg.uli" von der Ford-Update-CD schaut so 
aus:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000  55 4C 49 20 00 00 00 00 01 00 00 00 02 00 00 00  ULI ............
00000010  00 00 00 00 24 00 00 00 BB 0A 00 00 42 03 00 00  ....$...»...B...
00000020  93 E4 44 C8 00 0B AC BB B9 BB BA B7 AA CA F4 A5  “äDÈ..¬»¹»º·ªÊô¥
00000030  B6 B5 BB A7 A1 B2 B1 BD BF B2 A1 B3 BF BD B6 B7  ¶µ»§¡²±½¿²¡³¿½¶·
...
00000350  20 CF 20 0F 24 0E 7B 09 B1 BA B1 A8 FA 2F 0F 0E   Ï .$.{.±º±¨ú/..
00000360  CC F4 01 11 00 00 FF FF 00 00 00 00 00 00 00 00  Ìô....ÿÿ........
00000370  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000380  00 00 00 00 00 00 00 00 03 00 00 00 04 00 00 00  ................
00000390  02 00 00 00 3C 00 00 00 00 00 00 00 10 0A 08 0B  ....<...........
000003A0  00 00 01 00 CE DE AD CE 31 21 52 31 B4 03 00 00  ....ÎÞ.Î1!R1´...
000003B0  61 1C 56 EC                                      a.Vì

Jetzt gehe ich mal einfach her und nemhe die 4 Byte Magic und pumpe dort 
den 9 Byte Magic von LZO rein, wohlwissen das damit jegliche CRC 
vermutlich zum Teufel sein wird:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000  89 4C 5A 4F 00 0D 0A 1A 0A 00 00 00 00 01 00 00  ‰LZO............
00000010  00 02 00 00 00 00 00 00 00 24 00 00 00 BB 0A 00  .........$...»..
00000020  00 42 03 00 00 93 E4 44 C8 00 0B AC BB B9 BB BA  .B...“äDÈ..¬»¹»º
Wenn ich das mit der obigen Beschreibung vergleiche passt da fast nichts 
zusammen. Daher vermute ich das dies entweder eine modifizierte oder 
eine sehr frühe Version von LZO ist. Oder ein Teil der 
Header-Information ist ans Ende der Datei geschrieben worden.

: Bearbeitet durch User
von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Wenn ich das mit der obigen Beschreibung vergleiche passt da fast nichts
> zusammen.

Und warum nimmst Du nicht "lzopack", wie ich es geschrieben habe?

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Olli Z. schrieb:
>> Wenn ich das mit der obigen Beschreibung vergleiche passt da fast nichts
>> zusammen.
>
> Und warum nimmst Du nicht "lzopack", wie ich es geschrieben habe?

Ähm, ja, natürlich. Ist unter "examples" im code. Klappt aber leider 
auch nicht.

Habe den Header der basereg.uli so modifiziert das das im Source 
geforderte Magic (7 bytes) vorn dran steht. Da in der Originaldatei nur 
4 Byte magic drin stehen habe ich den Anfang der Datei um 3 Bytes 
vergrößert:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000  00 E9 4C 5A 4F FF 1A 00 00 00 00 01 00 00 00 02  .éLZOÿ..........
00000010  00 00 00 00 00 00 00 24 00 00 00 BB 0A 00 00 42  .......$...»...B
00000020  03 00 00 93 E4 44 C8 00 0B AC BB B9 BB BA B7 AA  ...“äDÈ..¬»¹»º·ª
Dabei bricht dann der "lzopack -d basereg.uli basereg.bin" mit der 
Meldung ab: "header error - invalid blocksize 512". Im Source erkennt 
man warum: an der Speicherstelle der Blockgröße steht in der Datei der 
Long "00 00 02 00", also 512 Byte, aber laut Source müssen es mindestens 
1024 Byte sein.

Den Wert in der Datei einfach zu erhöhen brachte keine Besserung, zwar 
ging der Test dann durch aber es kam keine Datei heraus (0 byte).

Es sieht im Source so aus als wäre der Header bei diesem Format nur 17 
Bytes lang:
7  Magic (00 E9 4C 5A 4F FF 1A)
4  Flags (00 00 00 00)
1  Method (01 => das ist gut, denn im Source wird nur diese zugelassen 
:-)
1 Compression level (00 => hmm)
4 Block size (00 00 02 00 = 512 Bytes)

von Dieter (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Klappt aber leider
> auch nicht.

Sorry, mein Fehler. Ich sehe hier gerade dass der Header im Vergleich 
zum original "lzopack" doch länger ist: nach den 4 Byte Magic kommen 
acht 32-Bit Werte (Little Endian), gebraucht werden davon die letzten 
drei (Block Größe, gepackte Größe, CRC). Die ausgepackte Größe gibt es 
nicht im Header und kann auf die Block Größe gesetzt werden. Die CRC ist 
nicht Adler32 sondern CRC32, die entsprechende Funktion gibt es in der 
LZO Library. Die ursprünglich von "lzopack" gelesenen Werte "flags", 
"method" und "compression_level" setzt man auf 1.

Für die größeren .ULI Dateien enthält der Header dann Angaben zu mehr 
als einem mit LZO gepackten Datenblock.

von Olli Z. (z80freak)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Olli Z. schrieb:
>> Klappt aber leider
>> auch nicht.
>
> Sorry, mein Fehler. Ich sehe hier gerade dass der Header im Vergleich
> zum original "lzopack" doch länger ist: nach den 4 Byte Magic kommen
> acht 32-Bit Werte (Little Endian), gebraucht werden davon die letzten
> drei (Block Größe, gepackte Größe, CRC). Die ausgepackte Größe gibt es
> nicht im Header und kann auf die Block Größe gesetzt werden. Die CRC ist
> nicht Adler32 sondern CRC32, die entsprechende Funktion gibt es in der
> LZO Library. Die ursprünglich von "lzopack" gelesenen Werte "flags",
> "method" und "compression_level" setzt man auf 1.
>
> Für die größeren .ULI Dateien enthält der Header dann Angaben zu mehr
> als einem mit LZO gepackten Datenblock.

Also verstehe ich Dich richtig? ...
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000  55 4C 49 20 00 00 00 00 01 00 00 00 02 00 00 00  ULI ............
00000010  00 00 00 00 24 00 00 00 BB 0A 00 00 42 03 00 00  ....$...»...B...
00000020  93 E4 44 C8 00 0B AC BB B9 BB BA B7 AA CA F4 A5  “äDÈ..¬»¹»º·ªÊô¥
4 Byte magic = "ULI "
Nun folgen acht 4-Byte (32-Bit) Werte im Little Endian Format:
1.) 00 00 00 00
2.) 01 00 00 00
3.) 02 00 00 00
4.) 00 00 00 00
5.) 24 00 00 00
6.) BB 0A 00 00 = Block Größe = 0xABB
7.) 42 03 00 00 = Gpackte Größe = 0x342
8.) 93 E4 44 C8 = CRC32 = 0xC844E493
Dann folgen die Daten:
00 0B AC BB B9 BB BA B7 AA CA F4 A5 ...

Ich habe nun den Code von examples/lzopack.c aus dem Paket 
http://www.oberhumer.com/opensource/lzo/#download etwas modifiziert:
[code c]
/* magic file header for lzopack-compressed files */
static const unsigned char magic[4] =
    { 0x55, 0x4C, 0x49, 0x20 }; // "ULI "

/* read Little Endian 32-bit integer */
static lzo_uint32_t xread32_le(FILE *fp)
{
    unsigned char b[4];
    lzo_uint32_t v;

    xread(fp, b, 4, 0);
    v  = (lzo_uint32_t) b[0] <<  0;
    v |= (lzo_uint32_t) b[1] <<  8;
    v |= (lzo_uint32_t) b[2] << 16;
    v |= (lzo_uint32_t) b[3] << 24;
    return v;
}

static int do_decompress(FILE *fi, FILE *fo)
{
    int r = 0;
    lzo_bytep buf = NULL;
    lzo_uint buf_len;
    unsigned char m [ sizeof(magic) ];
    lzo_uint32_t flags;
    int method;
    int compression_level;
    lzo_uint block_size;
    lzo_uint32_t checksum;
    lzo_uint32_t dummy;

    total_in = total_out = 0;

/*
 * Step 1: check magic header, read flags & block size, init checksum
 */
    if (xread(fi, m, sizeof(magic), 1) != sizeof(magic) ||
        memcmp(m, magic, sizeof(magic)) != 0)
    {
        printf("%s: header error - this file is not compressed by 
lzopack\n", progname);
        r = 1;
        goto err;
    }

    dummy = xread32(fi); // ??? (00 00 00 00)
    dummy = xread32(fi); // ??? (01 00 00 00)
    dummy = xread32(fi); // ??? (02 00 00 00)
    dummy = xread32(fi); // ??? (00 00 00 00)
    dummy = xread32(fi); // ??? (24 00 00 00)
    block_size = 0x2000; // DUMMY

    flags = 1; // fixed
    method = 1; // fixed
    compression_level = 1; // fixed
    checksum = lzo_crc32(0, NULL, 0);

/*
 * Step 2: allocate buffer for in-place decompression
 */
    buf_len = block_size + block_size / 16 + 64 + 3;
    buf = (lzo_bytep) xmalloc(buf_len);
    if (buf == NULL)
    {
        printf("%s: out of memory\n", progname);
        r = 4;
        goto err;
    }

/*
 * Step 3: process blocks
 */
    for (;;)
    {
        lzo_bytep in;
        lzo_bytep out;
        lzo_uint in_len;
        lzo_uint out_len;

        /* read uncompressed size */
        out_len = xread32_le(fi); // UNCOMPR SIZE (BB 0A 00 00)
    printf("Uncompressed size: %d (0x%X) bytes\n", out_len, out_len);
        /* exit if last block (EOF marker) */
        if (out_len == 0)
            break;

        /* read compressed size */
        in_len = xread32_le(fi); // COMPR SIZE (42 03 00 00)
    printf("Compressed size: %d (0x%X) bytes\n", in_len, in_len);

        /* sanity check of the size values */
        if (in_len > block_size || out_len > block_size ||
            in_len == 0 || in_len > out_len)
        {
            printf("%s: block size error - data corrupted\n", progname);
            r = 5;
            goto err;
        }

        /* place compressed block at the top of the buffer */
        in = buf + buf_len - in_len;
        out = buf;

        /* read compressed block data */
        xread(fi, in, in_len, 0);

        if (in_len < out_len)
        {
            /* decompress - use safe decompressor as data might be 
corrupted
             * during a file transfer */
            lzo_uint new_len = out_len;

            r = lzo1x_decompress_safe(in, in_len, out, &new_len, NULL);
            if (r != LZO_E_OK || new_len != out_len)
            {
                printf("%s: compressed data violation\n", progname);
                r = 6;
                goto err;
            }
            /* write decompressed block */
            xwrite(fo, out, out_len);
            /* update checksum */
            if (flags & 1)
                checksum = lzo_crc32(checksum, out, out_len);
        }
        else
        {
            /* write original (incompressible) block */
            xwrite(fo, in, in_len);
            /* update checksum */
            if (flags & 1)
                checksum = lzo_crc32(checksum, in, in_len);
        }
    }

    /* read and verify checksum */
    if (flags & 1)
    {
        lzo_uint32_t c = xread32_le(fi); // CRC32

        if (c != checksum)
        {
            printf("%s: checksum error - data corrupted\n", progname);
            r = 7;
            goto err;
        }
    }

    r = 0;
err:
    lzo_free(buf);
    return r;
}
[/code]

Wie man erkennt ist die Checksum die hier normalerweise genutzr wird 
nicht im Header sondern im Trailer des komprimierten Files zu finden. 
Was auch daher zu erklären ist, das die Prüfsumme auf den 
dekomprimierten Teil der Daten berechnet ist. Die Methoden zur 
Berechnung habe ich, wie von Dir vorgeschlagen von "adler32" auf "crc32" 
geändert.

Das mit Blocksize kommt mir komisch vor. Wenn ich das so nehme wie Du 
sagst, dann wäre die Blocksize im 6. 32-Bit Wert des Headers, also 
0xABB. Warum aber wird eine solch "krumme" Blockgröße verwendet? So wie 
ich die Blocks verstanden habe sind das in erster Linie Buffer die in 
der Lage sind den unkomprimierten Teil zzgl. ein paar Zwischenzustände 
aufnehmen zu können. Da hätte man doch eigentlich eher 0x1000 genommen 
oder sowas?! Für mich sieht das ja doch eher nach der unkomprimierten 
Größe aus. Im Sourcecode kann man erkennen das diese durchaus benötigt 
wird, um z.B. den output-Buffer zu initiieren.

Dann noch die Frage zur IN-Size (Länge der komprimierten Daten): Die ist 
mit 0x342 grundsätzlich plausibel. Nehme ich nun als Start der Daten den 
Offset 0x0020 dann lande ich bei 0x0361 als letztes Byte. Das sieht so 
irgendwie auch stimmig aus vom Bytemuster her, denn danach kommen noch 
etliche Daten mit vielen 0x00ern drin und am Ende könnte das wieder eine 
Checksum sein:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
...
00000350  20 CF 20 0F 24 0E 7B 09 B1 BA B1 A8 FA 2F 0F 0E   Ï .$.{.±º±¨ú/..
00000360  CC F4 01 11 00 00 FF FF 00 00 00 00 00 00 00 00  Ìô....ÿÿ........
00000370  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000380  00 00 00 00 00 00 00 00 03 00 00 00 04 00 00 00  ................
00000390  02 00 00 00 3C 00 00 00 00 00 00 00 10 0A 08 0B  ....<...........
000003A0  00 00 01 00 CE DE AD CE 31 21 52 31 B4 03 00 00  ....ÎÞ.Î1!R1´...
000003B0  61 1C 56 EC                                      a.Vì

Aber egal, habe es kompiliert und erhalte nur den Fehler:
Uncompressed size: 2747 (0xABB) bytes
Compressed size: 834 (0x342) bytes
lzopack.exe: compressed data violation
was wohl soviel bedeutet das die dekomprimierung nicht erfolgreich war 
:-(

Dann habe ich nochmal etwas gehackt und doch wie von Dir angenommen das 
der 8. 32-Bit Header-Wert die CRC ist und diese "überlesen" bevor ich 
den decoder gefüttert habe. Heraus kam das er das Dateiende nicht so 
richtig erkannt hat, aber er hat mir eine BIN Datei erstellt ohne 
"violation" und mit der richtigen CRC (Datei angehangen). Ob jetzt diese 
"basereg" (Registry?) nun irgendwas sinnvolles enthält... weiss noch 
nicht, werde mich mal an den anderen Dateien versuchen.

: Bearbeitet durch User
von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Ob jetzt diese "basereg" (Registry?) nun irgendwas sinnvolles enthält... > > 
weiss noch nicht, werde mich mal an den anderen Dateien versuchen.

Die ausgepackte Datei stimmt so, in den kleinen Dateien steht aber 
nichts direkt lesbares. Interessant wird es erst bein den größeren 
Code-Dateien.

von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Noch eine Korrektur: Die Blockgröße ist die Größe der ausgepackten 
Daten, das Ergebnis ändert sich dadurch aber nicht (LZO packt nur soviel 
aus wie tatsächlich da ist).

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Noch eine Korrektur: Die Blockgröße ist die Größe der ausgepackten
> Daten, das Ergebnis ändert sich dadurch aber nicht (LZO packt nur soviel
> aus wie tatsächlich da ist).

Ja, das war mir schon klar :-) Die Blockgröße ist das was ein Reader 
mindestens bereitstellen muss, damit LZO einen zusammenhängenden, 
komprimierten Datenbereich im RAM auspacken kann. Auf diesen Block 
scheint es dann jeweils eine Prüfsumme zu geben, welche am Anfang der 
komprimierten Daten steht. Also lag ich schon garnicht so falsch mit 
meiner Annahme das die Prüfsumme garnicht Bestandteil des Headers 
sondern eher Bestandteil des komprimierten Datenblocks ist. Besteht also 
eine Datei aus mehreren Blöcken, dann hätte jeder dieser Blöcke eine 
Prüfsumme vorweg. Die Größe der entpackten Daten im Header wäre dann 
aber vermutlich die der gesamten Datei und nicht des Blocks.

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Olli Z. schrieb:
>> Ob jetzt diese "basereg" (Registry?) nun irgendwas sinnvolles enthält... > >
> weiss noch nicht, werde mich mal an den anderen Dateien versuchen.
>
> Die ausgepackte Datei stimmt so, in den kleinen Dateien steht aber
> nichts direkt lesbares. Interessant wird es erst bein den größeren
> Code-Dateien.

Ich frag mich noch warum meine Version des lzopack (werde ich am besten 
mal in ulipack umbenennen ;-) das Ende der komprimierten Daten nicht 
erkennt und denkt das da noch ein Block folgen würde. Das ich ein 
korrektes Ergebnis habe liegt eher an meinem Hack. Das muss ich noch 
bereinigen. Ich frage mich aber was denn da hinter den komprimierten 
Daten noch für ein Zeug hängt?

von Olli Z. (z80freak)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Der Header der großen Dateien (hier mal "navfx001.uli" scheint komplett 
anders aufgebaut zu sein.
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  55 4C 49 20 80 92 44 A0 03 00 00 00 00 00 00 00  ULI €’D ........
00000010  00 00 00 A0 54 00 00 00 08 79 4B 00 B9 E6 35 00  ... T....yK.¹æ5.
00000020  13 69 B7 E9 02 00 00 00 08 89 4B A0 0D E7 35 00  .i·é.....‰K .ç5.
00000030  38 69 00 00 18 1B 00 00 0D 02 85 EF 04 00 00 00  8i........…ï....
00000040  40 F2 4B A0 00 00 00 00 F8 AB 02 00 00 00 00 00  @òK ....ø«......
00000050  FF FF FF FF 00 02 02 49 00 20 08 70 08 72 70 47  ÿÿÿÿ...I. .p.rpG
00000060  00 00 40 F2 4B A0 01 49 08 70 EC 01 00 FF 74 49  ..@òK .I.pì..ÿtI
...

Nach ein wenig Brute-Force habe ich folgendes herausgefunden:
- Die komprimierten Daten starten erst nach der 0xFFFF FFFF Signatur, 
also ab Offset 0x54. Die Prüfsumme (CRC32) steckt wie gewohnt in Offset 
0x20 (0xE9B76913). Extrahiere ich den Block (komprimiert 0x35E6B9 Bytes, 
entpackt 0x4B7908 Bytes) und rechne die Prüfsumme nach, passt diese. Das 
resultierende Binary (hier im ZIP zusammen mit dem Original ULI) enthält 
dann auch Code welchen man mit IDA debuggen kann (naja, sofern man ihn 
versteht ;-) sowie lesbaren Text.

Soweit so gut. Aber da fehlt hinten noch was. Es gibt also wenigstens 
noch einen weiteren gepackten Teil in dem ULI. Aufgrund der 
Größenangaben endet der erste gepackte Teil an Offset 0x35E70C:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

0035E6F0  31 39 F1 23 1C 8F 01 00 00 F0 7F 6C AB 09 00 00  19ñ#.....ð.l«...
0035E700  F8 7F 00 00 80 7F 00 00 C0 7F 11 00 00 02 00 00  ø...€...À.......
0035E710  00 00 00 C1 00 FF C0 00 D8 01 20 00 A1 18 00 78  ...Á.ÿÀ.Ø. .¡..x
0035E720  39 2A 10 07 2E 3C 00 2A 6C 00 20 AF 2C 00 EC 1D  9*...<.*l. ¯,.ì.
0035E730  BC 00 00 00 5D 01 4D 01 00 02 4D 02 00 03 4D 03  ¼...].M...M...M.
0035E740  00 04 4D 04 00 05 4D 05 00 06 4D 06 00 07 4D 07  ..M...M...M...M.

Ab 0x35E70D müsste dann der nächste Teil weiter gehen. Sicher sind hier 
auch wieder Headerinformationen enthalten, denn der Algo muss ja 
wenigstens wissen wieviele komprimierten Bytes nun folgen und wie die 
Prüfsumme des dekomprimierten Bereichs lautet. So richtig finde ich den 
nächsten Anfang aber nicht...

: Bearbeitet durch User
von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:
> So richtig finde ich den
> nächsten Anfang aber nicht...

Warum sind da wohl noch Daten vor dem 0xFFFFFFFF am Anfang der Datei, 
diese enthalten alle nötigen Informationen. Von der navfx001.uli hast Du 
aber sowieso schon fast alles, der fehlende Teil ist ausgepackt nur 
knapp 25 kByte groß.

von Olli Z. (z80freak)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Das meiste erkennt man, wenn man die Header-Daten etwas anders 
formatiert (siehe Bild).

Unklar ist mir noch was in den Bytes 4-7 drin steht, sowie dem sich 
wiederholenden Teil in jedem Header-Block der mit "????" gekennzeichnet 
ist.

Auch komisch ist bei den Dateien mit mehreren Blöcken das dort beim 
letzten Teil eigentlich keine wirklich sinnvollen Infos drin zu stehen 
scheinen (Sizes mit 0 und startpos mit 0, sowie Checksum mit FF)

: Bearbeitet durch User
von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Der Packer schreibt imho am Schluss einen leeren Block folglich ergibt 
sich das crc auf ff.
Der Entpacker erkennt daran den letzen Block des files und somit die 
zahl der Blöcke und das im Anschluss die komprimierten Daten beginnen.

Namaste

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Winfried J. schrieb:
> Der Packer schreibt imho am Schluss einen leeren Block folglich ergibt
> sich das crc auf ff.
> Der Entpacker erkennt daran den letzen Block des files und somit die
> zahl der Blöcke und das im Anschluss die komprimierten Daten beginnen.

Dann müsste er das ja beim Single-Block File genauso machen. Das klingt 
irgendwie nicht schlüssig für mich.

Interessant ist, das alle Dateien den gleichen Footer/Trailer zu haben 
scheinen. Dieser gehört definitiv nicht zum LZO-Teil und ist 0x4B Bytes 
(evtl. auch nur 0x48 Bytes) groß. Es ändern sich, bis auf bootload.bin, 
navreg.uli und navfx001.uli, nur die letzten 8 Bytes. Hierin sind 
definitiv zwei Informationen enthalten:
Der vorletzte 4-Byte Wert enthält die Gesamt-Dateilänge
Der letzte 4-Byte Wert enthält die CRC32 Prüfsumme der gesamten Datei, 
exlusive der Prüfsumme selbst (versteht sich von selbst ;-)

(In den nachfolgenden Anzeigen habe ich die Blöcke immer an Offset 
0x0000 kopiert damit es besser lesbar und vergleichbar ist)

main_ver.bin:
00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020  03 00 00 00 04 00 00 00 02 00 00 00 3C 00 00 00  ............<...
00000030  00 00 00 00 10 0A 08 0B 00 00 01 00 CE DE AD CE  ............ÎÞ.Î
00000040  31 21 52 31 5C 00 00 00 4E 40 53 92              1!R1\...N@S’

basereg.uli:
00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020  03 00 00 00 04 00 00 00 02 00 00 00 3C 00 00 00  ............<...
00000030  00 00 00 00 10 0A 08 0B 00 00 01 00 CE DE AD CE  ............ÎÞ.Î
00000040  31 21 52 31 B4 03 00 00 61 1C 56 EC              1!R1´...a.Vì

bootload.bin:
00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020  03 00 00 00 00 00 00 00 02 00 00 00 28 00 00 00  ............(...
00000030  00 00 00 00 0D 06 09 07 00 00 01 00 CE DE AD CE  ............ÎÞ.Î
00000040  31 21 52 31 9C 19 00 00 1F FC 06 E7              1!R1œ....ü.ç

fgs.dnl:
00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020  03 00 00 00 04 00 00 00 02 00 00 00 3C 00 00 00  ............<...
00000030  00 00 00 00 10 0A 08 0B 00 00 01 00 CE DE AD CE  ............ÎÞ.Î
00000040  31 21 52 31 94 D1 52 00 25 FE 51 7C              1!R1”ÑR.%þQ|

plattapp.uli:
00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020  03 00 00 00 04 00 00 00 02 00 00 00 3C 00 00 00  ............<...
00000030  00 00 00 00 10 0A 08 0B 00 00 01 00 CE DE AD CE  ............ÎÞ.Î
00000040  31 21 52 31 1C 28 39 00 32 4D 8D BE              1!R1.(9.2M.¾

plattreg.uli:
00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020  03 00 00 00 04 00 00 00 02 00 00 00 3C 00 00 00  ............<...
00000030  00 00 00 00 10 0A 08 0B 00 00 01 00 CE DE AD CE  ............ÎÞ.Î
00000040  31 21 52 31 E4 0D 00 00 50 99 AE 30              1!R1ä...P™®0

radio.dnl:
00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020  03 00 00 00 04 00 00 00 02 00 00 00 3C 00 00 00  ............<...
00000030  00 00 00 00 10 0A 08 0B 00 00 01 00 CE DE AD CE  ............ÎÞ.Î
00000040  31 21 52 31 D4 5E 0A 00 2A D6 CF 3C              1!R1Ô^..*ÖÏ<

system.elf:
00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020  03 00 00 00 04 00 00 00 02 00 00 00 3C 00 00 00  ............<...
00000030  00 00 00 00 10 0A 08 0B 00 00 01 00 CE DE AD CE  ............ÎÞ.Î
00000040  31 21 52 31 54 B2 3A 00 25 E1 99 D9              1!R1T²:.%á™Ù

navfx001.uli:
00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010  00 00 00 00 14 00 00 00 29 00 00 00 3C 00 00 00  ........)...<...
00000020  50 00 00 00 04 00 00 00 04 00 00 00 01 01 01 05  P...............
00000030  10 1B 09 0A 00 00 01 00 CE DE AD CE 31 21 52 31  ........ÎÞ.Î1!R1
00000040  7C 02 36 00 0D 3D A0 4F                          |.6..= O

navreg.uli:
00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000020  02 00 00 00 01 00 00 00 02 00 00 00 01 01 01 04  ................
00000030  12 1B 09 0A 00 00 01 00 CE DE AD CE 31 21 52 31  ........ÎÞ.Î1!R1
00000040  C8 26 00 00 10 2F 8C 58                          È&.../ŒX

Das "CE DE AD CE" ist wohl eine Signatur. Ich vermute das der Updater im 
Radio diese Daten benötigt um die Datei als gültige Updatedatei zu 
erkennen. Darüber lässt sich sicher eine Routine im Code (flashdump oder 
system.elf) finden die das behandelt!

Auch sollte man doch irgendwo eine CRC32 Funktion im Disassembler-Code 
finden können, so häufig wie davon Gebrauch gemacht wird. Auf jeden Fall 
finde ich schonmal die Entropy-Tabelle wie man sie im Quellcode von 
LZOP, aber auch frei im Internet findet (z.B.: 
http://web.mit.edu/freebsd/head/sys/libkern/crc32.c)

: Bearbeitet durch User
von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Darüber lässt sich sicher eine Routine im Code (flashdump oder
> system.elf) finden die das behandelt!

Warum einfach wenn es auch kompliziert geht? Man könnte z.B. nach "ULI " 
(mit dem Leerzeichen) in der "system.elf" suchen. Ganz nebenbei steht 
dann auch noch "LZO" in der Nähe...

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Warum einfach wenn es auch kompliziert geht? Man könnte z.B. nach "ULI "
> (mit dem Leerzeichen) in der "system.elf" suchen. Ganz nebenbei steht
> dann auch noch "LZO" in der Nähe...

Ja, darüber bin ich ja zum LZO gekommen ;-) Das wird/sollte alles 
irgendwie zusammenhängen. Über die Handler müsste man dann auch zum 
Aufruf gelangen. Aktuell weiss ich nur noch nicht wo und wie ich da 
ansetzen soll, dafür kenne ich IDA noch zuwenig.

von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Noch ein Tipp zu den "XXXreg.uli" Dateien: Ausgepackt sind die ja nicht 
direkt lesbar. Wenn man genau hinschaut erkennt man dass man das mit 
einem XOR beheben kann (trivial mit einem konstanten Byte).

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Noch ein Tipp zu den "XXXreg.uli" Dateien: Ausgepackt sind die ja nicht
> direkt lesbar

Vielen Dank! Irgendwie finde ich das richtig klasse mit Deinen 
Hinweisen, das ist fast wie ein Krimirätsel :-)

Momentan arbeite ich daran mir aus dem lzopack.c einen ulipack.c zu 
bauen, mit all den Erkenntnissen von oben. Da werde ich dann eine Option 
für die reg-Dateien mit integrieren.
Zuerstmal musste ich merken das die block_size beim uncompress-alog 
nicht beliebig sein kann, sprich bei großen Datenmengen muss man hier in 
kleineren Schritten vorgehen, sonst erhält man nen 
LZO_E_INPUT_NOT_CONSUMED, was laut API der Fall ist "if 'src_len' is too 
large". Naja, Lehrgeld halt...

> Wenn man genau hinschaut erkennt man dass man das mit
> einem XOR beheben kann (trivial mit einem konstanten Byte).
Wie kommt man denn darauf? Ich kann noch so lange drauf gucken, ich sehe 
nur Bytes. Woran "siehst" Du nur das da mit XOR gearbeitet wurde?

: Bearbeitet durch User
von Dieter (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Wie kommt man denn darauf? Ich kann noch so lange drauf gucken, ich sehe
> nur Bytes. Woran "siehst" Du nur das da mit XOR gearbeitet wurde?

Man sieht dass es nicht komplett zufällig ist (z.B. an den 
Wiederholungen),
außerdem ist Bit 8 in fast allen Bytes gesetzt (abgesehen vom dem 
letzten Byte). Das könnte also ASCII Text sein, nur halt mit XOR, damit 
man es nicht sofort erkennt. Und ein konstantes Bytes als XOR wegen der 
Wiederholungen.

Eine "akademische" Lösung wäre z.B. die Entropie ansehen oder die 
Häufigkeit der Byte-Werte berechnen, aber in diesem Fall ist es so 
einfach dass man mit ausprobieren schneller ans Ziel kommt.

von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Noch etwas wofür man keinen Disassembler braucht: Man kann etwas 
Struktur in die Daten aus dem Flash bringen (der Hexdump hier ganz am 
Anfang) wenn man genau hinsieht. Es gibt einen Header, dann kommen die 
Datensätze, die jeweils aus CRC, ID, Länge und den eigentlichen Daten 
bestehen. Etwas erschwert wird das Ganze durch ein Alignment der Daten, 
dafür werden Füllbytes verwendet. Der Header hat ebenfalls eine CRC, 
außerdem gibt es eine spezielle ID für gelöschte Datensätze.

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Noch ein Tipp zu den "XXXreg.uli" Dateien: Ausgepackt sind die ja nicht
> direkt lesbar. Wenn man genau hinschaut erkennt man dass man das mit
> einem XOR beheben kann (trivial mit einem konstanten Byte).

Ich denke das Cipher für die in "basereg.uli" enthaltenen Daten lautet 
0xFE.

Hab mir die Daten, wie Du gesagt hast nochmal auf mich wirken lassen. 
Zunächst mal sehe ich das dort nur hohe Werte enthalten sind und damit 
der Cipher wenigstens 0x80 (0b1000 0000) sein muss um gültige 
ASCII-Zeichen zu produzieren.

Dann habe ich mir in C schnell ein Tool geschrieben welches die ersten 
80 Zeichen (einfach nur um genug für eine Aussage zu haben) einer Datei 
einliest und dann über alle möglichen XOR-Werte (1 Byte) iteriert 
ausgibt. Dabei ersetze ich nicht ASCII-Zeichen durch "." damit es kein 
Wirrwarr im output gibt.

Das Ergebnis betrachte ich dann einfach und suche nach etwas "lesbarem":
PS C:\temp\crack_xor.exe basereg.bin
using cipher 0x80: ,;9;:7*Jt%65;'!21=?2!3?=670;#t%65;'!21=?2!3?=670;"-18*)?,;#t%65;'!21=?2!3?=670;"
using cipher 0x81: -:8:;6+Ku$74:& 30<>3 2><761:"u$74:& 30<>3 2><761:#,09+(>-:"u$74:& 30<>3 2><761:#
using cipher 0x82: .9;985(Hv'479%#03?=0#1=?4529!v'479%#03?=0#1=?4529 /3:(+=.9!v'479%#03?=0#1=?4529
using cipher 0x83: /8:894)Iw&568$"12><1"0<>5438 w&568$"12><1"0<>5438!.2;)*</8 w&568$"12><1"0<>5438!
using cipher 0x84: (?=?>3.Np!21?#%659;6%7;9234?'p!21?#%659;6%7;9234?&)5<.-;(?'p!21?#%659;6%7;9234?&
using cipher 0x85: )><>?2/Oq 30>"$748:7$6:8325>&q 30>"$748:7$6:8325>'(4=/,:)>&q 30>"$748:7$6:8325>'
using cipher 0x86: *=?=<1,Lr#03=!'47;94'59;016=%r#03=!'47;94'59;016=$+7>,/9*=%r#03=!'47;94'59;016=$
using cipher 0x87: +<><=0-Ms"12< &56:85&48:107<$s"12< &56:85&48:107<%*6?-.8+<$s"12< &56:85&48:107<%
using cipher 0x88: $3132?"B|->=3/):957:);75>?83+|->=3/):957:);75>?83*%90"!7$3+|->=3/):957:);75>?83*
using cipher 0x89: %2023>#C},?<2.(;846;(:64?>92*},?<2.(;846;(:64?>92+$81# 6%2*},?<2.(;846;(:64?>92+
using cipher 0x8A: &1310= @~/<?1-+8;758+957<=:1)~/<?1-+8;758+957<=:1(';2 #5&1)~/<?1-+8;758+957<=:1(
using cipher 0x8B: '0201<!A.=>0,*9:649*846=<;0(.=>0,*9:649*846=<;0)&:3!"4'0(.=>0,*9:649*846=<;0)
using cipher 0x8C:  7576;&Fx):97+->=13>-?31:;<7/x):97+->=13>-?31:;<7.!=4&%3 7/x):97+->=13>-?31:;<7.
using cipher 0x8D: !6467:'Gy(;86*,?<02?,>20;:=6.y(;86*,?<02?,>20;:=6/ <5'$2!6.y(;86*,?<02?,>20;:=6/
using cipher 0x8E: "57549$Dz+8;5)/<?31</=1389>5-z+8;5)/<?31</=1389>5,#?6$'1"5-z+8;5)/<?31</=1389>5,
using cipher 0x8F: #46458%E{*9:4(.=>20=.<0298?4,{*9:4(.=>20=.<0298?4-">7%&0#4,{*9:4(.=>20=.<0298?4-
using cipher 0x90: <+)+*':Zd5&%+71"!-/"1#/-&' +3d5&%+71"!-/"1#/-&' +2=!(:9/<+3d5&%+71"!-/"1#/-&' +2
using cipher 0x91: =*(*+&;[e4'$*60# ,.#0".,'&!*2e4'$*60# ,.#0".,'&!*3< );8.=*2e4'$*60# ,.#0".,'&!*3
using cipher 0x92: >)+)(%8Xf7$')53 #/- 3!-/$%")1f7$')53 #/- 3!-/$%")0?#*8;->)1f7$')53 #/- 3!-/$%")0
using cipher 0x93: ?(*()$9Yg6%&(42!".,!2 ,.%$#(0g6%&(42!".,!2 ,.%$#(1>"+9:,?(0g6%&(42!".,!2 ,.%$#(1
using cipher 0x94: 8/-/.#>^`1"!/35&%)+&5'+)"#$/7`1"!/35&%)+&5'+)"#$/69%,>=+8/7`1"!/35&%)+&5'+)"#$/6
using cipher 0x95: 9.,./"?_a0# .24'$(*'4&*(#"%.6a0# .24'$(*'4&*(#"%.78$-?<*9.6a0# .24'$(*'4&*(#"%.7
using cipher 0x96: :-/-,!<\b3 #-17$'+)$7%)+ !&-5b3 #-17$'+)$7%)+ !&-4;'.<?):-5b3 #-17$'+)$7%)+ !&-4
using cipher 0x97: ;,.,- =]c2!",06%&*(%6$(*! ',4c2!",06%&*(%6$(*! ',5:&/=>(;,4c2!",06%&*(%6$(*! ',5
using cipher 0x98: 4#!#"/2Rl=.-#?9*)%'*9+'%./(#;l=.-#?9*)%'*9+'%./(#:5) 21'4#;l=.-#?9*)%'*9+'%./(#:
using cipher 0x99: 5" "#.3Sm</,">8+($&+8*&$/.)":m</,">8+($&+8*&$/.)";4(!30&5":m</,">8+($&+8*&$/.)";
using cipher 0x9A: 6!#! -0Pn?,/!=;(+'%(;)%',-*!9n?,/!=;(+'%(;)%',-*!87+"03%6!9n?,/!=;(+'%(;)%',-*!8
using cipher 0x9B: 7 " !,1Qo>-. <:)*&$):($&-,+ 8o>-. <:)*&$):($&-,+ 96*#12$7 8o>-. <:)*&$):($&-,+ 9
using cipher 0x9C: 0'%'&+6Vh9*)';=.-!#.=/#!*+,'?h9*)';=.-!#.=/#!*+,'>1-$65#0'?h9*)';=.-!#.=/#!*+,'>
using cipher 0x9D: 1&$&'*7Wi8+(&:</, "/<." +*-&>i8+(&:</, "/<." +*-&?0,%74"1&>i8+(&:</, "/<." +*-&?
using cipher 0x9E: 2%'%$)4Tj;(+%9?,/#!,?-!#().%=j;(+%9?,/#!,?-!#().%<3/&47!2%=j;(+%9?,/#!,?-!#().%<
using cipher 0x9F: 3$&$%(5Uk:)*$8>-." ->, ")(/$<k:)*$8>-." ->, ")(/$=2.'56 3$<k:)*$8>-." ->, ")(/$=
using cipher 0xA0: .......jT....................T.............................T....................
using cipher 0xA1: .......kU....................U.............................U....................
using cipher 0xA2: .......hV....................V.............................V....................
using cipher 0xA3: .......iW....................W.............................W....................
using cipher 0xA4: .......nP....................P.............................P....................
using cipher 0xA5: .......oQ....................Q.............................Q....................
using cipher 0xA6: .......lR....................R.............................R....................
using cipher 0xA7: .......mS....................S.............................S....................
using cipher 0xA8: .......b\....................\.............................\....................
using cipher 0xA9: .......c]....................].............................]....................
using cipher 0xAA: .......`^....................^.............................^....................
using cipher 0xAB: .......a_...................._............................._....................
using cipher 0xAC: .......fX....................X.............................X....................
using cipher 0xAD: .......gY....................Y.............................Y....................
using cipher 0xAE: .......dZ....................Z.............................Z....................
using cipher 0xAF: .......e[....................[.............................[....................
using cipher 0xB0: .......zD....................D.............................D....................
using cipher 0xB1: .......{E....................E.............................E....................
using cipher 0xB2: .......xF....................F.............................F....................
using cipher 0xB3: .......yG....................G.............................G....................
using cipher 0xB4: .......~@....................@.............................@....................
using cipher 0xB5: .......A....................A.............................A....................
using cipher 0xB6: .......|B....................B.............................B....................
using cipher 0xB7: .......}C....................C.............................C....................
using cipher 0xB8: .......rL....................L.............................L....................
using cipher 0xB9: .......sM....................M.............................M....................
using cipher 0xBA: .......pN....................N.............................N....................
using cipher 0xBB: .......qO....................O.............................O....................
using cipher 0xBC: .......vH....................H.............................H....................
using cipher 0xBD: .......wI....................I.............................I....................
using cipher 0xBE: .......tJ....................J.............................J....................
using cipher 0xBF: .......uK....................K.............................K....................
using cipher 0xC0: l{y{zwj.4evu{garq}ras}vwp{c4evu{garq}ras}vwp{bmqxjil{c4evu{garq}ras}vwp{b
using cipher 0xC1: mzxz{vk.5dwtzf`sp|~s`r~|wvqzb5dwtzf`sp|~s`r~|wvqzclpykh~mzb5dwtzf`sp|~s`r~|wvqzc
using cipher 0xC2: ny{yxuh.6gtwyecps}pcq}turya6gtwyecps}pcq}tury`oszhk}nya6gtwyecps}pcq}tury`
using cipher 0xC3: oxzxyti.7fuvxdbqr~|qbp|~utsx`7fuvxdbqr~|qbp|~utsxanr{ij|ox`7fuvxdbqr~|qbp|~utsxa
using cipher 0xC4: h}~sn.0arqcevuy{vew{yrstg0arqcevuy{vew{yrstfiu|nm{hg0arqcevuy{vew{yrstf
using cipher 0xC5: i~|~ro.1`sp~bdwtxzwdvzxsru~f1`sp~bdwtxzwdvzxsru~ght}olzi~f1`sp~bdwtxzwdvzxsru~g
using cipher 0xC6: j}}|ql.2cps}agtw{ytguy{pqv}e2cps}agtw{ytguy{pqv}dkw~loyj}e2cps}agtw{ytguy{pqv}d
using cipher 0xC7: k|~|}pm.3bqr|`fuvzxuftxzqpw|d3bqr|`fuvzxuftxzqpw|ejvmnxk|d3bqr|`fuvzxuftxzqpw|e
using cipher 0xC8: dsqsrb.<m~}soizyuwzi{wu~xsk<m~}soizyuwzi{wu~xsjeypbawdsk<m~}soizyuwzi{wu~xsj
using cipher 0xC9: erprs~c.=l|rnh{xtv{hzvt~yrj=l|rnh{xtv{hzvt~yrkdxqc`verj=l|rnh{xtv{hzvt~yrk
using cipher 0xCA: fqsqp}`.>o|qmkx{wuxkyuw|}zqi>o|qmkx{wuxkyuw|}zqhg{r`cufqi>o|qmkx{wuxkyuw|}zqh
using cipher 0xCB: gprpq|a.?n}~pljyzvtyjxtv}|{ph?n}~pljyzvtyjxtv}|{pifzsabtgph?n}~pljyzvtyjxtv}|{pi
using cipher 0xCC: `wuwv{f.8izywkm~}qs~msqz{|wo8izywkm~}qs~msqz{|wna}tfes`wo8izywkm~}qs~msqz{|wn
using cipher 0xCD: avtvwzg.9h{xvjl|prl~rp{z}vn9h{xvjl|prl~rp{z}vo`|ugdravn9h{xvjl|prl~rp{z}vo
using cipher 0xCE: buwutyd.:kx{uio|sq|o}qsxy~um:kx{uio|sq|o}qsxy~ulcvdgqbum:kx{uio|sq|o}qsxy~ul
using cipher 0xCF: ctvtuxe.;jyzthn}~rp}n|pryxtl;jyzthn}~rp}n|pryxtmb~wefpctl;jyzthn}~rp}n|pryxtm
using cipher 0xD0: |kikjgz.$ufekwqbamobqcomfg`ks$ufekwqbamobqcomfg`kr}ahzyo|ks$ufekwqbamobqcomfg`kr
using cipher 0xD1: }jhjkf{.%tgdjvpc`lncpbnlgfajr%tgdjvpc`lncpbnlgfajs|`i{xn}jr%tgdjvpc`lncpbnlgfajs
using cipher 0xD2: ~ikihex.&wdgius`com`samodebiq&wdgius`com`samodebipcjx{m~iq&wdgius`com`samodebip
using cipher 0xD3: hjhidy.'vefhtrabnlar`lnedchp'vefhtrabnlar`lnedchq~bkyzlhp'vefhtrabnlar`lnedchq
using cipher 0xD4: xomonc~. qbaosufeikfugkibcdow qbaosufeikfugkibcdovyel~}kxow qbaosufeikfugkibcdov
using cipher 0xD5: ynlnob.!pc`nrtgdhjgtfjhcbenv!pc`nrtgdhjgtfjhcbenwxdm|jynv!pc`nrtgdhjgtfjhcbenw
using cipher 0xD6: zmomla|."s`cmqwdgkidweik`afmu"s`cmqwdgkidweik`afmt{gn|izmu"s`cmqwdgkidweik`afmt
using cipher 0xD7: {lnlm`}.#rablpvefjhevdhja`glt#rablpvefjhevdhja`gluzfo}~h{lt#rablpvefjhevdhja`glu
using cipher 0xD8: tcacbor.,}nmcyjiegjykgenohc{,}nmcyjiegjykgenohczui`rqgtc{,}nmcyjiegjykgenohcz
using cipher 0xD9: ub`bcns.-|olb~xkhdfkxjfdonibz-|olb~xkhdfkxjfdonib{thaspfubz-|olb~xkhdfkxjfdonib{
using cipher 0xDA: vaca`mp..loa}{hkgeh{ieglmjay.loa}{hkgeh{ieglmjaxwkbpsevay.loa}{hkgeh{ieglmjax
using cipher 0xDB: w`b`alq./~mn`|zijfdizhdfmlk`x/~mn`|zijfdizhdfmlk`yvjcqrdw`x/~mn`|zijfdizhdfmlk`y
using cipher 0xDC: pgegfkv.(yjig{}nmacn}ocajklg(yjig{}nmacn}ocajklg~qmdvucpg(yjig{}nmacn}ocajklg~
using cipher 0xDD: qfdfgjw.)xkhfz|ol`bo|nb`kjmf~)xkhfz|ol`bo|nb`kjmfplewtbqf~)xkhfz|ol`bo|nb`kjmf
using cipher 0xDE: regedit.*{hkeylocalmachine}*{hkeylocalmachine|software}*{hkeylocalmachine|
using cipher 0xDF: sdfdehu.+zijdx~mnb`m~l`bihod|+zijdx~mnb`m~l`bihod}rnguv`sd|+zijdx~mnb`m~l`bihod}
using cipher 0xE0: L[Y[ZWJ*.EVU[GARQ]_RAS_]VWP[C.EVU[GARQ]_RAS_]VWP[BMQXJI_L[C.EVU[GARQ]_RAS_]VWP[B
using cipher 0xE1: MZXZ[VK+.DWTZF@SP\^S@R^\WVQZB.DWTZF@SP\^S@R^\WVQZCLPYKH^MZB.DWTZF@SP\^S@R^\WVQZC
using cipher 0xE2: NY[YXUH(.GTWYECPS_]PCQ]_TURYA.GTWYECPS_]PCQ]_TURY@OSZHK]NYA.GTWYECPS_]PCQ]_TURY@
using cipher 0xE3: OXZXYTI).FUVXDBQR^\QBP\^UTSX@.FUVXDBQR^\QBP\^UTSXANR[IJ\OX@.FUVXDBQR^\QBP\^UTSXA
using cipher 0xE4: H_]_^SN..ARQ_CEVUY[VEW[YRST_G.ARQ_CEVUY[VEW[YRST_FIU\NM[H_G.ARQ_CEVUY[VEW[YRST_F
using cipher 0xE5: I^\^_RO/.@SP^BDWTXZWDVZXSRU^F.@SP^BDWTXZWDVZXSRU^GHT]OLZI^F.@SP^BDWTXZWDVZXSRU^G
using cipher 0xE6: J]_]\QL,.CPS]AGTW[YTGUY[PQV]E.CPS]AGTW[YTGUY[PQV]DKW^LOYJ]E.CPS]AGTW[YTGUY[PQV]D
using cipher 0xE7: K\^\]PM-.BQR\@FUVZXUFTXZQPW\D.BQR\@FUVZXUFTXZQPW\EJV_MNXK\D.BQR\@FUVZXUFTXZQPW\E
using cipher 0xE8: DSQSR_B".M^]SOIZYUWZI[WU^_XSK.M^]SOIZYUWZI[WU^_XSJEYPBAWDSK.M^]SOIZYUWZI[WU^_XSJ
using cipher 0xE9: ERPRS^C#.L_\RNH[XTV[HZVT_^YRJ.L_\RNH[XTV[HZVT_^YRKDXQC@VERJ.L_\RNH[XTV[HZVT_^YRK
using cipher 0xEA: FQSQP]@ .O\_QMKX[WUXKYUW\]ZQI.O\_QMKX[WUXKYUW\]ZQHG[R@CUFQI.O\_QMKX[WUXKYUW\]ZQH
using cipher 0xEB: GPRPQ\A!.N]^PLJYZVTYJXTV]\[PH.N]^PLJYZVTYJXTV]\[PIFZSABTGPH.N]^PLJYZVTYJXTV]\[PI
using cipher 0xEC: @WUWV[F&.IZYWKM^]QS^M_SQZ[\WO.IZYWKM^]QS^M_SQZ[\WNA]TFES@WO.IZYWKM^]QS^M_SQZ[\WN
using cipher 0xED: AVTVWZG'.H[XVJL_\PR_L^RP[Z]VN.H[XVJL_\PR_L^RP[Z]VO@\UGDRAVN.H[XVJL_\PR_L^RP[Z]VO
using cipher 0xEE: BUWUTYD$.KX[UIO\_SQ\O]QSXY^UM.KX[UIO\_SQ\O]QSXY^ULC_VDGQBUM.KX[UIO\_SQ\O]QSXY^UL
using cipher 0xEF: CTVTUXE%.JYZTHN]^RP]N\PRYX_TL.JYZTHN]^RP]N\PRYX_TMB^WEFPCTL.JYZTHN]^RP]N\PRYX_TM
using cipher 0xF0: \KIKJGZ:.UFEKWQBAMOBQCOMFG@KS.UFEKWQBAMOBQCOMFG@KR]AHZYO\KS.UFEKWQBAMOBQCOMFG@KR
using cipher 0xF1: ]JHJKF[;.TGDJVPC@LNCPBNLGFAJR.TGDJVPC@LNCPBNLGFAJS\@I[XN]JR.TGDJVPC@LNCPBNLGFAJS
using cipher 0xF2: ^IKIHEX8.WDGIUS@COM@SAMODEBIQ.WDGIUS@COM@SAMODEBIP_CJX[M^IQ.WDGIUS@COM@SAMODEBIP
using cipher 0xF3: _HJHIDY9.VEFHTRABNLAR@LNEDCHP.VEFHTRABNLAR@LNEDCHQ^BKYZL_HP.VEFHTRABNLAR@LNEDCHQ
using cipher 0xF4: XOMONC^>.QBAOSUFEIKFUGKIBCDOW.QBAOSUFEIKFUGKIBCDOVYEL^]KXOW.QBAOSUFEIKFUGKIBCDOV
using cipher 0xF5: YNLNOB_?.PC@NRTGDHJGTFJHCBENV.PC@NRTGDHJGTFJHCBENWXDM_\JYNV.PC@NRTGDHJGTFJHCBENW
using cipher 0xF6: ZMOMLA\<.S@CMQWDGKIDWEIK@AFMU.S@CMQWDGKIDWEIK@AFMT[GN\_IZMU.S@CMQWDGKIDWEIK@AFMT
using cipher 0xF7: [LNLM@]=.RABLPVEFJHEVDHJA@GLT.RABLPVEFJHEVDHJA@GLUZFO]^H[LT.RABLPVEFJHEVDHJA@GLU
using cipher 0xF8: TCACBOR2.]NMC_YJIEGJYKGENOHC[.]NMC_YJIEGJYKGENOHCZUI@RQGTC[.]NMC_YJIEGJYKGENOHCZ
using cipher 0xF9: UB@BCNS3.\OLB^XKHDFKXJFDONIBZ.\OLB^XKHDFKXJFDONIB[THASPFUBZ.\OLB^XKHDFKXJFDONIB[
using cipher 0xFA: VACA@MP0._LOA][HKGEH[IEGLMJAY._LOA][HKGEH[IEGLMJAXWKBPSEVAY._LOA][HKGEH[IEGLMJAX
using cipher 0xFB: W@B@ALQ1.^MN@\ZIJFDIZHDFMLK@X.^MN@\ZIJFDIZHDFMLK@YVJCQRDW@X.^MN@\ZIJFDIZHDFMLK@Y
using cipher 0xFC: PGEGFKV6.YJIG[]NMACN]OCAJKLG_.YJIG[]NMACN]OCAJKLG^QMDVUCPG_.YJIG[]NMACN]OCAJKLG^
using cipher 0xFD: QFDFGJW7.XKHFZ\OL@BO\NB@KJMF^.XKHFZ\OL@BO\NB@KJMF_PLEWTBQF^.XKHFZ\OL@BO\NB@KJMF_
using cipher 0xFE: REGEDIT4.[HKEY_LOCAL_MACHINE].[HKEY_LOCAL_MACHINE\SOFTWARE].[HKEY_LOCAL_MACHINE\
using cipher 0xFF: SDFDEHU5.ZIJDX^MNB@M^L@BIHOD\.ZIJDX^MNB@M^L@BIHOD]RNGUV@SD\.ZIJDX^MNB@M^L@BIHOD]

Die einzig sinnvollen Zeilen sind dann nur diese:
using cipher 0xDE: regedit.*{hkeylocalmachine}*{hkeylocalmachine|software}*{hkeylocalmachine|
using cipher 0xFE: REGEDIT4.[HKEY_LOCAL_MACHINE].[HKEY_LOCAL_MACHINE\SOFTWARE].[HKEY_LOCAL_MACHINE\
wobei ganz klar die letztere die gesuchte sein dürfte :-)
Wow, wer hätte gedacht das die Bosch-Bubens wirklich nen Windows Regedit 
für ihre Softwarekonfiguration nutzen...

Automatisiert könnte ich das XOR cipher nur dann finden wenn ich die 
resultierenden Zeichen auf den ASCII-Zeichensatz pro Cipher 
quantifizieren würde. Aber den Aufwand habe ich mir jetzt nicht gemacht 
;-)

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Die "entschlüsselte" Registry-Datei (hier im Beispiel aus "basereg.uli") 
entspricht weitestgehend dem was man von einem REGEDIT.EXE Export eines 
Hive unter Windows erkennt, ausser das ein Zeilenende nur mit LF (0x0A) 
markiert ist.
Zudem ist am Ende der Datei noch ein 2-Byte Wert welcher nicht 
standardmäßig zu einer Registrydatei gehört. Der ist auch bei 
verschiedenen Registry-Dateien gleich, also eher keine Prüfsumme sondern 
vielleicht nur eine Signatur?!
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  52 45 47 45 44 49 54 34 0A 5B 48 4B 45 59 5F 4C  REGEDIT4.[HKEY_L
00000010  4F 43 41 4C 5F 4D 41 43 48 49 4E 45 5D 0A 5B 48  OCAL_MACHINE].[H
00000020  4B 45 59 5F 4C 4F 43 41 4C 5F 4D 41 43 48 49 4E  KEY_LOCAL_MACHIN
00000030  45 5C 53 4F 46 54 57 41 52 45 5D 0A 5B 48 4B 45  E\SOFTWARE].[HKE
00000040  59 5F 4C 4F 43 41 4C 5F 4D 41 43 48 49 4E 45 5C  Y_LOCAL_MACHINE\
00000050  53 4F 46 54 57 41 52 45 5C 42 4C 41 55 50 55 4E  SOFTWARE\BLAUPUN
...
00000A80  4F 46 54 57 41 52 45 5C 42 4C 41 55 50 55 4E 4B  OFTWARE\BLAUPUNK
00000A90  54 5C 50 52 4F 43 45 53 53 5C 44 45 56 5C 4F 44  T\PROCESS\DEV\OD
00000AA0  4F 5D 0A 22 41 50 50 49 44 22 3D 64 77 6F 72 64  O]."APPID"=dword
00000AB0  3A 30 30 30 30 30 30 30 32 0A FF 01              :00000002.ÿ.

: Bearbeitet durch User
von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Noch etwas wofür man keinen Disassembler braucht: Man kann etwas
> Struktur in die Daten aus dem Flash bringen (der Hexdump hier ganz am
> Anfang) wenn man genau hinsieht. Es gibt einen Header, dann kommen die
> Datensätze, die jeweils aus CRC, ID, Länge und den eigentlichen Daten

Schau ich mal rein. Strukturen dieser Art habe ich schon gesehen 
(teilweise mit dem Keyword "INODE" versehen). Was genau könnte denn ein 
solchen "Datensatz" enthalten?
Mir scheint als verfüge das vermutlich zugrunde liegende RTOS 
Betriebssystem über ein Filesystem. Man erkennt ja auch sowas wie 
errorlogs. Daran wäre ich natürlich besonders interessiert weil sie 
evtl. Aufschluß über Hardwareprobleme geben.

Spannend finde ich auch diesen Code in der system.elf:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000320  2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A  ****************
00000330  2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A  ****************
00000340  2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 00 00 00 00  ************....
00000350  2A 2A 20 20 20 20 20 20 20 53 74 61 72 74 20 46  **       Start F
00000360  4F 52 44 20 48 53 52 4E 53 20 53 79 73 74 65 6D  ORD HSRNS System
00000370  20 20 20 20 20 20 20 20 20 20 2A 2A 00 00 00 00            **....

: Bearbeitet durch User
von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Was genau könnte denn ein
> solchen "Datensatz" enthalten?

Welchen Datensatz meinst Du? Die Datensätze in dem Hexdump sind alle 
möglichen Dinge wie Geräte-Seriennummer, das sieht man ja. Ich vermute 
dass das ursprünglich für einen EEPROM gedacht war (dafür spricht das 
Alignment, das könnte für EEPROM Pages gedacht sein).

Dass es im Flash auch noch ein Filesystem gibt hatte ich ja schon 
erwähnt. Dieses Filesystem hat aber nichts mit den Datensätzen in dem 
Hexdump zu tun. Es ist auch nicht so schwierig herauszufinden was das 
für ein Filesystem ist, allerdings ist es ein "Exot" und man findet nur 
ein wenig zu einer älteren Version, die nicht kompatibel ist (aber 
genügend Hinweise über die Internas enthält).

von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Spannend finde ich auch diesen Code in der system.elf:

Das ist eine von vielen möglichen Ausgaben des Loggings über die 
seriellen Schnittstelle, zumindest wen das Logging aktiviert ist.

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Das ist jetzt schon etwas weiter weg vom Topic, aber irgendwie dann doch 
dazugehörig:
Es gibt in der Firmware eine Funktion die bei erkennen des 
Rückwärtsganges (CAN-ID 433, Data 00 00 00 02 00 A0 00 00) den 
Bildschirm auf Video-In umschaltet um das Signal der Rückfahrkamera 
anzuzeigen. Wie könnte man herausbekommen ob es für diese Funktion noch 
eine Alternative gibt? Einer meiner vielen, verwegenen Pläne ist es 
nämlich über diesen Eingang eine Front-Kamera anzuschließen. Das Bild 
müsste aber beim aktivieren des PDC und eben ohne eingelegten 
Rückwärtsgang zu sehen sein...

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Olli Z. schrieb:
>> Spannend finde ich auch diesen Code in der system.elf:
>
> Das ist eine von vielen möglichen Ausgaben des Loggings über die
> seriellen Schnittstelle, zumindest wen das Logging aktiviert ist.

Genau, das wäre eine tolle Sache wenn man wüsste wie man das aktiviert. 
An den Service-Ports des Gerätes befinden sich zwei serielle 
Schnittstellen.

von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Olli Z. schrieb:
> Wie könnte man herausbekommen ob es für diese Funktion noch
> eine Alternative gibt?

Denkbar wäre vielleicht dass es die Möglichkeit gibt diese Funktion per 
UDS auszulösen um das z.B. in der Werkstatt oder bei der Produktion zu 
testen.

Ansonsten wird es schwierig wenn das nicht schon in der Software 
vorgesehen ist. "Schwierig" in dem Sinn dass man eine neue 
Funktionalität in das Binary einbauen muss, Du willst ja vermutlich 
nicht dauerhaft das Kamerabild sehen, also muss man das auch irgendwie 
ein-/ausschalten können.

Ohne Änderung am Code könnte man "Man-in-the-Middle" auf dem CAN-Bus 
spielen und die entsprechende CAN-Message bei Bedarf so manipulieren 
dass das Gerät denkt der Rückwärtsgang ist drinnen. Das wäre nicht so 
schwierig, entsprechende Hardware und Software gibt es. Ob man so einen 
Eingriff bei einem Fahrzeug tatsächlich machen will ist eine andere 
Frage, beim Infotainment könnte man das vielleicht noch akzeptieren.

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Ohne Änderung am Code könnte man "Man-in-the-Middle" auf dem CAN-Bus
> spielen und die entsprechende CAN-Message bei Bedarf so manipulieren
> dass das Gerät denkt der Rückwärtsgang ist drinnen.

Das ist aber umständlich. Einfacher wäre imho das Bit dafür im 
Schattenregister zu setzen und zu löschen als täte es der CAN-Busparser.

Schließlich ist das kein staatisch anliegendes Signal sondern ein 
ereignisgesteuertes Bit in irgendeiner Variable
mit dem warscheinlichen Namen "video-suorce".

Namaste

: Bearbeitet durch User
von Dieter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Winfried J. schrieb:
> Das ist aber umständlich. Einfacher wäre imho das Bit dafür im
> Schattenregister zu setzen und zu löschen als täte es der CAN-Busparser.

Du meinst im Gerät? Dann muss aber diese Funktion "hineingepatcht" 
werden, einschließlich einer Möglichkeit das ein- und auszuschalten. Und 
das wollte ich ja mit dem "Man-in-the-Middle" vermeiden. Wie gesagt, 
entsprechenden Code und Hardware gibt es, siehe z.B. ältere BlackHat 
Vorträge, wo das für Security Untersuchungen vorgestellt wurde.

von Olli Z. (z80freak)


Bewertung
0 lesenswert
nicht lesenswert
Nur zur Info: Wie man das über CAN macht weiss ich und hab das auch 
schon realisiert. Aber es ist recht umständlich, denn man muss einen 
CAN-Filter bauen der auf der einen Seite mit dem Sender (in meinem Fall 
ist es der Tacho der den Bus speist) und auf der anderen Seite mit dem 
Radio "redet". Der Filter muss überwiegend alles bidirektional 
durchschleifen, nur unter bestimmten Bedingungen simuliert er auf der 
Radioseite das Bit in dem Byte der CAN-ID welches den eingelegten 
Rückwärtsgang reflektiert und damit sorgt das das Navi auf Video-IN 
umschaltet. Heraus kommt man da mit Bordmitteln indem man irgend eine 
Taste am Navi drückt, z.B. Radio oder Menu, oder man den Rückwärtsgang 
wieder rausmacht. Bei letzterem allerdings mit einigen Sekunden 
Verzögerung.

Das war aber wirklich nur eine Nebenanfrage zu der ich zu gegebener Zeit 
lieber einen eigenen Thread eröffne. Denn hier geht es ja um was 
anderes...

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.