Nalen98 / GhidraEmu

Native Pcode emulator
MIT License
279 stars 20 forks source link

V850 discussion #6

Open brainstorm opened 1 year ago

brainstorm commented 1 year ago

Running Ghidra 10.3 from HEAD. The example binary I'm testing this with is this V850 blob

After "Start emulation here", I step once and get the following:

Cannot invoke "ghidra.app.plugin.core.colorizer.ColorizingService.clearBackgroundColor(ghidra.program.model.address.Address, ghidra.program.model.address.Address)" because "service" is null
java.lang.NullPointerException: Cannot invoke "ghidra.app.plugin.core.colorizer.ColorizingService.clearBackgroundColor(ghidra.program.model.address.Address, ghidra.program.model.address.Address)" because "service" is null
    at ghidraemu.GhidraEmuPopup.unsetColor(GhidraEmuPopup.java:167)
    at ghidraemu.GhidraEmuProvider$5.keyReleased(GhidraEmuProvider.java:390)
    at java.desktop/java.awt.Component.processKeyEvent(Component.java:6577)
    at java.desktop/javax.swing.JComponent.processKeyEvent(JComponent.java:2905)
    at java.desktop/java.awt.Component.processEvent(Component.java:6393)
    at java.desktop/java.awt.Container.processEvent(Container.java:2266)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4991)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4823)
    at java.desktop/java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1952)
    at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:883)
    at java.desktop/java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1146)
    at java.desktop/java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:1020)
    at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:848)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4872)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4823)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

---------------------------------------------------
Build Date: 2022-Dec-12 1243 AEDT
Ghidra Version: 10.3
Java Home: /opt/homebrew/Cellar/openjdk/18.0.1/libexec/openjdk.jdk/Contents/Home
JVM Version: Homebrew 18.0.1
OS: Mac OS X 12.6 aarch64
Nalen98 commented 1 year ago

Hello!

I was unable to reproduce this on Ghidra 10.3 HEAD. My steps:

Screenshot from 2022-12-13 15-39-34

What am I missing? Based on the error you provided, the ColorizingService has not been initialized. If possible, please provide more details on what you did so that I can reproduce and fix this error deeper than simple exception handling.

brainstorm commented 1 year ago

I did not use that 3rd party V850 extension, but the included V850 support that Ghidra already has. That being said, I closed & reopened Ghidra today and couldn't reproduce either 🤷🏻‍♂️ So I'm closing this issue, thanks for the fast response!

I'm getting the error on the second emulation step though:

Screen Shot 2022-12-14 at 11 44 17 am

The first "Step" on offset 0x00001298 works fine and updates the PC accordingly. I'll need to investigate those options and settings, thanks again for your support!

Nalen98 commented 1 year ago

Thanks for your activity!

I still believe that this is not your fault and the error is worth handling. I'll let you know when I've finished my investigation.

Nalen98 commented 1 year ago

https://github.com/Nalen98/GhidraEmu/commit/c39ba4afa954ebe6b86a292da2edc9ee6b4296ba

This commit successfully fixes this problem. Every call to step#EmulatorHelper or run#EmulatorHelper discarded the previously prepared value of the stackPointer into its own (0xFFFFFFFF). Now the plugin also uses this value (only for V850). This change allowed to avoid such errors.

Before you try, don't forget to specify the link register in the Registers View: https://github.com/Nalen98/GhidraEmu#register-view

Be sure to contact if you notice any other strangeness or errors.

brainstorm commented 1 year ago

Updated to HEAD today and I have a bit more information, namely the error message from the console:

Screen Shot 2022-12-21 at 8 24 05 am

Without squinting at the screenshot, here's what it says in plaintext:

GhidraEmu> Unable to read bytes at ram:fffff420

Is it possible to make GhidraEmu assume that bytes at that location are uninitialised? Here's the default memory map when importing the binary, if it helps:

Screen Shot 2022-12-21 at 8 26 04 am

Nalen98 commented 1 year ago

Hi!

Take a look at my MemoryMap with the same binary, I guess: Screenshot from 2022-12-21 13-55-38

As I mentioned before in previous https://github.com/Nalen98/GhidraEmu/issues/6#issuecomment-1351911281, in V850 I discovered a strange behavior that, when starting emulation, the stackpointer's value is assigned to 0xFFFFFFFF without the knowledge of the plugin (it's a question for the developer of this processor module in Ghidra). Now I made it in https://github.com/Nalen98/GhidraEmu/commit/c39ba4afa954ebe6b86a292da2edc9ee6b4296ba so that for V850 processor the stack space will be created according to default 0xFFFFFFFF address.

I see in your MemoryMap that you probably didn't reload this Ghidra project (cmciocbl.bin). Try setting the stack ranges manually (0xFFFFE000 - 0xFFFFFFFF), or if circumstances permit, delete this project and create a new one with the same binary. The stack will be automatically allocated to the required addresses in this case.

The plugin warning:

GhidraEmu> Unable to read bytes at ram:fffff420

related to the stack space and I hope my hint will help you deal with it.

brainstorm commented 1 year ago

Thanks a ton @Nalen98 for the fixes and detailed explanation! I tried both setting the stack/ram manually as suggested and recreating the project. The first didn't work (same issue as before with the new maps), but the recreation worked and I managed to get a bit further on the static emulation, this plugin shows a big promise, well done!

Unfortunately, after a few steps, the emulation stopped on a seemingly trivial instruction:

Screen Shot 2022-12-24 at 7 54 07 pm Screen Shot 2022-12-24 at 7 53 55 pm

Plus as you can see, most of the stack remains uninitialized, which it shouldn't after offset 0x12A0, where the sp is set?

Nalen98 commented 1 year ago

sp register can be found in the RegistersView (just scroll down a little bit in this window). The start default sp value for v850 is 0xFFFFFFFF.

After a few of improvements in https://github.com/Nalen98/GhidraEmu/commit/8075d5b1e6fa5c0584b688e7cd93a89c40253ddb I've tried to reproduce this case and here's what I've got: Start address = 0x0 -> press "Run"

Peek 2022-12-25 01-15

Emulator stops at address 0x29f8 because it doesn't know about how to deal with non-existing memory space at 0x03ffef7c. This is expected behavior since the emulator is not capable of reading from memory that does not exist.

brainstorm commented 1 year ago

Emulator stops at address 0x29f8 because it doesn't know about how to deal with non-existing memory space at 0x03ffef7c. This is expected behavior since the emulator is not capable of reading from memory that does not exist.

On the contrary, that memory space exists and this is where things get interesting and exciting as there's (that I know of) no other FLOSS emulator doing this properly out there :)

V850 has a fairly odd memory map that "wraps around" for instruction jump efficiency and some 26-bit oddness too. So the memory is indeed there and must be available as this is a simple bootloader that does not rely on external memory nor a lot of peripherals (perhaps som CSI/UART/SPI port but no complex MMIOs).

GhidraEmu needs to know those MCU quirks in order to emulate it properly:

Screen Shot 2022-12-25 at 3 42 59 pm Screen Shot 2022-12-25 at 3 43 17 pm Screen Shot 2022-12-25 at 3 43 34 pm Screen Shot 2022-12-25 at 3 44 11 pm

Here's a V850E2-compatible datasheet if you need to check it yourself for MCU NEC μPD703128.pdf

EDIT: Actually, I just realised that just setting an appropriate memory map might address the emulator stalling right there, I'll give it a go later.

Nalen98 commented 1 year ago

Thanks for the information.

EDIT: Actually, I just realised that just https://github.com/esaulenka/ghidra_v850/issues/20#issuecomment-1220026804 might address the emulator stalling right there, I'll give it a go later.

Yes, add new memory segments to the memory map of your binary in Ghidra according to your CPU memory space. Don't forget to make it initialized to zeros so that the emulator can read bytes from it without problems. Also, according to the screenshot of memory map here https://github.com/esaulenka/ghidra_v850/issues/20#issuecomment-1220026804, the section "PERIO_FF" intersects with the emulator stack space. The emulator won't find the "Stack" ranges for this memMap, because the plugin searches for the lowercase "stack" pattern across names of existing memory sections to set suitable as stack. It occurs when you're opening your binary project.

At this moment, my record is when emulator stops at 0x2aa6 instruction __enable_irq() call. 0x12f0 is the "while-do" cycle which can become infinite (follow PC).

Please, update GhidraEmu to the latest master, I try to find and fix more and more bugs, thanks.

brainstorm commented 1 year ago

Thanks for all the fixing and rapid progress on this all the way down to enable interrupts!

Are you planning some kind of support for peripheral "hooks" so that we can potentially feed data in and out of say, the CAN bus, ADC or any other peripheral?

Since most of them are MMIOs, do you provide some kind of scripting facility/API to manipulate memory in concert with GhidraEmu or Ghidra's API itself is preferred to manipulate GhidraEmu target's memory?

I cannot recognise the 0xFFFFF6C2 peripheral that is being checked on the tight do-while loop of the 0x12f0 offset you mention, but the other do-while that follows on the same function is checking for Clock generator status register on 0xFFFFF824:

Screen Shot 2022-12-28 at 8 37 39 pm

        <register>
          <name>CGSTAT</name>
          <description>Clock generator status register</description>
          <addressOffset>0xFFFFF824</addressOffset>
          <size>8</size>
          <access>read-only</access>
          <resetValue>0</resetValue>
          <resetMask>0xFFFFFFFF</resetMask>
        </register>

So I would suspect that this is an early stage setup for either the processor's clocking or some serial console's baud rate.

If you need a SVD for the datasheet I posted above and start implementing peripheral hook/support in GhidraEmu, I built one myself over here for the V850E2 CA 'Jupiter'. You can expect other MCUs to comply with the CMSIS-SVD spec, so it should be a safe bet for other processors.

Nalen98 commented 1 year ago

do you provide some kind of scripting facility/API to manipulate memory in concert with GhidraEmu or Ghidra's API itself is preferred to manipulate GhidraEmu target's memory?

The plugin fully compatible with Ghidra Memory Map ( I've already added this note for users to the README block "Before you start"), if you want to add new memory blocks, the emulator will know about it right away. It doesn't allocate new blocks by itself, and users themselves must deal with such memory allocations if the processor analysis script (app/plugin/core/analysis content of the Ghidra processor module) hasn't done this thing. Everything the plugin can do with memory blocks management:

Try to manipulate the project memory before starting the emulation to avoid possible bugs.

Also, I think it's a good idea to improve the existing processor module V850 in Ghidra so that after loading the binary (even in the absence of GhidraEmu) you would get the correct allocation of all blocks according to the specification and not do it manually every time.

parul19822002 commented 1 year ago

I am trying to emulate a read and write code through uart on stm32f103 controller I have added SVD loader script and added successfully the peripherals for the controller Now while running the emulation I get error reading from memory address which are added as peripheral above Kindly let me know the solution to this that how can I run the emulation for code and see the uart data register for output and input data

parul19822002 commented 1 year ago

As I can simulate controller in Kiel ide and run the code in simulation, can see the peripheral views, can give input through uart console and also can see the output on uart console Is it possible to do this in this emulator

Nalen98 commented 1 year ago

Now while running the emulation I get error reading from memory address which are added as peripheral above Kindly let me know the solution to this that how can I run the emulation for code and see the uart data register for output and input data

I also used the SVD loader to reverse one of the public FlashLoaders and found that indeed this script creates new memory blocks for the UART registers and other peripherals in your Ghidra project.

But open the Ghidra MemoryMap and pay attention - these memory blocks (although allocated) are not initialized with zeros. And that's what happens in the end - you catch an error when the plugin is running, because the MemoryFaultHandler is triggered on an attempt to read uninitialized memory. To fix this, before start emulation process go to the Ghidra MemoryMap and check the box "Initialized" in front of the memory segment of interest like that:

Screenshot from 2023-01-17 22-17-33

This will allow the emulator to know for sure that this memory area is initialized and can be read from here. Use this solution until I automate the process.

parul19822002 commented 1 year ago

Thanks

On Wed, 18 Jan 2023 at 1:04 AM, Helen Sklyarova @.***> wrote:

Now while running the emulation I get error reading from memory address which are added as peripheral above Kindly let me know the solution to this that how can I run the emulation for code and see the uart data register for output and input data

I also used the SVD loader to reverse one of the public FlashLoaders and found that indeed this script creates new memory blocks for the UART registers and other peripherals in your Ghidra project.

But open the Ghidra MemoryMap and pay attention - these memory blocks (although allocated) are not initialized with zeros. And that's what happens in the end - you catch an error when the plugin is running, because the MemoryFaultHandler is triggered on an attempt to read uninitialized memory. To fix this, before start emulation process go to the Ghidra MemoryMap and check the box "Initialized" in front of the memory segment of interest like that:

[image: Screenshot from 2023-01-17 22-17-33] https://user-images.githubusercontent.com/52778977/212994257-8e188427-f32c-4838-9ece-441dad45ca81.png

This will allow the emulator to know for sure that this memory area is initialized and can be read from here.

— Reply to this email directly, view it on GitHub https://github.com/Nalen98/GhidraEmu/issues/6#issuecomment-1385945855, or unsubscribe https://github.com/notifications/unsubscribe-auth/ARN6CVW45RLT4FOODYMHWETWS3X27ANCNFSM6AAAAAAS4WAZR4 . You are receiving this because you commented.Message ID: @.***>

parul19822002 commented 1 year ago

Can u make some videos for sample firmware using angryghidra also It would be grt help

On Wed, 18 Jan 2023 at 1:04 AM, Helen Sklyarova @.***> wrote:

Now while running the emulation I get error reading from memory address which are added as peripheral above Kindly let me know the solution to this that how can I run the emulation for code and see the uart data register for output and input data

I also used the SVD loader to reverse one of the public FlashLoaders and found that indeed this script creates new memory blocks for the UART registers and other peripherals in your Ghidra project.

But open the Ghidra MemoryMap and pay attention - these memory blocks (although allocated) are not initialized with zeros. And that's what happens in the end - you catch an error when the plugin is running, because the MemoryFaultHandler is triggered on an attempt to read uninitialized memory. To fix this, before start emulation process go to the Ghidra MemoryMap and check the box "Initialized" in front of the memory segment of interest like that:

[image: Screenshot from 2023-01-17 22-17-33] https://user-images.githubusercontent.com/52778977/212994257-8e188427-f32c-4838-9ece-441dad45ca81.png

This will allow the emulator to know for sure that this memory area is initialized and can be read from here.

— Reply to this email directly, view it on GitHub https://github.com/Nalen98/GhidraEmu/issues/6#issuecomment-1385945855, or unsubscribe https://github.com/notifications/unsubscribe-auth/ARN6CVW45RLT4FOODYMHWETWS3X27ANCNFSM6AAAAAAS4WAZR4 . You are receiving this because you commented.Message ID: @.***>

parul19822002 commented 1 year ago

I need to attach a fuzzer with ghidraemulator Can u help with that also On Wed, 18 Jan 2023 at 7:47 AM, parul tiwari @.***> wrote:

Can u make some videos for sample firmware using angryghidra also It would be grt help

On Wed, 18 Jan 2023 at 1:04 AM, Helen Sklyarova @.***> wrote:

Now while running the emulation I get error reading from memory address which are added as peripheral above Kindly let me know the solution to this that how can I run the emulation for code and see the uart data register for output and input data

I also used the SVD loader to reverse one of the public FlashLoaders and found that indeed this script creates new memory blocks for the UART registers and other peripherals in your Ghidra project.

But open the Ghidra MemoryMap and pay attention - these memory blocks (although allocated) are not initialized with zeros. And that's what happens in the end - you catch an error when the plugin is running, because the MemoryFaultHandler is triggered on an attempt to read uninitialized memory. To fix this, before start emulation process go to the Ghidra MemoryMap and check the box "Initialized" in front of the memory segment of interest like that:

[image: Screenshot from 2023-01-17 22-17-33] https://user-images.githubusercontent.com/52778977/212994257-8e188427-f32c-4838-9ece-441dad45ca81.png

This will allow the emulator to know for sure that this memory area is initialized and can be read from here.

— Reply to this email directly, view it on GitHub https://github.com/Nalen98/GhidraEmu/issues/6#issuecomment-1385945855, or unsubscribe https://github.com/notifications/unsubscribe-auth/ARN6CVW45RLT4FOODYMHWETWS3X27ANCNFSM6AAAAAAS4WAZR4 . You are receiving this because you commented.Message ID: @.***>

Nalen98 commented 1 year ago

Can u make some videos for sample firmware using angryghidra also It would be grt help

The README of this repository contains a detailed enough description of the functionality to get started with plugin.