 Hi, willkommen auf dem im Bettespielplatz. Ich habe mir vor ein paar Monaten zwei solche China GoPro-ähnlichen Action-Kameras gekauft. Ich wollte damit eigentlich nur Stereo-Videos machen. Irgendwann kam es durch so ein kleines Problem auf, dann habe ich angefangen zu reversen. Irgendwann wird das am Ende viel mehr Spaß gemacht als die Kameras normal zu benutzen. Jetzt wollte ich euch mal zeigen, weil ich aber alles so entdeckt habe und weil ich rumgebastelt habe. Und warum das vielleicht auch cooler ist, als 3D-Videos zu machen. Also erstmal das Ding ist ziemlich billig, deswegen kann ich mich gar nicht zurückhalten. Eine angebliche 4K-Kamera. Also ich speichere mich 4K gedönst ab. Der Sensor ist auch groß genug, ist aber supermatschiges Bild. Also wer irgendwie eine 4K-Kamera haben will, für den ist es nicht das Richtige. Aber um so irgendwie so eine billige Action-Kamera zu haben, ist das Ding für den Preis ziemlich gut, denke ich. Das hat einen welchen 4-Megapixel-Sensor, Mikrofon, LCD-Screen mit ziemlich schlechter Auflösung, irgendwie 320x240 und so ein paar Peripherals, USB, HDMI und MicroSD, um alles zu speichern. Und Wi-Fi ist ein cooles Feature, das aber etwas verstörend ist. Wie das nicht unbedingt absichert ist. Das ganze Ding ist gebaut mit so einem System an den Chip. Das ist irgendein MIPS Core von einer Firma, die darüber nicht mehr Informationen gibt. Also ich zeige, das ist wirklich sehr undokumentiert. Sie sagen nicht mal, das ist ein MIPS Core, das ist ein Data Sheet. Sie sagen nur, es ist ein Risk Prozessor. Das läuft mit irgendeiner mittleren Geschwindigkeit, irgendwie 450MHz vielleicht, weiß man nicht so genau, hat ein paar Hundert Megabit RAM, weiß man auch nicht so genau. Also ich habe das so geraten, anhand der Größe vom Address Space. Das müsste mindestens 128 sein, vielleicht auch mehr, vielleicht irgendwo noch was versteckt. Weiß man halt nicht. Auf dem Ding ist halt nicht nur eine CPU drauf, sondern auch direkt schon ganz viel so spezifische Mediensachen, wie H264 Codec, Object Tracking, Face Erkennung, Smile Detection, was man halt bei Kameras schon mal hat, um genau dann auszulösen. Es wird alles in der Software nicht benutzt, aber es ist da. Was mir im Beispiel vor allem aufgefallen ist, ist das Face Beautification Module, was ich in so einem embedded Core nicht erwartet hätte. Irgendjemand hatte in den letzten Tagen, als er das erzählt hat, einmal gesagt, dass es ja schon ziemlich hart ist, dass man damit das Schönheitsideal direkt schon ins Silicon gießt. Ich denke, das ist auch ein bisschen seltsam. Also das ist alles, was man zu diesem Core findet, wenn man Internet sucht. Ich habe lange gesucht auf Baidu und Google und Bing und mit 1000 verschiedene Stichworten. Das Beste, was halt rauskommt, ist dieses zweiseitige Data Sheet. Hier in dem Blog Diagramm steht auch klein, noch die Face Beautification Engine drin. Muss voll wichtig sein. So sieht es aus, wenn man das ganze Ding aufmacht. Dieses Ding ist halt eigentlich ein CPU Core, dieses System on the chip, wo alles drin ist. Hier ist ein Sensor auf dem Board, mit der Linse draufmatiert, der hat man nicht abgemacht, damit nicht alles staubig wird. Auf der Rückseite ist nicht so viel Interessante, es ist noch so ein SBI-Flash. Aber eigentlich hat mich nie nur interessiert, dass direkt hier neben dem Core zwei ganz kleinen Nötepunkte waren für ein Serial-Port. Und da ich ziemlich grobmentoriker bin, habe ich nette Leute gefunden, die mir erst mal angelötet haben, damit ich da auch mit rumspielen kann, ohne alles direkt kaputt zu machen. Der Serial-Port ist ein richtig schönes Ding. Da habe ich halt total Spaß dran gehabt. Es hat mich so gefühlt, wie so ein, mir das vorstellt, so als Hacker irgendwie in den 70ern oder 80ern, mit einem Mainframe einlockt. Es gibt vielleicht eine DoCoo, aber das Grenzsystem ist unbekannt, da gibt es nicht mehr so viele Forschen. Es gibt einen kleinen Abenteuer-Spielplatz. Es gibt noch viele Firmen, für die man drauf flächen kann. Es gibt eine alte Firma, die ist eigentlich cooler als die neue. Die schafft nämlich nicht nur die Matching 4K, sondern auch noch 720p bei 120 frames pro Sekunde. Was eigentlich viel interessanter ist, als ein matchiges Bild in weniger frames pro Sekunde. Das haben wir später entfernt aus irgendeinem Grund. Man weiß nicht, warum. Es gibt auch keinen Change-Lock. Ganz wichtiger als Feature ist, wenn man den Down-Button hier in der Seite drückt, geht das Wi-Fi an. Wenn ihr irgendwo mal ein Wi-Fi namens ICAM H9 seht, könnt ihr euch mal einloggen. Das Passwort ist halt immer fix, man kann es noch nicht ändern. Man kann direkt alle Bilder runterladen. Ich hab das Ding in der Box bekommen, aber es war kein Manual dabei. Da hab ich mal ge-googelt, was in das Passwort ist. Was ich gefunden hab, war ein anderer Online-Shop, für einen bisschen höheren Preis. Aber das Manual war ziemlich klar, dass es die gleiche Kamera ist. Das Passwort passt auch. Ich hab mal geschaut, das ist ein ziemlich guter Shop. In Finnland haben ganz viele verschiedene Produkte, die man zum selben Preis auch findet. Ich glaub, die haben einen ziemlich guten Profit. Man bekommt dafür auch noch so eine Android-App, die wirklich sehr hässlich ist, und ziemlich schlecht funktioniert. Das heißt Easy-ICAM. Ich hab auch mal ein bisschen rein reversed. Ist auch ein Haufen GPL-Boot, glaub ich, drin. Es gibt natürlich keinen Source, aber im Endeffekt war mir die App jetzt nicht so wichtig, nur, falls einer von euch Lust hat, GPL-Verletzungen auf den Grund zu gehen. Das geht da ganz einfach. Man kann da mit Livestreamen sogar übers Wi-Fi. Man verbindet es mit dem Handy zum Wi-Fi, dass die Kamera aufmacht mit diesem Passwort. Die Kamera holen, Audio und Video. Kann also Einstellungen ändern, kann Videos aufnehmen, kann Bilder aufnehmen, alles runterladen. Ich wollte erst mal gucken, wie ich den Stream auf einem normalen Rechner benutzt kann, weil ich halt nicht diese Dove App dafür nehmen wollte. Das ließ in der Beineway nicht so gut finden, aber beim Sniffen war sofort klar, einmal in den Wire-Shark reingeschaut, da sieht man sofort die URL. Das klappt auch ganz gut direkt. Das ein bisschen schade ist, man sieht schon eine URL, das ist MotionJPEG. Das ist so ein Videokodec, der funktioniert neben jedes einzelne Bild als JPEG gespeichert wird. Das viel ineffizienter ist als modernen Kodecs. Bei derselben Bitrate hat man viel matchere Qualität. Ich hab da mal rumprobiert, also ganz doof einfach mal Stem-JPEG, da H.264 hingeschrieben. Geht leider nicht. Aber später noch ein bisschen in dem Room Reverse, in dem Media Server, wonach es mir ausser als müsste, genau das eigentlich gehen. Bist mal mal erforschen, wie das irgendwie geht. Ich fände so ein H.264-Stream mit gute Qualität echt schön. Was ich für mich am interessantesten war, war der FDP Server da drauf. Der ist halt auch so handgekloppelt, nichts, was man irgendwo kennt. Es ist halt, Leute sich dachten, FDP ist nicht so schwer, das kann man selber machen. Geht natürlich wie immer schief. Man kann darüber halt alle Bilder hoch- und runterladen. Und was am schönsten ist, man kann auch eine Fernwehr hochladen. Beim nächsten Reboot wird der installiert. Man muss je nachher aber leschen, weil sonst wird bei jedem Reboot neu die Filmwehr flaschen. Das ist ein bisschen schade. Aber wenn ihr also ein offenes Wi-Fi, oder ein Wi-Fi seht mit dem Namen, könnt ihr euch einloggen, ein Filmwehr ändern. Das ist halt schon ziemlich böse. Man kann mal gekauft und nicht weiß, wie offen das steht. Ich wollte eigentlich ursprünglich auch mal schauen, wie man das Wi-Fi verpasst, was verändert. Aber habe ich am Nachher gar nicht ausprobiert. Es sollte ziemlich einfach sein. Es gibt also eine Partition, wo eine Host-APD-Konflikt darauf ist, oder gerne mal ausprobieren. Das ist so sieht der MJPEG Stream aus, wenn man das einmal macht. Man sieht es noch ein bisschen trotz der schlechten VWA-Qualität. Es ist ziemlich JPEG-Artefaktik. Das ist total hässlich. Und nicht wirklich, was man so gerne hätte. Das ist ungefähr, was die Kamera macht. Dann habe ich sie natürlich auseinandergenommen. Denn installte Dinge sind, wenn man einem auf den C-Report connectet. Denn der sieht schon mal richtig schön bunt aus. Die haben so Terminal-Escape-Codes reingemacht, damit es auf jedem ordentlichen Dinos-Terminal auch richtig schön farbig ist. Und es gibt einem richtig viel Output. Das ist eine Freude, wenn man es erstmal connecte. Ich habe hier per C-Report es angeschlossen mit so einem Bus-Pirate. Total simpel, nichts Spezielles dabei. Wenn ich jetzt mal eine Strom verbinde, kommt erstmal richtig schön viel ausgablich. Ich habe keine Ahnung, was es meist davon bedeutet. Ein paar Sachen sind irgendwie klar, aber das meiste ist halt irgendwie spezielle Bildprozessorsachen und ähnliches. Und hier bekomme ich direkt eine nette Shell. Wenn ich mal help angebe, bekomme ich auch richtig viele Befehle. Wir haben an sich viele Stunden mit beschäftigen Sachen ausprobieren. Was ganz nett ist das OS-Ding. So macht es erstmal nix. HelpOS kriegt man sogar eine Info. Und ich kriege ziemlich viele Informationen hier. Was ich sehr schön finde, muss ich erstmal wissen, bei den Betriebs-Team laufen alle, es gibt für eine verschiedene Prozesse isoliert sind, sondern es gibt nur ganz viele Thread-Steam im selben Adressbereich laufen. Die teilen sie alles und damit kann man auch einige Informationen bekommen, die man sonst in normalen Betriebs-Team nicht einfach auflisten könnte. Weil ich will alle Malloc-Allocationen, die alle Prozesse jeweils gemacht haben, kann ich hier sehen, oder welche auf Free sind. Das ist zum Debug ganz nett, wo man halt irgendwie was kaputt macht und wissen will, warum es genau kaputt geht. Sehr schön, wenn man es einem sehr viel Informationen auflistet. Es laufen wir direkt schon ganz, ganz viele Prozesse hier. Ich weiß nicht, was hier gerade gedammt wurde. Vielleicht ist das Ding abgestürzt und da gibt es mir ein Memory-Dump. Ich weiß es nicht. Es ist ganz viel Rater-Rei dabei. Ich weiß einige Dinge, aber das ist ein komplexes Teil. Ich bin immer am Raten, was wirklich passiert. Ja, ich hatte die falsche Idee und ich funktioniere jetzt schon mal die Helper rauskopiert. Was hier passieren kann, ist, wenn man Pechert und ein Befehl nimmt, der nicht so dokumentiert ist, dann führt man in den Außen alle Stürz ab, was man bei dem System merkt, dass es auch wieder richtig viele Ausgabe einem gibt. Wenn man stürzt, dann kann man wenigstens mal die Programmierer sagen, was dann alles los ist, der gibt mir für alles, was er ausgeben kann. Am Ende bekomme ich diese Dead Shell. Er setzt das prompt durch Dead und nicht mehr viel funktioniert, aber man kann zumindest noch ein bisschen Speicherdumpen. Hier gibt es den tollen Dump-Befil. Den gebe ich, ich möchte Beides haben, gebe mir eine Adresse und eine Länge und der hat mir einen schönen Next-Dump. Ich finde das total freundlich von den Entwicklern, dass sie sowas alles einbauen. Was mir sehr praktisch gerne aus Dump-Programm write and read, um ein bisschen Daten von der SD-Karte in den Speicher zu laden oder andersherum, kann man das auf dem Rechner mal besser analysieren. Die Network-Shell, die ist auch ziemlich ausführlich, die kann auch viel mehr als das eigentliche Device normalerweise könnte. Ich reboots einmal, weil bei diesen Dead-Modos bei sehr vielen Sachen abstürzt, die normalerweise funktionieren. Das ist halt nur so ein Recovery-Debugging-Tool. Es gibt diese Net-Shell hier. Wenn ich hier Fragezeichen mache, bekomme ich nur die Netzwerkspezifischen Kommandos und es gibt noch ungefähr 10, 15 Undokumentierte, die nicht in der Liste hier drin stehen. Einiges hier fand es auch ein bisschen bekannt. Der WPAS ist der WPASublicant, den Sie jetzt echt draufgepackt haben. Bei dem das von der Lizenz auch vollkommen okay ist, das ist da legitim. Ich habe hier keine GPL-Verletzungen bei der Firma entdeckt. Wenn man verschiedene Firmenwesen durchprobieren will, das wäre nämlich ziemlich absurd, wenn der irgendwie Firmenwesen anbieten würde. Man geht lieber in russische Foren, wo es einen etwa 400 Seiten langen Thread gibt, wo man alle 200 Posts ungefähr eine Firma erfindet und zwischendurch mit Google Translate raten kann, was die Leute sagen, was besser und schlechter geworden ist oder was überhaupt die Änderungen sind. Ich habe mich durch ein paar durchgekämpft, habe am Ende einfach irgendeine Firma gepickt und die auseinander genommen und den Rest erstmal ignoriert. Das ist die BN, die 9 Megabyte groß ist, was ziemlich große Mengen Code eigentlich ist. Man muss sich da ein Riesen-Heu auf dem Wühlen um die interessanten Sachen zu finden. Wie man es erzählt hat, um zu flächen, packt man es auf die SD-Karte, die man in den Rechner steckt oder per FDP, rebooted, wartet ein paar Minuten. Man findet sehr viele panische Posts von Leuten im Forum, die sagen, meine Kamera ist kaputt, die Bildschirme ist weiß. Dann kriegen die die Antwort, fünf Minuten warten bis das Firmenware Update fertig ist. Und irgendwie progressbar oder irgendein Output ist halt überbewertet. Das braucht man nicht so. Auf der Serienkonsole kriegt man richtig viel Output beim Flächen. Also kann man auch jedem empfehlen, einfach mal ein bisschen dran zu löten. Dann kriegt man auch mit, wie es funktioniert beim Flächen. Oh, es gibt da sogar, ein paar Leute haben sogar ein Repair-Punker da hochgeladen, wo ein Haufen Exeter teilen und ganz properitärer Kram drin ist. Ich weiß nicht, wie legitim das ist und wo die das herhaben. Das ist irgendwie Tools zum Firmenware bearbeiten. Das habe ich schon benutzt. Weil zu dem Zeit, wo ich sie gefunden habe, hatte ich eh schon meinen Tools fertig, wo ich das Format reversed habe. Aber ich glaube, damit haben ein paar Leute auch ohne groß rumzufrickeln, ihr WLAN-Passwort geändert. Das ist wahrscheinlich die benutzerfreundliche Variante. Ich habe das Ding erst mal an Bino-Walk geschmissen, was so ein Standard-Tool ist, wenn man eine Binary hat und mal wissen will, was da drin ist. Bino-Walk geht halt da von vorne bis hinten durch und guckt einfach, was Interessantes findet. Das ist ein Format. Und wenn so ein Ergebnis rauskommt, ist eigentlich schon mal super. Denn dann weiß man, es ist zumindest nicht komplett verschlüsselt. Also zumindest diese Teile hier sind unverschlüsselt und komprimiert. Das muss man halt noch irgendwie raten, wo Kryptoschlüssel sind oder welche Kompromierungsformate die benutzt haben. Das ist schon mal ein schönes Ergebnis. Was ein bisschen mich auf falsche Pferde geführt hat, ist hier zu sehen, war-run-host-APD und user-bin-bash klingt so nach Unix-Faden. Das ist nur Artifakt von der Teilen, die die halt drüber kopiert haben. Und ja, host-APD läuft ja normalerweise häufig auf Unix-Eden-Systemen. Der copyright-String ist übrigens von WPA-Sublicant. Das ist genau das eine Ding, was Sie da in Open Source Software drin haben. Bei dem Rest ist es so, das ist ein ganz fremdes Land irgendwie für mich gewesen. Normalerweise, wenn ich das reversee, suche ich irgendwelche Funktionsnamen, die aufgerufen werden. Das ist ein ein bisschen von einem Smart-Library, der ich benutzt habe, genutzt worden. Hier google man was man findet gar nichts oder manchmal so ein zehn Jahre alten Forum-Spread, wo jemand fragt hier ist dieses Stück Sourcecode, das ich auf der Arbeit habe. Ich verstehe diese Sachen nicht. Das war leider kein interessantes Stück Sourcecode. Ich fand es total witzig, dass halt jemand in dieser Firma arbeiten und fragte, was macht ein RAWT-F0 in diesem C-Code. Magic Sunpea Burnfy. Sunpea steht voll für Sunplus, was der alte Namen der Firma ist, aber die Entwickler dieses SPCA Socks, dass da drauf ist. Irgendwie sehr viele Firmen, die irgendwie zusammenhängen, man weiß nicht genau wie. Interessanter ist halt die binary Daten danach. Das hier zum Beispiel, habe ich irgendwann gemerkt, ist die Länge der Datei. Also die Länge ist genau, das ist die normalen Dateilänge, wenn man das in Little Indian hat. Das heißt, alle Bytes, in Bytes-Aufteilen, die Reihenfolge verdrehen, hatten wir hier genau das 8E 18DA hier stehen. Das heißt, diese vier Bytes sind die Länge der Firma. Haben sich hier denken, was könnte das sein, ein bisschen rumgeschaut. Und dann gemerkt, diese vier Bytes sind ein Offset in der Datei. Wenn man an dieses Offset geht in der Datei, hier unten, finde ich man da, aber das war dieses hier, finde ich man da auch wieder so ein Magic String, dasselbe noch für mehr Offsets. Also man findet, wenn man ein bisschen rumschaut, merkt man, dass es zwar ein bisschen random aussieht, aber ich kann es leider nicht so richtig markieren. Der zweiten Zeile hier in dieser zweiten Spalte, das ist irgendein Offset. Das ist auch ein Offset, was ich erst gar nicht dachte. Diesen, wenn man zu zwei A 3720 geht, findet man, dass hier was total nach Müll aussieht und nicht wie ein Header. Aber stellt sich raus, das ist der interessanteste Part. Ich habe keine Ahnung, was die Burn Header 1 und 2 sind. Keine Ahnung, was da gespeichert ist. Aber das hier, das ist, was ich wollte, das ist der Source Code. Das ist der Binary, das sind MIPS Instructions. Die Frage war nur, wo wird, sorry. Ja, das ist genau der Code, der ausgeführt wird. Das ist ein interessanter Part. Das war schon alles, was ich unter Teil des Formats brauchte, wo es diesen Teil kann ich ausschneiden, den Rest ignorieren und später noch gucken, ob man es brauchen kann, aber erst mal das Reversen, was da ist. Die Frage ist jetzt, wir haben dann einen Haufen Code. An dieser Stelle hier, man ist total bereit zu wissen, wo das jetzt gemapped ist als Wirteladresse, denn wenn man das Disassembly sich anschaut, findet man Referenzen zu festen Speicheradressen. Das heißt, er lädt ein String von der Adresse 0x804040 oder so. Und wenn ich jetzt nicht weiß, wo das gemapped ist, dann weiß ich auch nicht, welcher String in der Datei es ist. Ich kenne nur die virtuellen Adresse im Speicher, aber nicht die Adresse in der Datei. Also ich muss irgendwie gucken, wie kann ich diesen Block hin und her schieben im Speicher, dass es hinkommt. In der Annahme, also die Grundanahme, die ich getroffen habe, war, dass dieses Ganze ein Block ist, der an eine Stelle verschoben wird. Das heißt mal, nur die Datei wird an eine Stelle im Speicher gemapped und nicht irgendwie mehrere Parts. Was zum Glück so geklappt hat. Ein Trick, den ich hier benutzt habe, ist, dass da sehr viele Strings drin waren. Und wenn man sich anschaut, wie so eine String-Tabelle kompelliert wird, dann hat man dieses C-Konstrukt hier mit drei Strings und er packt irgendwo im Speicher. Ich habe es jetzt so pseudo-gutmäßig hingeschränkt. Und Speicher packt ja einfach alle hintereinander hin, getrennt mit Nullbytes, weil ein String halt mit Null terminiert wird in C. Manchmal auch mehr für Alignment, damit das hier auf einer Adresse startet, die mit Vielfaches von vier Bytes ist, das als ein Mistprocessor total gerne hat. Wir messen diesen Beispiel, er nimmt, dass dieses Data bei NullX 1000 mapped ist, dann würde in S tatsächlich drin stehen. Also S ist ja eigentlich eine Liste von Pointern, von drei Pointern zu Strings. Einmal der Pointer zu NullX 1000, im Anfang hier von, das heißt in diesem A einmal dasselbe plus vier, dann kommt man bei der Null hier aus, also Null, eins, zwei, drei, vier. Und nochmal dasselbe Null und C, um hier zum CCC zu kommen. So, wenn ich jetzt hier Teile lese und nicht die Wette ein Interessen kenne, dann sehe ich trotzdem irgendwo diese Strings hier und irgendwo sehe ich diese Pointer hier. Und wenn ich jetzt erraten kann, dass das Strings sind und das Pointer sind, kann ich versuchen irgendwie zu matchen. Ich sehe hier der Abstand von dem Strings zu dem sind vier Zeichen, von dem zu dem sind acht Zeichen. Und woanders habe ich mal eine Pointern, dann merke ich hier auch, von hier zu hier sind vier Zeichen, von hier zu hier sind acht Zeichen. Kann man sich denken, wenn es genug sind, wo es übereinstimmt, dann wird das schon passen, dann klappt das alles. Kleines Programm geschrieben, was das macht, was ein bisschen trickier war, gedacht weil es halt manchmal hat man Strings, die man übersieht, oder manchmal hat man Sachen, die keine Strings sind oder Pointer, die keine Pointer sind. Was am Ende raus kam, der Code wird gemappt nach NullX 80, Null, Null, Null, Null, Null, Null, Null, Null. Was irgendwie ein langweiliges Ergebnis war, das hätte man auch raten können. Alle Pointer fingen mit NullX 80 an, das hätte man einmal probieren können. Allga, für die Zukunft, vielleicht kann man es einmal brauchen. Ich habe ganz kurz, ganz, ganz, ganz kurze Zusammenfassung, wie man MIPS Code liest, weil so ein bisschen den Folien danach drauf kommt. Wenn das irgendwas unverständlich ist, ist nicht so schlimm, das kann aber trotzdem helfen. Also man hat auch so auf dem MIPS hier 32 Register, die jeweils 32 byte groß sind und die haben so ein paar symbolischen Namen. Also man kann die mit Null bis 31 betiteln, aber die haben auch anhand ihrer Funktionen gibt man denen auch extra Namen. Sollte ich die S0 bis 7, welche die in dieser Calling Convention, die dort benutzt wird, vom, ja, es wird später wichtig, die werden gespeichert, bevor man ein Funktionsaufruf, sorry, wenn man ein Funktionsaufruf macht und die Funktionen erst Null benutzen würde, muss sich anfangs sichern und die wiederherstellen mit derjenige, der die Funktion aufgerufen hat, weiter damit rechnen kann. An Null bis 30 Funktionsargumenten, wenn man irgendwo sieht, dass sie zugewiesen werden, das meistern nach dem Call und das ist wie ein Funktionsargument. Wenn man mehr als vier Argumenten hat, kam es, glaube ich, meist aus dem Stack drauf und in V0 kommt der Return Wert rein. Instruktionen sind auch, die sind alles ziemlich simpel, ist ja kein X86, sondern so eine Risk-Architektur. Man hat so Load Befehle, man hat Load mit der Länge, einen Wordladen an Inregister S0, der holt es von 4 plus, also man liest das hier, dieses Offset ist wie bei X86 AT&T Notation, summiert man das hier, 4 plus V0, also die Adresse in V0, plus ein Offset von 4 ist die Adresse von der geladen wird. Analog dazu, Speichern per Store Byte, wird ein Byte aus diesem Register gespeichern, diese Adresse. Solche Aditionsdinger sehen ein bisschen anders als bei X86, hat mal drei Argumente, das erste ist, wo das Ergebnis gespeichert wird und die anderen beiden sind die Operanten. Und das wäre jetzt ein Beispiel noch für so ein Funktionsaufruf oder ein Funktionspointeraufruf als Call. Hier wird, das ist Jump and Link oder sowas, Jump and Link Register, wie das Argument ein Register ist. Es springt an die Adresse, die in diesen Registriker speichert, es speichert vor dem Program Counter up in dem Return Address Register, was ein bisschen ungewöhnlich ist, wenn man sowas noch nicht gesehen hat. Wenn man hier halt vertiefere Rekussionen hat oder eine andere Funktion aufruft, muss man selber die alte Return Adresse speichern und später wieder herstellen. Das macht nicht wie bei X86 CPU für einen, man Call aufruft und sofort die Return Adresse am Stack gepackt. Das passiert nur, wenn jemand das manuell macht. So, und hier ist es direkt bis mit Miss Code und noch eine Besonderheit sieht, und zwar zwei Besonderheiten sieht. Einmal sind alle Instruktionen auch genau 32-Bit lang, also vierbeit lang, was sehr hilfreich ist, da man immer genau weiß, wo sie anfangen, wo sie aufhören. Bei X86 hat man das schon mal ein bisschen verschoben, weiß nicht genau, was anfängt, ist alles ein bisschen nervig. Was nervig ist, wenn man hier ein 32-Bit-Wert ein Register laden will, geht das nicht mit einer Instruktion, denn die 32-Bit, naja, bliebe kein Platz mehr für die Instruktion übrig, wenn man die Daten 32-Bit weit da drin hat, wird in zwei Stücken gemacht. Hier wird einmal in A0 sollen Punkte reingeladen werden, das heißt, hier werden einmal load-upper-immediate, werden die oberen 16-Bit geladen und danach nochmal die unteren 16-Bit. Das ist hier das IDA-Disassembly, der hat einem das schon was vereinfacht. Hier würde halt nur die unteren 16-Bit stehen und er hat schon das zusammengesetzt und rausgefunden, wo der Point dann zeigt. Das ist leider nicht komplett zuverlässig, manchmal verhasst man sich wieder da und schafft es nicht rauszufinden, was wie ich der komplette Pointer ist. Man hat ein paar Stellen sehr nervig ist. Vermutet man, dass man das viel besser machen könnte, bin ich auch nicht dazu gekommen, da mal rumzufrickeln. Die andere Besonderheit ist der Delay-Slot. Wenn man bei einem MIPS-Prozessor oder bei, wahrscheinlich gibt es auch andere bei dieser Art MIPS-Prozessor einen Funktionsaufruf macht oder einen Branch macht, anders hinspringt, wie hier dieses Branch equals zero, das heißt, wenn Nullis springt dazu dieser No-Code-Sack, wird, auch wenn der Jump genommen wird, noch die Instruktion danach ausgeführt. Also dieses Load-Word A0 wird in jedem Fall ausgeführt, noch bevor der an diesem No-Code-Sack ankommt. Das klingt gar nicht so kompliziert, wenn man es einmal im Kopf hat, aber ich habe das ständig vergessen. Dann liest man ein Code und es macht einfach gar keinen Sinn und vieles schon später fällt einem auf, da war noch irgendwo ein Branch-Delay-Slot, den man übersehen hat und dann macht alles Sinn. Also wenn irgendwo, wo was keinen Sinn macht, wenn ihr MIPS-Code lest, den dann Branch-Delay-Slot, das hat mir viel Zeit gekostet. Was viel Zeit gespart hat, war so ein Debug Outputs, die in dem Programm drin waren. Hier wird eine Funktion NDK-Lock aufgerufen und einer der Parameter, Parameter 1 in Regisseur 1, ist etwas, das für das gewisse Funktionsname aussieht. Und diese Funktion wird halt von 100 oder 150 anderen Funktionen aufgerufen. Da wir gar keine Symbole haben, gar keine Ahnung, haben wir die Funktionen heißen, kann man die Information hier nehmen, um das alles wieder umzubenennen. Ich habe geguckt, welche Caller gibt es, also per Skript geschaut, welche Caller dieses NDK-Lock gibt es. Ich habe geschaut, was ist in Regisseur A1 drin. Wenn man Instruktion für Instruktion zurückgeht, bis man zahlt, weiß. Und das hat Funktionsname gespeichert. Und wenn man schon mal Haufen Funktionen da hat, ist das ganz schon mal viel weniger angsteinflößend. Wenn ich sonst die neuen Mega-Bite-Binary-Lade habe, da 500 oder 5.000 Funktionen, ich habe keine Ahnung, die alle einen Zufallsnaben haben, dann weiß man gar nicht, wo man anfangen sollen. Wenn auf einmal welche dann fdp.d.c.md.port heißen, ist sofort klar, was da passiert. Und wenn ich eine fdp.d. frickelen will, dann spring ich da rein und weiß Bescheid. Gab es nur ein paar verschiedene Lock-Funktionen. Davor muss man mal alle raussuchen. Hier ist das Some Print of Thing 2, wo es auch genauso benutzt. Auf die Weise habe ich ziemlich viele Symbole recoveren können. Das ist so eine Standard-Technik beim Reversen. Das ist nichts Besonderes, aber hat hier viel geholfen. Falls einer von euch noch nicht kennt, das ist eine schöne Sache. Viele Stunden Reversing later, später habe ich dann halbwegs herausgefunden, was die Shell-Commands alle machen, oder die mit interessanten Namen, die sonst halt abgestürzt sind, wenn man denen nicht die richtige Parameter hergegeben hat. Also, wir haben halt nicht so sehr Tests, wie ob die Parameter im Gericht sind. Wenn man es falsch macht, stürzt er das ganze Gerät ab. Ich bin ziemlich froh, dass meine Server nicht so sind, dass, wenn ich da irgendwie ein Befehle falsch tippe, für eine tippe, dass der ganze Server abstürzt, wäre ziemlich traurig. Ich habe eine Sache, die will ich jetzt mal als Demo versuchen. Ich hoffe, es geht nicht schief. Einmal als Ding-Rebooten. Eine Funktion, ich hatte eine Vermutung, was sie macht, war mir nicht ganz sicher. Hab gesagt, ich kann es einfach mal ausprobieren. Denn einer meiner Lieblingsbefehle in dieser Shell nennt sich Map-Exe. Und der Name ist ein bisschen bewerrend, aber was es macht, ist, ich gebe ihm eine Adresse und die called her, und ich kann mir noch Parameter geben. Also, ich kann einfach irgendwelche Adressen anspringen und gucken, was Funktionen machen. Irgendwo hat das hier aufgerufen zwischendrin. Wenn ich hier verschiedene Sachen reingebe, merkt man schon, dass es ein bisschen anders verhält. Ich hatte die Vermutung, dass es so ein, oder kann jemand sehen, raten, was es macht, bevor ich es dir verrate. Ja. Nicht ganz. Es ist so ein Putschar, also 0x41 ist der Code für ein Groß A, das gibt er hier aus, 0x10 ist ein Zeilennoveau, keine Ahnung, wo der hin ist. Sollte eigentlich auch irgendwo rauskommen. Das ist natürlich ziemlich böse jetzt gewesen, wenn das hier nicht funktioniert, wenn das hier komisch funktioniert. Der hat der nächste. Oh, danke. Ja, es gibt bestimmte. Ist es bei den Folien? Das ist nur weiß, okay. Sorry, habe ich nicht gemerkt. Gut, das ist anscheinend Putschar, der schickt irgendwas auf einen serialen Port heraus, aus der Nutzung zum Debuggen. Und hier ist ein bisschen kompliziert da noch der Print F, die auch richtig schön funktioniert. Da kann man auch, ja, kann man direkt, wenn man eine Funktion gefunden hat beim Reversen, direkt mal ausprobieren, was ihr macht. Oder sie benutzen. Oder als eine eigenen Code reinladen, mit MapExe ausführen. Ich finde, diesem Fiel total praktisch. So, das Ganze jetzt bisher hat nur funktioniert mit einem Serial Port dran. Und wenn ich jetzt aber irgendwelche an der Kamera rumspielen will, ohne erst aufzumachen und rumzulöten und vielleicht alles kaputt zu machen, weil ich zu grob mentoreisch bin, will ich vielleicht lieber das Ganze remote machen, am besten über das Netzwerk, wenn man nachher das auch kann, wenn er mein WLAN findet. Und da hat man direkt mal angeschaut, FTP Server, das klingt nach was, was Leute ständig kaputt machen. Ständig falsch machen, weil sie denken, es wäre einfach und irgendwo ist es dann doch nicht ganz so einfach. Und hier ist vielleicht ein Schauter rein, guckt in die erste Funktion, die irgendwie eine Zeile passt und das ist schon irgendwas im Argen. Sorry. Also erholt sich vom Socket ein paar Bytes in den Buffer rein, 200 Bytes. Terminiert das mit 0, ganz schön und ruft eine Funktion auf, die das Aufsplitten soll in einzelnen Parts. Also ich gebe zum Beispiel ein Fehler in User MXN, dann sollen da zwei Springpointe rauskommen, User und MXN, so dass man das ordentlich behandeln kann, soll diese FTP-Command-Split-Funktion machen. Sie bekommt einen Pointer, wo die ganzen, wo die Zeiger zu den einzelnen Wörtern gespeichert werden sollen. Die hat mit Leerzeichen oder TAP-ähnlichen getrennt sind und das Command. Und die hat irgendwie hardcoded bis zu 24, Entschuldigung, bis zu 24 Pointer speichert sie ab mit dieser Tabelle. Blöderweise hat man hier nur für 17 Platz. Aber gut, wer wird das schon irgendwie ein FTP-Commandos schicken, wo mehr als 17 Teile drin sind? Das macht doch keiner, was man ist nicht drum kümmern. Das ist sogar kein Problem. So, mal gucken, was die sind, das ist im Detail aus, wenn man sich das alles anschaut. Hier ist dieses Part 0, das ist das Parts-Array von eben, wo drin alle Pointer gespeichert werden. Und hinter diesen Array finden sich hier savedS0 bis S6. Das sind diese Register, die ich vorhin in dem MIP Survival angesprochen hatte, die von einer aufrufenden Funktion gespeichert werden und vorm Return werden sie wieder restored. Das heißt, wenn wir hier diesen Overflow machen und überschreiben die gespeicherten Register, dann lädt er danach zwar nicht unser Return-Adresiere rein, die ist ein bisschen weit hinten, aber die ganzen Register kontrollieren wir mit unseren Pointern auf unsere Werte. Und das ist an der Stelle super praktisch, was danach passiert, denn der Code, der er danach mit S0 was weitermacht, der diese Funktion aufruft, für den S0 zeigt irgendwelche Strukturen rein mit Funktionspointern, da ruft er einen Funktionspointer auf und den nächsten und gibt Argumente rein, die da drin stehen, ist total nützlich. Du könntest was denken, das ist wie eine Backdoor. Aber würde ich es nicht behaupten, aber das ist halt schon irgendwie komisch. Das ist die Funktion, die S0 aufruft. Hier ruft die diesen Command-Handler auf, wo der Back drin ist. Das heißt, nach diesem Aufruf ist S0 zeigt etwas, was wir kontrollieren. Hier ist es ein Pointer, der S0 plus ein kleines Offset, das ist nicht so wichtig. Wichtig ist diese Schleife hier, wo er aus diesem Buffer auf das S0 zeigt, einen Funktionspointer rausholt, einen Argument rausholt, noch ein Argument rausholt und damit den Funktionspointer aufruft. Das heißt, wir können unseren Buffer reinschreiben, welch Funktion aufgerufen wird. Wir können das zweite und vierte Argument kontrollieren. Zwei, drei andere Register zeigen an auf unsere Sachen eine richtig schöne Voraussetzung für den total schönen Exploit. Was leider nicht so gut funktioniert, ist, Schalecode auszuführen, denn die haben tatsächlich eine ganz primitive MMU da drin. Also, nicht aller Speicher ist ausführbar und der Speicher, in dem unser Kram liegt, der ist erstmal per Default gar nicht ausführbar. Man bekommt, wenn man da hinspringt, den Riesenland Crash mit den 10.000 Zeilen. Wenn man zwischen sich anhält, bevor der Buffer voll ist und hoh scrollt, dann kriegt man diese Ausgabe hier PC Violated und diese Ranges hier, ohne weitere Erklärung. Und mit so ein bisschen raten, kann man denken, okay, das hier, das ist auch, wo die Firma gemapt ist, diese 80.000.000. Und das ist ungefähr der Ranges ausführbar sein sollte. Die anderen hier kenne ich nicht. Aber eigentlich würde es erreichen, wenn dieser Rang ein bisschen weiter noch geht, so bis zum Ende des Speicherbereichs. Das funktioniert doch tatsächlich. Man muss nur wissen, wo es ist. Ich habe mal geschaut, der Code, den diesen Dump erstellt hier, der liest einfach alles aus der Maschinenregisterne aus, die an der Adresse hier liegen. Und man sieht, es ist eine line-over-Einstimmung hier. Das sind eigentlich genau die selben Zahlen. 1, 1, 80, 80, die Endzahl, es ist eigentlich exakt das Gleiche. Und ich habe mal geschaut, dieses Ding hier ist halt recht schreibbar. Kann einfach an einer Zahl reinschreiben und schon ist alles ausführbar. Das kann ich sehr empfehlen, einfach da mal reinschreiben. Erste Byte überschreiben in 90, hat man schon alles erwischt, was man braucht. Was ich ziemlich interessant fand, ist, dass das ein Wissen versteckt ist. Wenn ich hier nämlich den Befehl Rack Dump benutze, der Allerregister ausdampen soll, oder ich vermute, der soll Allerregister ausdampen, der Name klingt halt so. Schauen wir noch mal. Hier die Ecke war, das war B000, 1320. Das heißt, 1, 0, 13, 1320, müsste irgendwo hier sein. Ich weiß nicht genau, warum die es nicht ausgeben, weil irgendwie das ist der einzig interessante Teil, die ich hinterher gefunden habe. Aber gut, so gut haben sie nicht versteckt. Man kann ja von Hand einfach mit Damp nachschauen. Das ist ganz normaler Speicherzugriff. Gut, das heißt, wir müssen einmal irgendwo remote dieses Ende überschreiben, bevor wir unseren eigenen Shellcode ausführen. Also Schritt 1 wäre, wir schaffen, also die Situation ist immer noch die folgende, dass wir hier ein Haufen Funktionsbeute angeben können. Argumenten, die rufen die für uns nacheinander auf. Das heißt, wir können erst mal eine Sache ausführen, dann die nächste, dann die nächste, um alles vorzubereiten. Und die erste Sache, die wir machen würden, wäre, diesen executable range zu verändern. Das heißt, an diese Stelle, schreiben wir noch ein byte, oder an diese Stelle auch. Ich habe dafür ein schönes Gadget in der Binary gefunden. Das speichert einfach hier v0, wo eine hingereichende Großzahl drinsteht, an a1 plus ein Offset, a1 haben wir Kontrolle darüber, das heißt, ich gebe a1 an die Stelle, wie wir wollen, minus 2105. Und er überschreibt mir alles. Returned und führt die nächste Funktion aus. Dann dachte ich, ich kann sofort zum Shellcode springen. Leider crash das ständig oder vielleicht einen von 10 mal, das funktioniert. Was ein bisschen verdächtig war, bis irgendwann eine Idee kam, was da los sein könnte. Und zwar, ist das bei MIPS-Prozessoren ein bisschen anders als bei X86. Die haben auch ein Data Cache und Instruction Cache. Die muss man aber tatsächlich manuell manchmal flaschen. Also, wenn ich Speicher veränder und den dann ausführen will, muss ich im Prozess so einmal sagen, da hat sich was geändert. Lär mal deinen Cache oder lär die neu. Und dafür gibt es die Sync I-Operation. Die muss man einmal irgendwie ausführen. Die kriegt ein Pointer für 32 Bytes oder sowas. Das heißt, wir müssen für unser ganzen Shellcode einmal drüber looten. Zum Glück gibt es in der Firma eine direkte Funktion, die genau das macht. Kommt eine Adresse in der Länge, können wir einmal aufrufen. Alles funktioniert, schön zuverlässig danach. Muss man nur einmal den Prozessbescheid sagen, dass man exploiten wollen. Kleinen Shellcode brauche ich noch. Ich habe noch was ganz Primitives hier gemacht. Ich habe mir die Print Adresse rausgesucht. Die lade ich in die Register rein. Ich rufe das auf. Und in dem Jump Delay Slot nach ganz nifty hier ein paar Bytes sparen, schick ich einfach ein Pointer rein, wo ein String entsteht. Der OWN ist ein ziemlich passend Fund. Und einmal zurückspringen, so basicmäßig, go to 10, um alles ein paar Mal auszugeben. Dummerweise die normalen Branch Destruction, mit der man einfach unbedingt zurückspringt, enthält Bytes, wenn ich benutze, kann ich null Byte oder sowas. Dann muss man ein bisschen tricksen. Wenn A0 und A1 verschieden sind, springt dahin. Ist immer verschieden. Dann klappt das schon. Man hofft, dass es funktioniert. Ich werde mal versuchen, zu dem Ding zu connecten. Das ist bitte keiner als Wischenfunk hier. Erkennt das Passwort alle. Aber wäre irgendwie schade. Hier ist noch ein letzter Befehl. Mit Host kann man die ganzen Tasten hier per Software auslösen. So, ich habe das Wi-Fi angeschaltet. Er macht seinen Access Point auf, startet alle Demons. Und wenn man den Rechner jetzt noch mitmacht. Okay, bin verbunden. Oh, war die null am Anfang oder so? Ich habe mir zwischendurch eben schon gedacht, ob das andersrum war. Nee, war nicht mal Absicht. Das Log-in kann fehlen. Wie habe ich das denn geschafft? Ich glaube, dass, wenn man ein leeres Passwort, ein leerer Meduzinnamen hat. Also der Check ist eigentlich nur, ob das erste Token, User ist das erste Token Passwort ist. Dann scheint noch die Länge. Ja, ich kann hier direkt auf alles zugreifen. Aber, was ich eigentlich will, ist es einem exploiten. Oh, Bellin Winner null. Ich glaube, das hier ist ein own, own, own, own, own, own, own. Ich kann es nicht abbrechen. Ich reboot den mal, bevor die CPU so heiß läuft. Wer weiß, ob das gut genug erkühlt ist. Ja, da kann man natürlich auch sinnvolle Schelkote reinpacken. Ich hatte dann mal angefangen, so einen 2-States-Schelkot zu machen. Also an dieser Stelle, hier sind ganz, ganz viele Bytes, die man nicht benutzen kann. Weil er die halt, vorher beim String-Processing, als Trenn-Symbol benutzt. Das war, ich habe so einen Decoder-Schelkot gemacht, der einen zweiten Schelkot holt und dem mit irgendwas gesort. Das war ziemlich schmerzhaft, wenn man, zum Beispiel, war es dann, glaube ich, besser, um minus 1 zu subtrieren, als 1 zu addieren, weil man dann die ganzen Null-Bytes nicht drin hat, die bei einer 1, vor der 1 stehen. Das war viel freckleier. Ich weiß nicht, ob das eine funktioniert hat. Das ist ein paar Monate her. Ich habe deswegen die own Sache hier nochmal benutzt. Okay, dem hat funktioniert. So sieht es am Anfang aus. Das ist schon vorbei gescrollt. Der gibt einem noch so ein bisschen, einen kleinen Error, Sonntagserror, so mag ich das eigentlich gar nicht. Und dann macht er bedroht, was ich möchte. So, so kriegt man Remote irgendwie Kod ausgeführt. Nur, was man da eben hier macht, wäre die andere Sache. Ich habe mir überlegt, wäre ganz schön, wenn man einfach selber Kod reinladen kann, der aufgerufen werden kann von der Firma, zum Beispiel ein neues Befehl für die Shell, oder ein Telnet-Server, der leider halt nicht enthalten ist, oder auch, irgendwelche Bildsachen, zum Beispiel, wenn ich jetzt 2 Kameras habe und möchte Stereo-Videos aufnehmen, es ist ziemlich schön, wenn man irgendwie die, Aufnahmen, gleichzeitig triggern kann, dass die zum gleichen Zeitpunkt aufgenommen werden, oder halt mit einem definierten Verzöger, oder sowas. Also ganz viele Sachen, die halt für normalen Menschen unnötig sind, aber für einen Freaklar ganz schön sind. Und dann mal ich mal gucken, wie kriege ich das, um hier überhaupt einen kurzen Fall auszuführen. Also dieses MapExe-Kommand, der ich vorhin benutzt habe für Putscher und Print-Eff, das hilft mir schon mal, irgendwo hin zu koallen. Also, das ist mir der 1. Schritt, ruf ich einfach mal M-Allow auf, hol ich mir ein bisschen Speicher, dann kann ich mit Read von der SD-Karte mein Programm da reinladen, kann das noch, Map war es noch so ein Befehl, damit kann man einfach ein bisschen Speicher setzen. Damit kann man diese Auswahlschutz aushebeln, oder beenden, und dann einfach in den Code reinspringen. Was halt auch klappt, wenn man so ein einfach einen Shellcode hat, wie eben, nur, ist es ja irgendwie unschön, wenn ich jetzt ein Programm schreiben will, das mit dem Telner Server schreiben will, will ich es nicht unbedingt in S-Lambli machen, sondern dann wollt er C-Code dafür kompellieren. Und dafür ein bisschen mal den GTC überzeugen, das für mich zu machen. Ich habe das ziemlich rumgefrickelt, ich bin mir sicher, dass es für eine viel bessere Lösung gibt, und falls immer von euch sich mit Compilern auskennt und Mips, Abys, würde mich freuen, wenn ihr mich anspricht, vielleicht kriegen wir das viel eleganter hin. Also, was ich, ich habe da einfach Hardcore reingefrickelt, bis es funktioniert hat. Also, Cross Compiler einfach aus Derbit installiert, der stellt aber leider Linux-El-F-Dateien, die man halt erstmal mit Elflow da irgendwo laden muss, und ich kann nicht einfach da reinsprengen. Das heißt, ich habe mir einen Kasten Linkerscript geschrieben, wo man dem Compiler sagt, an welcher Stelle der Datei soll jetzt irgendwie der Ausführbarer Code, wo sollen die Daten hin, welche Sachen brauche ich überhaupt nicht, habe so gemacht, dass einfach die erste Adresse von der, die erste Byte von der Datei was ist, was ich anspringen kann, hat dann länger rumgespielt mit den ganzen Compiler Flex und irgendwie ist nicht hinbekommen, GTC zu überzeugen, nicht so Relocations einzubauen, die ich nötig sind. Der hat so indirekte Calls über die Global Offset Table, obwohl es gar nicht nötig ist. Also, der macht es irgendwie, es gibt bestimmte Möglichkeit, den zu überreden, das schön zu machen. Habe ich aber nicht gefunden. Seitens am Ende habe ich so eine kleine Art Bootloader geschrieben, die am Anfang einmal die, die binary LED, ist ungefähr so, wie ein normaler Bootloader aus der sächlichen Art. Ich habe mal in U-Boot reingeschaut, weil der eigentlich dasselbe Problem löst und habe eine ähnliche Lösung gebaut. Was dann noch fricklicher war, war das Problem, dass die Abys, also die binary Interfaces, die in der Firma verwendet werden, anders sind als die, zu denen ich GCC überzeugen konnte, Code zu erzeugen. Es gibt auch verschiedene GCC Versionen für verschiedene Abys, aber habe da keine Erfolg gehabt. Das am Ende habe ich so einen Übersetzer gebaut. Also, das Hauptproblem ist das Register GP. Das nennt sich Global Pointer und das wird in der Firma dafür benutzt. Es zeigt in den Sonatensegment rein, wenn man irgendwelche statischen globalen Variablen hat, kann man die UDIS GP Register zugrafen. GP plus 10, GP plus 20 und so weiter. In dem Code, der den GCC erzeugt, wird das GP Register allerdings komplett anders benutzt und ändert sich ständig. Das heißt, wenn ich jetzt aus meinem Code auf einmal den Firmenwerkod aufrufe, dann greift er nachher auf was GP relativ zu und das ist alles kaputt. Andersrum, wenn mein Code aufgerufen wird, selbe Problem, wenn es aus meinem Code returned, das GP Register kaputt, alles crashed weg. Weil es dann hingefrickelt habe, waren so kleine Wrapper, das heißt, wenn ich eine Libraryfunktion aufrufe, ruf ich nicht direkt auf, sondern erst ein kleines Stück Code von mir, das den GP richtig setzt und andersrum, wenn meine Funktion aufgerufen werden soll, macht er es gleich danach. Ist ziemlich fricklig, sieht ungefähr so aus. Das ist so eine Libraryfunktion, die UDPrintf. Hier wird einmal das T0-Register-Gladen mit der Adresse von der Libraryfunktion, einmal das GP-Register mit dem GP-Wert, der eine Firma benutzt wird, also jetzt die ganze Zeit fix für eine Firmaversion. Da muss man sich nur wirklich nicht drum kümmern, einfach diese Konstante nehmen, dann springt er zu der Print-Erfung, alles ist super. So funktioniert das. Man könnte auch hier so einen absoluten Jump nehmen zu einer Adresse, hat leider mein GCC gecrashed, als ich versucht habe. Deswegen ist das hier ein bisschen hässlicher der Code. Aber es funktioniert. Ich habe das alles verpackt in Haufen Makros, in Indian Assembly. Der Code, den ich niemals anschauen sollte. Wenn man ihn anschaut, danach am besten sofort wieder vergessen, ist nämlich wirklich hässlich. Aber wie man es auch benutzt, ist ganz simpel. Ich gebe eine Funktions-Definition an, also einen normalen C-Prototypen. Ich sage, wo sich das ein Speicher befindet und dann kann ich es dann einfach callen wie eine normale Funktion. Und das jetzt wäre so eine Funktion, die ich gebaut habe, die ich aufrufen möchte. Dafür muss dann einmal das Defin hier machen. Der sagt, okay, es gibt nachher im finalen Binary ein Symbol AP Test. Wenn ich das aufrufe, wird eigentlich diese Funktion hier aufgerufen. Klingt vielleicht ein bisschen kompliziert, ist aber auch total einfach. Man schreibt seinen Code, schreibt einmal Entrypoints dran für die Funktion, die man von außen aufrufen will und fertig. Und mit ein bisschen Glück kann ich euch jetzt zeigen, dass es funktioniert. Ach so, die Datei existiert schon. Das hatte ich schon mal hochgeladen. So, also ich habe gerade eine komplierte Binary draufgeladen, was ihr seht. Entschuldigung, das ist die Test.C. Das ist genau was auf dem Folienaufdraustand, nur ein paar extra Funktionen noch. Und wird genau eine von, also drei verschiedenen Testfunktionen, die verschiedene Probleme, die halt so beim Komplieren auftreten können, testen und will einmal davon aufrufen. Das ist gerade ziemlich umständlich noch, wenn man es alles manuell machen muss. Aber irgendwie macht das auch viel mehr Spaß, als wenn es einfach funktionieren würde. Also, was man ungefähr machen muss, ist, finden, wo ich die Datei habe, wo es steht, wie man es macht. Erstmal ein bisschen Speicher allokieren, indem wir Mallock aufrufen, was hinter der Adresse sich verbirgt. So, das ist die Mallockfunktion, das ist der Rückgabewert, das heißt, das ist der Speicherbereich, wo wir jetzt benutzen können. Dann setze ich einmal die Endadressen von diesen Speicherschutz. Vielleicht soll ich es einmal printen, wie es vorher aussah. Seite 2, 0. Also, hier sind zwei ausführbare Bereiche. Aber vielleicht lieber ein paar mehr. Hier sind alle ausführbare Bereiche. Jetzt überschreibe ich die einmal die Endadressen davon. Wenn man das jetzt hier vergleicht, vorher gegen diese ausführbare Bereiche bis 80 4f, jetzt geht er bis 90 4f. Da jetzt aber unser ausführbarer Kot hier bei A0 liegen voran fängt, müssen wir diesen Bereich hier auch ändern. Der geht auch bis B0, das heißt, alles, was wir wollen, ist ausführbar, kann gar nichts passieren. Dann laden wir unseren Code rein mit dem coolen Read Befehl, der eine Binary von diesem System hier lädt, an eine Adresse, die wir ihm angeben. Habe ich mich vertippelt, crashed alles. Und jetzt müssen wir das eigentlich schon... Oh, jetzt müssen wir einmal noch den iCash lernen. Das heißt, wir rufen diese Funktionen auf, die ich auch im Xbox benutze, um den Instruction Cache zu löschen. Und jetzt kann man es aufrufen. Mit map.exe springe ich rein. Das passiert nix, weil das ist nur mein Bootloader, der einmal die ganze Binary zum Laufweg macht. Jetzt noch mehr Frickolage. Man guckt einmal mit readElf rein. Wurden das Symboles, das wir anspringen wollen. Das hier wollte ich haben. Das ist eine Adresse plus 20c. Dann lassen wir ein bisschen rechnen. Es ist richtig, richtig manuell hier. Das ist die Startadresse von meinem Programm. Plus das Offset zu der Funktion, die ich aufrufen will. Moment ein bisschen Glück. Funktioniert es. Und das hat ein Welcome draus. Das ist so ein Timeout, wenn man die normalen Tasten nicht benutzt, wie der nach einiger Zeit geht, der in so einen Standby-Modus App UI Message Power Off. So. Oops. Oh, das ist auch, was ich hinbekommen habe. Ich habe den ganzen oder einen großen Teil des Kranes mal mal auf GitHub hochgeladen, wenn ihr mit rumspielen wollt. Wenn ihr mit der Harte mal basteln wollt, könnt ihr gerne zu mir kommen. Ich sitze hier irgendwo beim Slushier Automaten da hinten oder schreiblich per Java oder IRC an. Stellt das ganz zur Verfügung, dass er leider mit der Schelle rumzuspielen macht. Echt Spaß. Kann ich sehr empfehlen. Weil ich für die Zukunft eine Idee habe, was ich wieder machen würde oder vielleicht jemand anders Lust zu machen, wäre einmal den Exploit so zu verwesten, dass man auch mal ordentlich einen Code ausführen kann, da ich meinen Tell-A-Server direkt ausführe. Denn die ganze Zeit um auf dem C-Report auszugeben, interessiert halt keinen. Das merkt mein Nachbar gar nicht. Tell-A-Server bauen, wäre cool. Statt C-Code Rustcode ausführen, fände ich super cool. Und die Sache, die ich gerade gezeigt habe, mit 20 Befehlen, um Hello World auszugeben, das geht sicher auch irgendwie einfacher, wenn man da mal ein bisschen Arbeit rein investiert. Und halt die GCC-Sache ist so eine fricke Leihgrade. Ich habe keinen Lust, nochmal zu machen. Ich habe da irgendwie den ganzen Tag rein, für zwölf Stunden reingesetzt und habe sehr viele Schmerzen erlitten. Aber wenn jemand Lust hat, das cool zu machen, ich würde mich freuen. Hoffen, war was Interessantes dabei. Vielen Dank. Wenn ihr Fragen habt, immer gerne. Der Fragen hat einfach Hände hoch. Der hat hier nur einen Adress, also die Frage war, da wir mixen mit A-Heat-Architektur ist, wenn ich Daten drin habe, wie ich überhaupt ausführen kann, falls man es jetzt nicht hören konnte im Video. Das Ding hat nur einen einzigen Adressbereich für Daten und Code. Der macht ja keine Unterschied. Die einzige Sache ist dieser Schutz, dieser paar Register, die sagen, welcher Code ausführbar ist. Ist MIPS normalerweise immer Harvard? Da haben sie ordentlich was umgebastelt für das Sock hier. Dieses Map war, macht tatsächlich nur, speichert mich nur ein Bein. Ich habe das ganze Ding disassembliert. Das will ich nur speichersetzen. Der Export passiert ja auch nur das. Nee, das. Dann müssen wir wahrscheinlich einiges rumgeändert haben an den Kurs, bevor die das gebaut haben. Interessant, danke. Ja? Okay. Ist das vielleicht so eine historische Sache gewesen, dass es früher anders war? Okay. Ah, da vorne. Du hast gerade ein Mikrotis. Ja, ich wollte fragen, du hast das jetzt mit einer Kamera gesehen. Ist diese MIPS-CPU irgendwie dir bekannt, dass sie noch in anderen vielleicht Sicherheits relevanten Geräten vorhanden ist? Also, ich kann mir vorstellen, dass irgendwelche Überwachungskameras das benutzen. Also, sie hat es schon sehr auf irgendwelche Medienanwendungen ausgelegt mit der Perkderkennung und Videokollexen sowas darin. Das werden wir wahrscheinlich nur dort einsetzen. Ja? Gibt es da keinen BIP? Ah, ich habe für mich noch gar nicht so informiert. Na gut, da muss man noch ein paar Monate warten. Schade. Ja? Konntest du rausfinden, was für ein Betriebssystem das ist? Oder... Das habe ich ganz vergessen zu sagen. Also, was ich weiß, da basiert was auf Thredex, was so ein proprietäres Embedded-Betriebssystem ist. Das sieht allerdings an paar Stellen ein bisschen anders aus. Also, ich habe das mal verglichen mit Bindways von Thredex selber und der, das kompliziert sieht ziemlich anders aus. Wir haben das halt mit sehr anderen Optionen kompelliert oder selber noch stark verändert. Was man aber auf jeden Fall noch gut sehen kann von dem Original-System sind Sachen wie Tasks und Threads wie Threads und Qs und sowas, die man sich alle auflisten lassen kann oder Mutechse. Das sind alles 1 zu 1 die primitive aussiedelnd Thredex-System die hier darin sind. Waren noch mehr Fragen? Hey, vielen Dank. Fahne ich etwas Interesse? Viel Spaß bei den Demos.