Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V850 discussion #6

Open
brainstorm opened this issue Dec 13, 2022 · 19 comments
Open

V850 discussion #6

brainstorm opened this issue Dec 13, 2022 · 19 comments
Assignees

Comments

@brainstorm
Copy link

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
@brainstorm brainstorm changed the title NPE: Cannot invoke "ghidra.app.plugin.core.colorizer.ColorizingService.clearBackgroundColor(ghidra.program.model.address.Address, ghidra.program.model.address.Address)" because "service" is null NPE: Cannot invoke "ghidra.app.plugin.core.colorizer.ColorizingService.clearBackgroundColor()" Dec 13, 2022
@Nalen98 Nalen98 self-assigned this Dec 13, 2022
@Nalen98
Copy link
Owner

Nalen98 commented Dec 13, 2022

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
Copy link
Author

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
Copy link
Owner

Nalen98 commented Dec 14, 2022

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 Nalen98 reopened this Dec 14, 2022
@Nalen98
Copy link
Owner

Nalen98 commented Dec 14, 2022

c39ba4a

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.

@Nalen98 Nalen98 closed this as completed Dec 15, 2022
@brainstorm
Copy link
Author

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
Copy link
Owner

Nalen98 commented Dec 21, 2022

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 #6 (comment), 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 c39ba4a 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
Copy link
Author

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 Nalen98 changed the title NPE: Cannot invoke "ghidra.app.plugin.core.colorizer.ColorizingService.clearBackgroundColor()" V850 discussion Dec 24, 2022
@Nalen98 Nalen98 reopened this Dec 24, 2022
@Nalen98
Copy link
Owner

Nalen98 commented Dec 24, 2022

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 8075d5b 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
Copy link
Author

brainstorm commented Dec 25, 2022

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
Copy link
Owner

Nalen98 commented Dec 25, 2022

Thanks for the information.

EDIT: Actually, I just realised that just esaulenka/ghidra_v850#20 (comment) 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 esaulenka/ghidra_v850#20 (comment), 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
Copy link
Author

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
Copy link
Owner

Nalen98 commented Dec 29, 2022

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:

  • will allocate the stack if there is no such area yet
  • initializes memory block to zeros that is required for emulation but was not initialized

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
Copy link

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
Copy link

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
Copy link
Owner

Nalen98 commented Jan 17, 2023

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
Copy link

parul19822002 commented Jan 18, 2023 via email

@parul19822002
Copy link

parul19822002 commented Jan 18, 2023 via email

@parul19822002
Copy link

parul19822002 commented Jan 18, 2023 via email

@Nalen98
Copy link
Owner

Nalen98 commented Jan 18, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants