Man braucht 2 Tools: Hex-Editor (meine Wahl: HxD), und einen Disassembler, der ARM versteht (meine Wahl: "Cutter"
Sie müssen registriert sein, um Links zu sehen.
), beides Freeware.
Den Hex-Editor braucht man zum Ändern (ginge wohl auch direkt in Cutter, funktionierte bei mir aber nicht auf Anhieb). Die richtige Stelle sucht man also zuerst mit dem Disassembler.
1. Zuerst also die FlashGPS.tool (habe die aus dem Rider-Ordner genommen) in Cutter öffnen. Nun wollen wir nach der Fehlermeldung suchen. Dazu lassen wir uns erstmal alle Strings anzeigen, indem wir auf "Windows"->"Strings" klicken:
Du musst Regestriert sein, um das angehängte Bild zusehen.
2. Wenn wir nun die String-Liste runterscrollen, finden wir irgendwann die Fehlermeldung, die interessant klingt: "Unknown device detected". Aber wo wird die nun im Programm verwendet? Dazu machen wir einen Rechtsklick darauf und klicken auf "X-Refs", um uns alle Verweise auf diesen String anzeigen zu lassen.
Du musst Regestriert sein, um das angehängte Bild zusehen.
3. Das sieht dann wie hier aus. Und: Glück gehabt! Denn es gibt nur einen einzigen Verweis, und zwar in der Funktion "Initialize_CEnvironment". Das klingt doch ganz gut: da wird anscheinend irgendwas initialisiert, und dabei wird irgendwo auf unsere Fehlermeldung verwiesen. Dann schauen wir uns das doch mal genauer an.
Du musst Regestriert sein, um das angehängte Bild zusehen.
4. Also in der Funktionsliste die Funktion gesucht, und per Doppelklick springt man im Disassembly-Fenster an die richtige Position.
Du musst Regestriert sein, um das angehängte Bild zusehen.
5. So, da sind wir also. Erstmal werden wohl nur ein paar Variablen initialisiert. Das soll uns nicht weiter interessieren. Wir scrollen einfach mal runter.
Du musst Regestriert sein, um das angehängte Bild zusehen.
6. Da finden wir dann eine Stelle, an der unsere Fehlermeldung auftaucht (bei 0x0000c900). Interessanter ist aber, dass ein paar Zeilen davor eine Funktion aufgerufen wird (bl fcn.00006384), dann ein Test/Vergleich durchgeführt wird (tst r0, 0xff), und dann ein "Conditional Jump" (bei ARM spricht man eigentlich nicht von Jumps, sondern von "Branches") stattfindet (bne 0xc928). "bne" steht für "branch on not equal" und bedeutet, dass die Ausführung an Adresse "0xc928" fortgeführt werden soll, wenn die beiden Register (r0, 0xff) nicht übereinstimmen.
Es ist also anzunehmen, dass die Funktion "fcn.00006384" die Geräte-ID ausliest und irgendeinen Wert zurückgibt. "tst" überprüft diesen dann. Wie dieser Wert nun aussieht, ist uns aber herzlich egal. Wir sehen nur, dass wenn der Test "0" zurückliefert, unser Conditional Jump "bne" nicht stattfindet. Stattdessen wird dann das Programm einfach an der Stelle weiter ausgeführt, was dazu führt, dass die Fehlermeldung ausgegeben wird und das Programm beendet wird. Für die Beendung ist der Jump/Branch "b 0xcb98" in Zeile 0x0000c924 zuständig.
Wenn der erste Test aber Ungleich-0 ergibt, dann springt BNE zu Zeile 0x0000c928 und fährt dort mit der Ausführung fort. Dort sehen wir, dass erneute Tests durchgeführt werden (CMP und CMPNE), allerdings hier mit einem Conditional Branching wenn beide Werte im Test gleich sind: "beq 0xc96c", also "Branch if Equal". Andernfalls landen wir auch hier wieder bei einer Fehlermeldung und beenden das Programm durch einen Sprung zu 0xcb94.
Du musst Regestriert sein, um das angehängte Bild zusehen.
7.1 Wir müssen also irgendwie diese Tests zu unseren Gunsten entscheiden. Aber das ist zu kompliziert. Viel einfacher ist es, die Ergebnisse der Tests einfach zu ignorieren. Wir wollen ja nur an den Code-Blöcken vorbei, die die Fehlermeldung ausspucken und das Programm beenden. Wenn wir also statt "bne" und "beq" einfach sagen, dass wir in jedem Fall "branchen" wollen, dann müssen wir nur diese beiden Instruktionen ändern, und zwar in ein "b", dass also generell einen Sprung/Branching ausführt, egal was vorher passiert. Die beiden Blöcke mit den Fehlermeldungen werden dann einfach übersprungen und niemals ausgeführt. Und das Programm denkt dann (hoffentlich, und in diesem Fall funktioniert das glücklicherweise), dass vorher alles okay war und es jetzt mit der Update-Routine fortfahren kann.
Aber wie sieht der Code dafür aus? Fangen wir mit der ersten Instruktion "bne" an, die wir auf "b" ändern wollen. Dazu darauf ein Rechtsklick->Edit->Instruction.
Du musst Regestriert sein, um das angehängte Bild zusehen.
7.2 Wir haben also unsere Instruktion mit dem Wert "0b00001a", die für "bne 0xc928" steht. Und zwar an Adresse "0x0000c8f4". Indem wir in dem Fenster die Instruktion auf "b 0xc928" ändern, sehen wir, dass der neue Code dafür nun "0b0000ea" lautet. Sprich: wir müssen in der Programm-Datei an Adresse "0x0000c8f4" den Code von "0b00001a" in "0b0000ea" abändern. Das Gleiche machen wir noch für das zweite Conditional Branching. Dafür gibt's jetzt keine Bilder, aber dort müssen wir an Adresse "0x0000c934" den Code von "0c00000a" in "0c0000ea" abändern. Damit sind wir in "Cutter" fertig und können das Programm schließen.
Du musst Regestriert sein, um das angehängte Bild zusehen.
Du musst Regestriert sein, um das angehängte Bild zusehen.
8. Öffnen wir die FlashGPS.tool also im Hex-Editor. Nun scrollen wir zu der vorher notierten Adresse "0x0000c8f4" und finden dort unsere Byte-Folge "0b00001a" als "0B 00 00 1A" wieder. Wie wir vorher herausgefunden haben, müssen wir hier lediglich das "1A" in "EA" umändern. Ebenso passen wir die zweite Stelle an.
Du musst Regestriert sein, um das angehängte Bild zusehen.
9. Nun noch abspeichern. Und das wars dann auch schon :smile: