2017-09-01 4 views
3

Ich habe ein binäres Firmware-Image für ARM Cortex M, von dem ich weiß, dass es bei 0x20000000 geladen werden sollte. Ich möchte es in ein Format konvertieren, das ich für Assembly-Level-Debugging mit gdb verwenden kann, was bedeutet, dass ich in eine .elf konvertieren möchte. Aber ich konnte nicht herausfinden, wie ich dem .elf genügend Metadaten hinzufügen kann, damit dies geschieht. Hier ist, was ich bisher versucht habe.Wie konvertiere ich einen binären Firmware-Dump in ein .elf-Debugging für Assembler?

arm-none-eabi-objcopy -I binary -O elf32-littlearm --set-section-flags \ 
    .data=alloc,contents,load,readonly \ 
    --change-section-address .data=0x20000000 efr32.bin efr32.elf 

efr32.elf:  file format elf32-little 
efr32.elf 
architecture: UNKNOWN!, flags 0x00000010: 
HAS_SYMS 
start address 0x00000000 

Sections: 
Idx Name   Size  VMA  LMA  File off Algn 
    0 .data   00000168 20000000 20000000 00000034 2**0 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 
SYMBOL TABLE: 
20000000 l d .data 00000000 .data 
20000000 g  .data 00000000 _binary_efr32_bin_start 
20000168 g  .data 00000000 _binary_efr32_bin_end 
00000168 g  *ABS* 00000000 _binary_efr32_bin_size 

Muss ich mit der Konvertierung der Binärdatei in .o beginnen und ein einfaches Linker-Skript schreiben? Soll ich dem Befehl objcopy eine Architekturoption hinzufügen?

+1

Es gibt objcopy Möglichkeiten, dies zu tun, aber Sie benötigen eine feste Länge Befehlssatz, Daumen ohne Daumen2 (obwohl das wahrscheinlich nicht mit Gnu arbeiten), Arm ohne Daumen, Mips nur 32 Bit (ohne 16-Bit-Anweisungen), nicht x86 , nicht eine Anzahl von anderen. –

Antwort

3

Ein kleines Experiment ...

58: 480a  ldr r0, [pc, #40] ; (84 <spi_write_byte+0x38>) 
    5a: bf08  it eq 
    5c: 4809  ldreq r0, [pc, #36] ; (84 <spi_write_byte+0x38>) 
    5e: f04f 01ff mov.w r1, #255 ; 0xff 

müssen Sie nicht, dass natürlich haben, aber Sie können die binären und tun dies mit ihm lesen:

.thumb 
.globl _start 
_start: 
.inst.n 0x480a 
.inst.n 0xbf08 
.inst.n 0x4809 
.inst.n 0xf04f 
.inst.n 0x01ff 

dann sehen, was passiert.

arm-none-eabi-as test.s -o test.o 
arm-none-eabi-ld -Ttext=0x58 test.o -o test.elf 
arm-none-eabi-objdump -D test.elf 

test.elf:  file format elf32-littlearm 


Disassembly of section .text: 

00000058 <_start>: 
    58: 480a  ldr r0, [pc, #40] ; (84 <_start+0x2c>) 
    5a: bf08  it eq 
    5c: 4809  ldreq r0, [pc, #36] ; (84 <_start+0x2c>) 
    5e: f04f 01ff mov.w r1, #255 ; 0xff 

aber die Realität ist es nicht funktionieren ... wenn diese binäre keine thumb2 Erweiterungen hat es funktioniert isnt gehen, man kann Befehle mit variabler Länge linear auseinander. Sie müssen in der Reihenfolge der Ausführung mit ihnen umgehen. Also, dies zu tun richtig müssen Sie einen dissassembler schreiben, die den Code in Ausführungsreihenfolge geht durch, die Bestimmung der Anweisungen, die Sie herausfinden können, markieren Sie sie als Befehle ...

80: d1e8  bne.n 54 <spi_write_byte+0x8> 
    82: bd70  pop {r4, r5, r6, pc} 
    84: 40005200 
    88: F7FF4000 
    8c: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} 
    90: 4887  ldr r0, [pc, #540] ; (2b0 <notmain+0x224>) 
.thumb 
.globl _start 
_start: 
.inst.n 0xd1e8 
.inst.n 0xbd70 
.inst.n 0x5200 
.inst.n 0x4000 
.inst.n 0x4000 
.inst.n 0xF7FF 
.inst.n 0xe92d 
.inst.n 0x41f0 
.inst.n 0x4887 

    80: d1e8  bne.n 54 <_start-0x2c> 
    82: bd70  pop {r4, r5, r6, pc} 
    84: 5200  strh r0, [r0, r0] 
    86: 4000  ands r0, r0 
    88: 4000  ands r0, r0 
    8a: f7ff e92d   ; <UNDEFINED> instruction: 0xf7ffe92d 
    8e: 41f0  rors r0, r6 
    90: 4887  ldr r0, [pc, #540] ; (2b0 <_start+0x230>) 

es wird sich erholen, und brechen und erholen

Stattdessen müssen Sie einen Disassembler schreiben, der durch den Code geht (muss nicht unbedingt in die Assemblersprache zerlegt werden, aber genug, um den Code zu durchlaufen und alle möglichen Verzweigungspfade zu durchlaufen). Alle Daten, die nicht als Anweisungen bestimmt sind, werden als Anweisungen markiert

.thumb 
.globl _start 
_start: 
.inst.n 0xd1e8 
.inst.n 0xbd70 
.word 0x40005200 
.word 0xF7FF4000 
.inst.n 0xe92d 
.inst.n 0x41f0 
.inst.n 0x4887 

00000080 <_start>: 
    80: d1e8  bne.n 54 <_start-0x2c> 
    82: bd70  pop {r4, r5, r6, pc} 
    84: 40005200 andmi r5, r0, r0, lsl #4 
    88: f7ff4000   ; <UNDEFINED> instruction: 0xf7ff4000 
    8c: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} 
    90: 4887  ldr r0, [pc, #540] ; (2b0 <_start+0x230>) 

und unsere stmdb-Anweisung ist nun korrekt.

viel Glück.

+0

Welche objdump-Optionen haben Sie verwendet, um die .inst.n-Zeilen anzuzeigen? – joeforker

+0

diese wurden von Hand in diesem Fall erstellt, würden Sie ein Werkzeug schreiben, das die Binärdatei liest und eine Datei so erstellt. –

+0

Beachten Sie, dass ich gezeigt habe, dass, obwohl ich sagte, es war eine Daumen-Anweisung inst.n, wenn ich die thumb2 Extensions anstelle von einem 32-Bit-inst.w als zwei 16-Bit-inst.w in den Disassembler dachte, es war ein Daumen2. .. –

Verwandte Themen