Ich habe das IDA Pro Buch noch nicht durch aber schon eine Frage zu IDA Pro, weil es mich nervt. Ich habe ein 1MB großes Image und die anfängliche Auto-Analyse hat schon einiges darin als Code identifiziert. Nun drücke ich seit ca. 1 Stunde "c" auf den "grünen" Berechen, sehe aber kein Land. Gibt es eine Möglichkeit einen Bereich zu markieren in dem IDA eine nicht-lineare Codesuche durchführt? Sprich versuch alles was dort liegt als Code umzuwandeln?
Nun 1MB ist schon eine Hausnummer, wenn du das als binär einliest hat IDA nicht sehr viel Infos. Du kannst aber jederzeit einen Bereich markieren und mit c assemblieren. ev vorher mit u unassemble machen. Das ist aber m. E. Der falsche Weg. Bau als erstes die Vectortabelle mit d auf. Markiere alle Vector calls als Funktionen mit f. Suche im Binary nach Strings und stelle diese mit s als Strings dar. Gib den Vector Calls sinnvolle Namen. Versuche Unterprogramme mit f zu markieren. Versuche herauszubekommen welcher Compiler benutzt wurde, und dann baue oder benutze endsprechende Flirt Tabellen. Nicht vergessen mach regelmäßig Kopien der Datenbank es gibt kein Undo! Thomas
Undo, ja, wie ist das denn mit der "Database snapshot"?
Olli Z. schrieb: > Undo, ja, wie ist das denn mit der "Database snapshot"? Das ist die Sicherung der Datenbank. IDA verändert nie die Daten. Was du machst ist immer nur die Sichtweise bzw Interpretation der Daten zu verändern. Es gibt einige Kommandos wo du Gefahr läufst diese Interpretation zu verlieren. Die Segment Operatoren fallen mir da in erster Linie ein. Deshalb die Sicherung. Thomas
Thomas Z. schrieb: > Nun 1MB ist schon eine Hausnummer, wenn du das als binär einliest hat > IDA nicht sehr viel Infos. Klar :-) > Du kannst aber jederzeit einen Bereich markieren und mit c assemblieren. ev vorher mit u unassemble machen. Ok! > Das ist aber m. E. Der falsche Weg. Bau als erstes die Vectortabelle mit > d auf. Markiere alle Vector calls als Funktionen mit f. Suche im Binary Vectortabelle habe ich, damit gehts ja überhaupt erst los. Das ist eine ARM7 MPU und hat 8 Einträge. Durch das 'c' an Pos 0x0000 0000 kam schon ein bischen was, aber noch lange nicht alles. Achja, mit "d" geht da nix, weil das ist doch das Gegenteil von "c", also data. Tippfehler von Dir? > nach Strings und stelle diese mit s als Strings dar. Gib den Vector Strings habe ich mit Subview Strings suchen lassen und ne Menge gefunden, leider auch viel False-Positives, also Schrott. Markiert IDA die dann nicht automatisch als Strings? > Calls sinnvolle Namen. Versuche Unterprogramme mit f zu markieren. Auch das macht IDA doch automatisch bei der Analyse? > Versuche herauszubekommen welcher Compiler benutzt wurde, und dann baue > oder benutze endsprechende Flirt Tabellen. DAS finde ich interessant. Wie könnte ich denn da dahinter kommen? In den Strings habe ich "C++ library exception" gefunden.
:
Bearbeitet durch User
Kapitel 12 im Ida Book (Seite 211 in der ersten Printausgabe) beschreibt Flirt. Das ist halt alles etwas x86 lastig genau wie alles bei IDA. Man merkt deutlich, dass das Teil aus x86 Ecke kommt. Ich bin mit ARM noch nicht so sattelfest, kann also nicht so genau beurteilen wie gut das Prozessor Modul ist. Es gab hier schon mal einen Tread wo es um ARM und IDA ging. (Motorcontroller für E Skooter) da hab ich das File mal aus Neugier in den IDA geladen. Das hat gar nicht so schlecht ausgeschaut waren aber nur 32k. Da der TO aber nicht willens oder fähig war notwendige Infos zu liefern, hab ich das nicht weiterverfolgt. Vielleicht kannst du anhand des Startupcodes (Reset Vector) einen Compiler identifizieren. Im Automotive Bereich würde ich als erstes Keil vermuten ev noch IAR. Beide Compiler gibt's als Demo. Der Startupcode sollte im Source vorliegen. Im Startup Code sollten zumindest Code zum initialisieren der globalen Var. erkennbar sein. Irgendwann sollte dann ein JMP nach main kommen. Der C++ String kommt von der Runtime Bibliothek. Wenn du die Stelle findest wo der String referenziert wird hast, zumindest schon mal Libcode gefunden. Thomas
Ich bin leider erst bei Kapitel 6. Und ja, es reizt immer das erlernte auszuprobieren, aber das muss ja schief gehen ;-) In anderen Firmwares konnte ich hinweise auf die compiler und zum Teil sogar lokale Sourcecodepfade lesen, hier in dieser FW eher nicht. Eine Referenz auf den Lin-String habe ich nicht gefunden. Zum Startup-Code: Du meinst also das das immer vorhanden und gleich ist? Also wenn ich eine leere main() compiliere für den MAC7116 das ich dann den gleichen Teil vorne weg hab? Klingt mir fast zu einfach und ich weiss ja auch nicht in welcher Version die FW compiliert wurde. Von der MPU her weiss ich das das Programm-Flash bei 0x0000 0000 startet und 1 MB groß ist. Das SRAM liegt ab 0x4000 0000 - 0x4000 C000 (48 kb). Der ganze IO Kram ab 0xFC00 0000. Der erste Vector geht in die Region vom Primary Bootloader ab 0x0000 1000 und da verliert sich dann seine Spur, spricht ich habe aufgrund der zahlreichen Verästelungen bislang keine Main ausfindig machen können. Ich denke ja immer das dies in erster Linie eine Serverloop sein müsste und aussenrum viel mit Timern und Interrupts passiert. Wie gesagt, die FW hat schon eine gewisse Komplexität...
Der Startupcode wird sich ganz erheblich unterscheiden. Zum einen verlangt c ja dass globale Variablen mit 0 initialisiert werden. Zusätzlich müssen Variablen die auf File Ebene mit einem Wert initialisiert werden auch vom startup behandelt werden. z.B. initialisierte Arrays. Es gibt sicher noch ein paar andere Dinge die mir im Moment nicht einfallen. Ob bei 1 MB noch eine simple Mainschleife da ist muss man schauen. Ich würde eher auf ein RTOS mit Tasks tippen. Als Versuch würde ich einfach mal ein durchaus komplexeren Programm compilieren und anschließend nach bin konvertieren. Wenn du das in IDA lädst und gegen das Mapfile und Lstfile vergleichst solltest du Zusammenhänge erkennen können. Thomas
Thomas Z. schrieb: > verlangt c ja dass globale Variablen mit 0 initialisiert werden. Meinst Du damit z.B. solche Subs?
1 | int sub_428C() |
2 | { |
3 | _DWORD *v0; // ST08_4 |
4 | int result; // r0 |
5 | _DWORD *v2; // r12 |
6 | _DWORD *v3; // r12 |
7 | _DWORD *v4; // r12 |
8 | |
9 | v0 = (_DWORD *)sub_43B0(); |
10 | result = sub_4574(); |
11 | *v0 = 0; |
12 | v0[1] = 0; |
13 | v0[2] = 0; |
14 | v0[3] = 0; |
15 | v2 = v0 + 4; |
16 | *v2 = 0; |
17 | v2[1] = 0; |
18 | v2[2] = 0; |
19 | v2[3] = 0; |
20 | v3 = v0 + 8; |
21 | *v3 = 0; |
22 | v3[1] = 0; |
23 | v3[2] = 0; |
24 | v3[3] = 0; |
25 | v4 = v0 + 12; |
26 | *v4 = 0; |
27 | v4[1] = 0; |
28 | v4[2] = 0; |
29 | v4[3] = 0; |
30 | v0[7] = 336; |
31 | v0[6] = 64; |
32 | v0[4] = 1; |
33 | v0[5] = result; |
34 | return result; |
35 | } |
36 | |
37 | int sub_4574() |
38 | { |
39 | return sub_3392(); |
40 | } |
41 | |
42 | void *sub_3392() |
43 | { |
44 | return &unk_4000BEFC; |
45 | } |
Ich bin den Bootloadercode jetzt einfach mal von Anfang an durchgegangen und recht früh finde ich einen solchen Aufruf. Dies ist Pseudo-Code von IDA, aber das sieht mir doch sehr nach Initialisierung aus. Hier noch der Rest vom Anfang des Bootloader codes:
1 | ROM:00000000 B loc_1018 |
2 | ... |
3 | ROM:00001018 loc_1018 |
4 | ROM:00001018 LDR R0, =unk_4000BEFC |
5 | ROM:0000101C MSR CPSR_c, #0xD2 |
6 | ROM:00001020 SUB SP, R0, #0x100 |
7 | ROM:00001024 MSR CPSR_c, #0x5F ; '_' |
8 | ROM:00001028 B loc_3E98 |
9 | ... |
10 | ROM:00003E98 BL nullsub_4 |
11 | ROM:00003E9C BL sub_428C |
12 | ... |
13 | ROM:000040C4 nullsub_4 |
14 | ROM:000040C4 BX LR |
15 | ... |
16 | |
17 | RAM:4000BEFC unk_4000BEFC % 1 ; DATA XREF: ROM:loc_1018↑o |
18 | RAM:4000BEFC ; ROM:off_102C↑o ... |
Bei loc_1018 wird der Stackpointer für den Interrupt-Modus initiallisiert. Also der ARM wird in den Interrupt-Modus geschaltet, dann der Stackpointer gesetzt (Stackgröße: 256 Einträge), dann in den System-Mode geschaltet. nullsub_4 ist vielleicht irgendwas wegoptimiertes. Springt rein und wieder raus. Oder es soll die Instruction Pipeline oder den Cache neu füllen (reiner Spekulatius ;))? das Pseudo-C: sub_43B0 macht irgendwas und gibt einen DWord-Pointer auf irgend eine Strucktur zurück, deren Inhalt initalisiert wird. sub_4574 gibt wahrscheinlich die Basisadresse des Interrupt-Stack zurück. Für die globale Init sieht das aber zu klein aus. Fröhliches Reversen und guten Jump ins neue Jahr :D
Ihr koennt euch auch einfach mal Ghidra angucken ;) Ghidra: https://ghidra-sre.org/ Ghidra: NSA stellt quelloffenes Software-Analyse-Tool vor https://www.heise.de/newsticker/meldung/Ghidra-NSA-stellt-quelloffenes-Software-Analyse-Tool-vor-4327737.html
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.