Open 7ingsong opened 2 years ago
I found a similar issue https://github.com/NationalSecurityAgency/ghidra/issues/3428
I tried to set VLE register to 1 for the region, but it doesn't help. The same error
from ghidra.app.emulator import EmulatorHelper
from ghidra.app.emulator import EmulatorHelper
from ghidra.program.model.symbol import SymbolUtilities
from ghidra.program.model.lang import RegisterValue
from java.math import BigInteger
def getAddress(offset):
return currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(offset)
def getSymbolAddress(symbolName):
symbol = SymbolUtilities.getLabelOrFunctionSymbol(currentProgram, symbolName, None)
if (symbol != None):
return symbol.getAddress()
else:
raise("Failed to locate label: {}".format(symbolName))
vleReg = currentProgram.language.getRegister("vle")
value = RegisterValue(vleReg, BigInteger.ONE)
loadedMemory = currentProgram.getMemory().getLoadedAndInitializedAddressSet()
#print("addr",loadedMemory.getMinAddress(),loadedMemory.getMaxAddress())
currentProgram.getProgramContext().setRegisterValue(getAddress(0x0), getAddress(0x50), value)
emuHelper = EmulatorHelper(currentProgram)
codeStart=0x0
codeStop=0x6
emuHelper.writeRegister(emuHelper.getPCRegister(), codeStart)
while monitor.isCancelled() is False:
executionAddress = emuHelper.getExecutionAddress()
if (executionAddress == getAddress(codeStop)):
print("Emulation complete.")
break
print("Address: 0x{} ({})".format(executionAddress, getInstructionAt(executionAddress)))
success = emuHelper.step(monitor)
if (success == False):
lastError = emuHelper.getLastError()
print("Emulation Error: '{}'".format(lastError))
break
emuHelper.dispose()
The error
emu-error.py> Running...
Address: 0x00000000 (se_mflr r0)
Address: 0x00000002 (se_bl 0x00000010)
Address: 0x00000010 (se_mflr r0)
Emulation Error: 'Instruction decode failed (Unable to resolve constructor at 00000010), PC=00000010'
emu-error.py> Finished!
I'm still looking into this, but I can get the python script to run without error by adding a call to emuHelper.setContextRegister
in the try block. If I set the context register at the beginning of the script it won't flow properly to other functions. What is weird here is if I get the register value I get the same value before and after .
from ghidra.app.emulator import EmulatorHelper
from ghidra.program.model.symbol import SymbolUtilities
from ghidra.program.model.symbol import SymbolUtilities
from ghidra.program.model.lang import RegisterValue
from java.math import BigInteger
def getAddress(offset):
return currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(offset)
def getSymbolAddress(symbolName):
symbol = SymbolUtilities.getLabelOrFunctionSymbol(currentProgram, symbolName, None)
if (symbol != None):
return symbol.getAddress()
else:
raise("Failed to locate label: {}".format(symbolName))
emuHelper = EmulatorHelper(currentProgram)
codeStart=0x0
codeStop=0x6
emuHelper.writeRegister(emuHelper.getPCRegister(), codeStart)
while monitor.isCancelled() is False:
executionAddress = emuHelper.getExecutionAddress()
if (executionAddress == getAddress(codeStop)):
print("Emulation complete.")
break
try:
vleReg = currentProgram.language.getRegister("vle")
emuHelper.setContextRegister(vleReg,BigInteger.ONE)
print("Address: 0x{} ({})".format(executionAddress, getInstructionAt(executionAddress)))
except:
raise
success = emuHelper.step(monitor)
if (success == False):
lastError = emuHelper.getLastError()
print("Emulation Error: '{}'".format(lastError))
break
# Cleanup resources and release hold on currentProgram
emuHelper.dispose()
Alternatively, replacing the emuHelper.setContextRegister(vleReg,BigInteger.ONE)
call with the following also works:
emuHelper.setContextRegister(emuHelper.getContextRegister())
The issue here is that the emulator is not properly setting the seedContext in the disassembler. To correct it, we need to modify Emulate.java with this:
public void setSeedContext(ProgramContext seedContext) {
pseudoDisassembler.setSeedContext(new DisassemblerContextImpl(seedContext));
}
Emulator.java with this:
public void setSeedContext(ProgramContext seedContext) {
emulator.setSeedContext(seedContext);
}
and modify your script to either rely on the context in the program listing:
emHelper.getEmulator().setSeedContext(program.getProgramContext())
or you can just manually set the vle
context variable:
ProgramContextImpl context = new ProgramContextImpl(program.getLanguage())
Register vleReg = currentProgram.language.getRegister("vle")
context.setValue(vleReg, startAddr, endAddr, BigInteger.ONE)
emulator.setSeedContext(context)
Either way, I'll get the changes to the emulator incorporated so these steps work out of the box.
Describe the bug
Error during emulation of code PPC Big-endian VLE, Ghidra can't emulate the instruction after branch "se_mflr r0"
To Reproduce
def getAddress(offset): return currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(offset)
def getSymbolAddress(symbolName): symbol = SymbolUtilities.getLabelOrFunctionSymbol(currentProgram, symbolName, None) if (symbol != None): return symbol.getAddress() else: raise("Failed to locate label: {}".format(symbolName))
emuHelper = EmulatorHelper(currentProgram)
codeStart=0x0 codeStop=0x6
emuHelper.writeRegister(emuHelper.getPCRegister(), codeStart)
while monitor.isCancelled() is False: executionAddress = emuHelper.getExecutionAddress()
Cleanup resources and release hold on currentProgram
emuHelper.dispose()
Environment (please complete the following information):
Additional context