ghidra icon indicating copy to clipboard operation
ghidra copied to clipboard

DecompilerPanel.tryGoToVarnode navigates to wrong address space on Harvard architectures

Open mikenawrocki opened this issue 1 year ago • 0 comments

Describe the bug DecompilerPanel.tryGoToVarnode navigates to the wrong address space for array accesses on Harvard architectures (dsPIC30F for example).

The following code pulls out the second operand of a PTRSUB operation, which may occur if a global array is accessed:

               Varnode vn = token.getVarnode();
		if (vn == null) {
			PcodeOp op = token.getPcodeOp();
			if (op == null) {
				return;
			}
			int operation = op.getOpcode();
			if (!(operation == PcodeOp.PTRSUB || operation == PcodeOp.PTRADD)) {
				return;
			}
			vn = op.getInput(1);

This is later used as the offset in the call controller.goToScalar(vn.getOffset(), newWindow); which constructs an address using the offset. This constructed address may be in the wrong address space

The decompiler function Funcdata::spacebaseConstant documentation indicates that the first operand of the PTRSUB is a constant zero, and the flags of this Varnode are set to indicate it's a Spacebase, and a TypeSpacebase type is assigned to allow lookup in the correct address space within the decompiler.

From what I can tell, that information isn't present in the Java Varnode for input operand 0. I think either this information needs to be transferred from the decompiler, or a different lookup mechanism is required to get the correct addresses from PTRSUB operations.

To Reproduce Steps to reproduce the behavior:

  1. Load a firmware image on dsPIC30F with global arrays defined in RAM (data address space)
  2. Open the array access function in the decompile view
  3. Double click on the array access
  4. Notice that the navigated/attempted address is in the ROM address space (program address space)

Expected behavior Double clicking the array name navigates to the address in the correct address space.

Screenshots Screen Shot 2023-05-09 at 10 23 53 AM Note the error lower left; _global_buf2 is at ram:0x900 but the attempted address is rom:0x480.

Attachments Attached is an example dsPIC30F firmware with a _main function that accesses an array. dspic30F_global_array.zip

Environment (please complete the following information):

  • OS: MacOS 11.7.4 (also observed on Windows 10)
  • Java Version: 17.0.4
  • Ghidra Version: 10.2.3 (also master as of b3616a6831)
  • Ghidra Origin: Official Github distro (also local builds)

Additional context I've attempted this with array accesses, but I think it will likely fail for structure accesses as well. Also note that I had to make a second array for my example to work; the decompiler doesn't recognize the symbol for the first array for some reason. I think that's likely a separate issue.

mikenawrocki avatar May 09 '23 14:05 mikenawrocki