Forum: PC Hard- und Software IDA Pro nach Autoanalyse weiteren Code finden lassen


von Olli Z. (z80freak)


Lesenswert?

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?

von Thomas Z. (usbman)


Lesenswert?

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

von Olli Z. (z80freak)


Lesenswert?

Undo, ja, wie ist das denn mit der "Database snapshot"?

von Thomas Z. (usbman)


Lesenswert?

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

von Olli Z. (z80freak)


Lesenswert?

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
von Thomas Z. (usbman)


Lesenswert?

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

von Olli Z. (z80freak)


Lesenswert?

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...

von Thomas Z. (usbman)


Lesenswert?

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

von Olli Z. (z80freak)


Lesenswert?

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 ...

von . . (Gast)


Lesenswert?

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

von Kaj (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.