NationalSecurityAgency / ghidra

Ghidra is a software reverse engineering (SRE) framework
https://www.nsa.gov/ghidra
Apache License 2.0
51.31k stars 5.84k forks source link

Debugger not working for embedded ARM Cortex-M3 target #3333

Closed maxgerhardt closed 3 years ago

maxgerhardt commented 3 years ago

Describe the bug

When setting up Ghidra's new debugger to work with gdb-multiarch connected to a GDB server opened by Renode (used as an ARM emulator here), debugging does not work correctly in the sense that:

To Reproduce Steps to reproduce the behavior:

  1. Use the repo at https://github.com/maxgerhardt/ghidra-test-fw to download or compile the test firmware and the instructions on how to start Renode (+ its GDB server). The firmware is a simple Arduino-sketch for a STM32F103C8 ("Bluepill") that prints "Hello, world" twice a second via UART2.
  2. Create a new Ghidra project, import the ELF file, override the detected architecture as the "Cortex" one, little endian (not ARMv8! Cortex-M3 is a ARMv7-M)
  3. Open the firmware in Ghidra's debugger
  4. Let it analyze the firmware
  5. Have gdb-multiarch installed (sudo apt install gdb-multiarch on Ubuntu)
  6. Start a new debug connection as "IN-VM GNU gdb local debugger", set "GDB launch command" to /usr/bin/gdb-multiarch
  7. Go to the interpreter window to be able to type GDB commands
  8. Execute initialization and connect commands (renode is running in the background) as
    set architecture arm
    set endian little
    set arm fallback-mode thumb
    set arm force-mode thumb
    set style enabled off
    file /home/max/ghidra-test-fw/.pio/build/genericSTM32F103C8/firmware.elf
    target remote :3333

    (adapt path to firmware.elfas needed)

  9. Observe state of debugger, empty "Dynamic view"

Expected behavior The dynamic view is not empty and shows stuff.

Screenshots

grafik

Attachments

Needed firmware.elf and other instructions are in linked repo.

Environment (please complete the following information):

Additional context

Similiar problems are reported in https://github.com/NationalSecurityAgency/ghidra/issues/3169 and possibly https://github.com/NationalSecurityAgency/ghidra/issues/2859. The code that prints the "Could not list regions" was added in https://github.com/NationalSecurityAgency/ghidra/commit/270c0b65a20bad68591398961cb351c845a5179d.

The README page at https://github.com/bootleg/ret-sync#embedded-devices-and-missing-procpidmaps also talks about the PID error.

Someone at https://wrongbaud.github.io/posts/ghidra-debugger/ seems to have gotten the debugger to work with an ARM target but no screenshot is shown of what the dynamic view looks like.

d-millar commented 3 years ago

@maxgerhardt Thanks for the detailed information - will try to recreate your error and give you more specifics this week, but in the meantime wanted to give you some possible solutions. For starters, as near as I can tell, everything you've done so far is correct - nicely done. I think the one missing piece is the mapping from firmware.elf to a region. Normally (i.e. user-mode Linux applications), the debugger gets the list of modules and their base addresses using "maintenance info sections ALLOBJ". It then tries to match the name of the program being analyzed in the Static disassembly to the corresponding entry in Modules and rebases accordingly. If it can't, the user can establish this mapping by hand in the Debug Console or the Modules window.

In your case, am guessing this command is meaningless/unsupported, and you have no entries in the Modules window at all. The workaround is to write/run a small gdb script to define that command. We have the same problem for "info proc mappings", although 10.0.2 at least attempts to fake it if this command isn't supported. Let me know if this doesn't make sense or doesn't get you a Dynamic listing.

d-millar commented 3 years ago

Oh, and the breakpoints issue probably stems from the same problem, i.e. the debugger doesn’t know how to apply the breakpoint to the real address space because it’s unable to map the program to its loaded address

maxgerhardt commented 3 years ago

Many thanks for the quick reply and initial thoughts.

In your case, am guessing this command is meaningless/unsupported, and you have no entries in the Modules window at all

Correct, "Modules" is empty.

grafik

And in fact when I try the command

info proc mappings

It gives out the same error message as it also does whenever executing a single-step in the debugger:

(gdb)info proc mappings
Can't determine the current process's PID: you must name one.

However when I go into Window -> Memory map, it well knows about the memory map structure

grafik

The memory map for the microcontroller (STM32F103C8) is really simple, in this case really only the flash memory (at 0x8000000, size 64 kByte) and RAM (at 0x2000000, size 20kByte) is important.

I'd love to tell Ghidra about this memory mapping again in the modules, but there's no "Add Module definition" button in the Modules tab that I see. Do you have a pointer to a script, or a skeleton thereof, that I could work on to add this information? Or would the debug console way (do you mean GDB here? The "Debug Console" tab is just a log Window in Ghidra) be better?

d-millar commented 3 years ago

Talking with @nsadeveloper789 today, I think there are two ways to do this, but am having trouble figuring one out myself so will wait until I get more info from him before describing how to do that. The other way is to define "maintenance info sections ALLOBJ" (and maybe actually "info proc mappings"). We have a sample for the latter in the distribution - look for the file "define_info_proc_mappings". It basically tells gdb what to produce for that command, so that, when the debugger executes it, you get a result. After starting up your target, just "source define_info_proc_mappings" (with the path) in the Interpreter window. You'll want to do the same for the former, i.e. "source define_maintenance" or whatever you call your script. The format is basically:

Object file: /path_to/firmware.elf 0x2000000->0x2004000 at 0x2000000: RAM ALLOC READ_WRITE 0x8000000->08010000 at 0x8000000: flash ALLOC READ_ONLY

I think - I haven't looked at this in a while - so you're script will basically "echo" those values. Yell, if this doesn't make sense. (Also, there's a bit more discussion in the the GitHub "Debugger" Discussions channel.)

maxgerhardt commented 3 years ago

I found that in GDB the command maintenance info sections already contains goodlooking output after I load the ELF file in:

 (gdb)maintenance info sections
Exec file:
     `/home/max/firmware_test/.pio/build/genericSTM32F103C8/firmware.elf', file type elf32-littlearm.
  [0]      0x8000000->0x800010c at 0x00010000: .isr_vector ALLOC LOAD READONLY DATA HAS_CONTENTS
  [1]      0x800010c->0x8001fc4 at 0x0001010c: .text ALLOC LOAD READONLY CODE HAS_CONTENTS
  [2]      0x8001fc4->0x80022fc at 0x00011fc4: .rodata ALLOC LOAD READONLY DATA HAS_CONTENTS
  [3]      0x80022fc->0x80022fc at 0x00020074: .ARM.extab HAS_CONTENTS
  [4]      0x80022fc->0x80022fc at 0x00020074: .ARM HAS_CONTENTS
  [5]      0x80022fc->0x80022fc at 0x00020074: .preinit_array ALLOC LOAD DATA HAS_CONTENTS
  [6]      0x80022fc->0x800230c at 0x000122fc: .init_array ALLOC LOAD DATA HAS_CONTENTS
  [7]      0x800230c->0x8002314 at 0x0001230c: .fini_array ALLOC LOAD DATA HAS_CONTENTS
  [8]      0x20000000->0x20000074 at 0x00020000: .data ALLOC LOAD DATA HAS_CONTENTS
  [9]      0x20000074->0x20000314 at 0x00020074: .bss ALLOC
  [10]     0x20000314->0x20000314 at 0x00020074: .noinit HAS_CONTENTS
  [11]     0x20000314->0x20000918 at 0x00020314: ._user_heap_stack ALLOC
  [12]     0x0000->0x0029 at 0x00020074: .ARM.attributes READONLY HAS_CONTENTS
  [13]     0x0000->0x4f4fb at 0x0002009d: .debug_info READONLY HAS_CONTENTS
  [14]     0x0000->0x9210 at 0x0006f598: .debug_abbrev READONLY HAS_CONTENTS
  [15]     0x0000->0x1420 at 0x000787a8: .debug_aranges READONLY HAS_CONTENTS
  [16]     0x0000->0x25d06 at 0x00079bc8: .debug_macro READONLY HAS_CONTENTS
  [17]     0x0000->0x26771 at 0x0009f8ce: .debug_line READONLY HAS_CONTENTS
  [18]     0x0000->0xad16f at 0x000c603f: .debug_str READONLY HAS_CONTENTS
  [19]     0x0000->0x0066 at 0x001731ae: .comment READONLY HAS_CONTENTS
  [20]     0x0000->0x22e0 at 0x00173218: .debug_ranges READONLY HAS_CONTENTS
  [21]     0x0000->0x1382f at 0x001754f8: .debug_loc READONLY HAS_CONTENTS
  [22]     0x0000->0x3e34 at 0x00188d28: .debug_frame READONLY HAS_CONTENTS

So I did not override that (it also gave me a Error in sourced command file: "maintenance info sections" is not a prefix command. error when I tried). I created a script /home/max/define_info_proc_mappings with contents

define info proc mappings
echo 0x0 0xFFFFFFFF 0x100000000 0x0 mem \n
end

aka, a very generic full 32-bit address space mapping, and added the command source /home/max/define_info_proc_mappings in the initialization commands.

Now the dynamic view is not empty anymore, but still doesn't look correct:

grafik

The "Modules" tab is still empty, but the the dynamic view indeed syncs to the PC, which is 0x8000024c at the moment, but the instruction there is not "swilt 0x4770". When I consult GDB it says

 (gdb)x/10i $pc
=> 0x800024c <HAL_GetTick+4>:   bx  lr
    0x800024e <HAL_GetTick+6>:  nop
    0x8000250 <HAL_GetTick+8>:  lsls    r0, r0, #12

which is also what it says inthe firmware.elf listing. I looks like it misinterprets the opcodes to be for a different ARM architecture, when looking at the decoder https://armconverter.com/?disasm&code=70%0947%0900%09bf%09 it says

grafik

I did notice a mistake in my initial GDB comments regarding

set architecture arm

after looking at the set architecture command I realized there is the more fitting armv7 (=ARMv7) target (ARMv7E-M is a Cortex-M4 and thus not fitting for an M3, and ARMv7-M isn't there), so I changed it to

set architecture armv7

but it still didn't make a difference.

The "language" of the ELF file in Ghidra is set to "Cortex, Little Endian". If I re-import the ELF file as "ARMv7 little endian" the disassembly of the code looks still correct but is still exactly as broken as before in the dynamic view.

I think this is very close to being solved if that architecture problem is resolved.

maxgerhardt commented 3 years ago

I also just noticed that in the screenshot I posted, the debug console says

Selected first mapping offer: <Offer: 'GDB on Linux arm' lang=ARM:LE:32:v8 cs=default confidence=100 target=Inferiors[1]> [] Tue Aug 17 02:05:27 CEST 2021

..which is wrong. It's not ARMv8, it's a ARMv7-M in thumb mode, not ARM mode.

EDIT:

Using arm-none-eabi-gdb of the newest version (10.3-2021) instead of gdb-multiarch leads to Ghidra not even being able to load the registeres (empty tab, they are filled in gdb-multiarch), with the dynamic view being empty again.

d-millar commented 3 years ago

Ah, excellent - definite progress. I don't know how to fix the arm/thumb issue off the top of my head. Has something to do with setting the contact register, but someone on the team will. Will get you an answer tomorrow!

d-millar commented 3 years ago

OK, @nsadeveloper789 confirms that the Dynamic view "should" be reading the cpsr register and using the fifth bit (0x20) to determine whether you'e in thumb/arm mode. So, a couple of possibilities - first, there's some chance the debugger isn't reading that register (i.e. it's not in its set of default registers to be read) or it's misreading the registers (the set it believes it's using doesn't match the returned register set from this gdb stub), or gdb is actually just faking this register. I would start by checking what's in the Register view and what's reported by "info registers". You can override this by right-clicking on the disassembly and telling it to disassemble as thumb, but doing this everywhere would probably be a drag. @nsadeveloper789 notes we may not have tested this completely :(

maxgerhardt commented 3 years ago

Reading up on https://www.keil.com/support/man/docs/armasm/armasm_dom1359731139098.htm

The CPSR is not present in ARMv6-M and ARMv7-M processors.

So Cortex-M3 of the ARMv7-M architecture doesn't even have a CPSR.

Further reading up https://www.eecs.umich.edu/courses/eecs373/labs/refs/M3%20Guide.pdf chapter 1.4

Focused on small memory system devices such as microcontrollers and reducing the size of the proces- sor, the Cortex-M3 supports only the Thumb-2 (and traditional Thumb) instruction set.

So actually the ARM instruction set isn't even an option my Cortex-M3 and it's always either Thumb or Thumb-2.

And further reading https://www.keil.com/pack/doc/cmsis/Core/html/group__Core__Register__gr.html#ga732e08184154f44a617963cc65ff95bd

Read the xPSR register. .. T (xPSR[24]) (Thumb bit) =1 Indicates that that the processor is in Thumb state. =0 Attempting to execute instructions when the T bit is 0 results in a fault or lockup.

Reading out the registers in gdb-multiarch within Ghidra gives

(gdb)i r
r0             0x57b7              22455
 r1             0x28                40
 r2             0x20000318          536871704
 r3             0x20000300          536871680
 r4             0x1f4               500
 r5             0x55f0              22000
 r6             0x0                 0
 r7             0x0                 0
 r8             0x0                 0
 r9             0x0                 0
 r10            0x0                 0
 r11            0x0                 0
 r12            0x0                 0
 sp             0x20004fc8          0x20004fc8
 lr             0x8001c6b           134225003
 pc             0x800024c           0x800024c <HAL_GetTick+4>
 xpsr           0x192               402
 msp            0x0                 0
 psp            0x0                 0
 primask        0x0                 0
 basepri        0x0                 0
 faultmask      0x0                 0
 control        0x0                 0

In Ghidra's register view, there is no xPSR register, and cpsr is 0. Also, the "Debug Console" shows the error message "Mapper's extra register 'cpsr' is not mappable!"

grafik

It seems that Ghidra doesn't properly know about the Cortex-M3's ARMv7-M architecture? But it could disassemble the firmware just fine. The language ID of the firmware.elf is set to ARM:LE:32:Cortex (1.103), as previously said.

In IDA the ARM architecture settings are much more granular

grafik

but in Ghidra the only applicable architectures I see are the generic Cortex and ARMv7, both of which behave the same in regards to above.

Edit: Right-clicking in the Dynamic view and going "Set Register Values", then settings CPSR to 0xffffffff and "TMode" to 1 does not make a difference in the disassembly. The "Listing: firmware.elf" view is already correct.

d-millar commented 3 years ago

OK, have talked to the team, and I think I understand what's going on. Definitely, some bugs to fix on our end....

The Static listing is driven by the architecture assigned when you loaded the firmware image, and, as you've noted, that seems to be doing the right thing. The debugger tries to pick an architecture based on the currently mapped image for the Dynamic listing. In this case, we've picked Arm but it looks like the debugger's interpretation of Arm is a little overly broad. The register list presented is some flavor of an intersection between the registers reported by gdb and the architecture in the listing. This seems like a mistake or at least needs refinement. Registers not in the gdb set are reported as unmappable, which causes the message you're seeing in the Debug Console. That admittedly is not much of a clue. We really need to tell the user pretty explicitly there's a mismatch between gdb and the static architecture.

One thing that would help us if you're game, can you tell us what "show arch" reports for you? If there's sufficient information there, we can use that to do something more sane in the Dynamic view. Will also talk with the team re ARM variants. As you can tell, I am not the architecture guy. Would be nice to know if Cortex in the language model always maps to Thumb-only or if there are variants with Arm. Perhaps, we need another choice in the language model set, although obviously the main Ghidra engine knows how to do that right thing.

Once we have a fix, we can incorporate it into the next patch cycle. If you would like an interim solution, we may also be able to get you the appropriate patches as source or binary. How comfortable are you with operating in the developer mode for Ghidra and/or replacing class files in a Java archive?

maxgerhardt commented 3 years ago

One thing that would help us if you're game, can you tell us what "show arch" reports for you? If there's sufficient information there, we can use that to do something more sane in the Dynamic view.

When using gdb-multiarch and my startup commands,

set architecture armv7
set endian little
set arm fallback-mode thumb
set arm force-mode thumb
set style enabled off
source /home/max/define_info_proc_mappings

file /home/max/firmware_test/.pio/build/genericSTM32F103C8/firmware.elf
target remote :3333

the command will just echo back what I've previously set

 (gdb)show arch
The target architecture is set to "armv7".

I have to set it in gdb-multiarch since there's a bazillion of them

 (gdb)set arch
Requires an argument. Valid arguments are i386, i386:x86-64, i386:x64-32, i8086, i386:intel, i386:x86-64:intel, i386:x64-32:intel, aarch64, aarch64:ilp32, aarch64:armv8-r, arm, armv2, armv2a, armv3, armv3m, armv4, armv4t, armv5, armv5t, armv5te, xscale, ep9312, iwmmxt, iwmmxt2, armv5tej, armv6, armv6kz, armv6t2, armv6k, armv7, armv6-m, armv6s-m, armv7e-m, armv8-a, armv8-r, armv8-m.base, armv8-m.main, armv8.1-m.main, arm_any, alpha, alpha:ev4, alpha:ev5, alpha:ev6, hppa1.0, ia64-elf64, ia64-elf32, m68k, m68k:68000, m68k:68008, m68k:68010, m68k:68020, m68k:68030, m68k:68040, m68k:68060, m68k:cpu32, m68k:fido, m68k:isa-a:nodiv, m68k:isa-a, m68k:isa-a:mac, m68k:isa-a:emac, m68k:isa-aplus, m68k:isa-aplus:mac, m68k:isa-aplus:emac, m68k:isa-b:nousp, m68k:isa-b:nousp:mac, m68k:isa-b:nousp:emac, m68k:isa-b, m68k:isa-b:mac, m68k:isa-b:emac, m68k:isa-b:float, m68k:isa-b:float:mac, m68k:isa-b:float:emac, m68k:isa-c, m68k:isa-c:mac, m68k:isa-c:emac, m68k:isa-c:nodiv, m68k:isa-c:nodiv:mac, m68k:isa-c:nodiv:emac, m68k:5200, m68k:5206e, m68k:5307, m68k:5407, m68k:528x, m68k:521x, m68k:5249, m68k:547x, m68k:548x, m68k:cfv4e, mips, mips:3000, mips:3900, mips:4000, mips:4010, mips:4100, mips:4111, mips:4120, mips:4300, mips:4400, mips:4600, mips:4650, mips:5000, mips:5400, mips:5500, mips:5900, mips:6000, mips:7000, mips:8000, mips:9000, mips:10000, mips:12000, mips:14000, mips:16000, mips:16, mips:mips5, mips:isa32, mips:isa32r2, mips:isa32r3, mips:isa32r5, mips:isa32r6, mips:isa64, mips:isa64r2, mips:isa64r3, mips:isa64r5, mips:isa64r6, mips:sb1, mips:loongson_2e, mips:loongson_2f, mips:gs464, mips:gs464e, mips:gs264e, mips:octeon, mips:octeon+, mips:octeon2, mips:octeon3, mips:xlr, mips:interaptiv-mr2, mips:micromips, rs6000:6000, rs6000:rs1, rs6000:rsc, rs6000:rs2, powerpc:common64, powerpc:common, powerpc:603, powerpc:EC603e, powerpc:604, powerpc:403, powerpc:601, powerpc:620, powerpc:630, powerpc:a35, powerpc:rs64ii, powerpc:rs64iii, powerpc:7400, powerpc:e500, powerpc:e500mc, powerpc:e500mc64, powerpc:MPC8XX, powerpc:750, powerpc:titan, powerpc:vle, powerpc:e5500, powerpc:e6500, riscv, riscv:rv64, riscv:rv32, s390:64-bit, s390:31-bit, sh, sh2, sh2e, sh-dsp, sh3, sh3-nommu, sh3-dsp, sh3e, sh4, sh4a, sh4al-dsp, sh4-nofpu, sh4-nommu-nofpu, sh4a-nofpu, sh2a, sh2a-nofpu, sh2a-nofpu-or-sh4-nommu-nofpu, sh2a-nofpu-or-sh3-nommu, sh2a-or-sh4, sh2a-or-sh3e, sparc, sparc:sparclet, sparc:sparclite, sparc:v8plus, sparc:v8plusa, sparc:sparclite_le, sparc:v9, sparc:v9a, sparc:v8plusb, sparc:v9b, sparc:v8plusc, sparc:v9c, sparc:v8plusd, sparc:v9d, sparc:v8pluse, sparc:v9e, sparc:v8plusv, sparc:v9v, sparc:v8plusm, sparc:v9m, sparc:v8plusm8, sparc:v9m8, m32r, m32rx, m32r2, auto.

When I'm using arm-none-eabi-gdb, which was my first logical choice, with the startup commands

set style enabled off
source /home/max/define_info_proc_mappings

file /home/max/firmware_test/.pio/build/genericSTM32F103C8/firmware.elf
target remote :3333

Then it says

 (gdb)show arch
The target architecture is set to "auto" (currently "armv7").

So sadly not very detailed. Again, arm-none-eabi-gdb + Ghidra seems to be more broken than with gdb-multiarch, since the "Regsters" view is completely empty in Ghidra.

grafik

it however looks like it returns the same set of registers than gdb-multiarch did. (possibly because this is controlled by the Renode GDB-server and not the GDB client?)

 (gdb)i r
r0             0x40                64
 r1             0x40004400          1073759232
 r2             0x1                 1
 r3             0xe000e100          3758153984
 r4             0x200001e0          536871392
 r5             0x20000338          536871736
 r6             0x10                16
 r7             0x20000338          536871736
 r8             0x10                16
 r9             0x20000274          536871540
 r10            0x0                 0
 r11            0x0                 0
 r12            0x0                 0
 sp             0x20004f68          0x20004f68
 lr             0xfffffff9          4294967289
 pc             0x8001410           0x8001410 <USART2_IRQHandler>
 xpsr           0x192               402
 msp            0x0                 0
 psp            0x0                 0
 primask        0x0                 0
 basepri        0x0                 0
 faultmask      0x0                 0
 control        0x0                 0

Would be nice to know if Cortex in the language model always maps to Thumb-only or if there are variants with Arm.

I think "Cortex" is too general as a language-model, I read at https://en.wikipedia.org/wiki/ARM_architecture#Thumb-2

All ARMv7 chips support the Thumb instruction set. All chips in the Cortex-A series, Cortex-R series, and ARM11 series support both "ARM instruction set state" and "Thumb instruction set state", while chips in the Cortex-M series support only the Thumb instruction set.

So within ARMv7, depending on whether it's a ARMv7-M or ARMv7-A or ARMv7-R, there are already these differences. Then there's Armv7E-M which is for a Cortex-M4 (has a DSP chip compared to a Cortex-M3).

Once we have a fix, we can incorporate it into the next patch cycle. If you would like an interim solution, we may also be able to get you the appropriate patches as source or binary. How comfortable are you with operating in the developer mode for Ghidra and/or replacing class files in a Java archive?

I can comfortably build Ghidra from source using https://github.com/dukebarman/ghidra-builder, that has worked for me in the past. I'm not in a rush to get a fix in the next 24 hours or something, so if it is fixed cleanly new Ghidra commits, I should be able build and test that.

d-millar commented 3 years ago

Apologies, I realized after I sent the last that you had already provided the information we needed. Didn't mean to make extra work for you. I think we've isolated the base problem and will try to get a fix out to you ASAP. If you look in ghidra.app.plugin.core.debug.platform, you'll see that the GdbArmDebuggerMappingOpinion is woefully incomplete. OffersForEnv is returning the Linux LE ARM offer for any architecture that begins with "arm" - obviously not good in your case. There's some chance that just adding a clause for "armv7" would solve the problem, but would like to actually test that. The language model for ARM:LE:Cortex apparently knows enough to start in Thumb mode, which is why the Static listing has good disassembly, but I think we need more complete logic to process the existence/non-existence of cpsr, the behavior for xpsr, et cetera.

Will let you know when we have something in place, although, of course, feel free to experiment in the meantime!

d-millar commented 3 years ago

@maxgerhardt Also, wanted to let you know I've used your instructions to duplicate your set-up - am (of course) seeing just what you're seeing, so with luck will be able to test our solution against your config.

nsadeveloper789 commented 3 years ago

I believe we have the relevant fixes merged into our patch branch, scheduled for 10.0.3. Not sure when they'll get pushed out, though. First, we refined our logic for selecting Ghidra languages based on GDB-reported architectures, particularly in the ARM family. Unfortunately, our languages do not distinguish variants within Cortex, so Ghidra still presents the cpsr.... So, second, we added a heuristic to our ARM/THUMB selection logic: If cpsr is absent on GDB's side, i.e., it displays in grey on Ghidra's side, we assume THUMB mode. Third, though I don't know if you need this, we added a "Map Identically" button, which absent a module list, should sync your static and dynamic listing cursors, assuming no relocation.

maxgerhardt commented 3 years ago

I've used the ghidra-builder (with a fix) to build me the current patch branch, commit dd277a91fe385f507b8cbe1cc9da443c943573d2, that gave me a ghidra_10.0.3_DEV_20210824_linux64.zip. I've unzipped it, started Ghidra from it, created a new project, reimportant the firmware.elf as "Cortex:little", let it be analayzed and started the debugger.

In the GDB startup commands I left out the script defining info proc mappings. This gets me to

grafik

Still an empty module window. I didn't find a "Map Identically" button, could you point me to where that is?

So then I restarted the session but this time including the info proc script and got

grafik

So it's still doing the Thumb decoding in a wrong way. I wonder if that's due to how I set up the proc mapping (script was posted above) :/

EDIT: The "Debug Console" still contains the same

Selected first mapping offer: <Offer: 'GDB on Linux arm' lang=ARM:LE:32:v8 cs=default confidence=100 target=Inferiors[1]> [] Wed Aug 25 00:54:52 CEST 2021

Message as before.

d-millar commented 3 years ago

will verify today, but I don’t think the relevant changes have been pushed to patch yet

ryanmkurtz commented 3 years ago

Sorry for the confusion. GitHub is a mirrored repo for us. The changes are only in our internal repo at the moment. When we sync up GitHub, you'll notice that this issue gets closed and the commit that fixed it will be linked in.

maxgerhardt commented 3 years ago

With the new version this now works. One just has to remember to use a define_info_proc_mappings script to override info proc mappings and use the new "Map identical" button, then the dynamic view and decompilation view are correct. Thanks to everyone involved!

grafik

I still have issues like the debugger step into/over buttons not working correctly (execution never pauses again) or only the top function of a stacktrace being selectible, but those will go into separate issues.

d-millar commented 3 years ago

@maxgerhardt Glad things are working better! I was able to duplicate your set-up and also noted that single-step and step-over were not working correctly. However, they don’t appear to be working correctly for gdb in general. I’d be interested in your thoughts on this - would like to see you get a functional solution.

maxgerhardt commented 3 years ago

I think it has something to do with Renode and/or gdb-multiarch, basic stepi instructions in the GDB console are also not working.. Breaking at functions however with e.g. b loop and continue works better. I'll need to check wether that occurrs with just gdb-multiarch or arm-none-eabi-gdb too.

The blog posted I linked above also says this

Note: If you are remotely debugging using gdb-multiarch and are finding that some breakpoints aren’t being hit - try using the stepi command instead of c. This is an issues that I’ve seen in mGBA before and does not have anything to do with Ghidra’s GDB server.