mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GP-3599 Fix for function bodies including one byte of non-disassembled
data. PowerPC disassembly from computed branch.
This commit is contained in:
parent
a7063c672e
commit
b7ede746d0
6 changed files with 312 additions and 4 deletions
|
@ -637,7 +637,7 @@ public class CreateFunctionCmd extends BackgroundCommand {
|
||||||
FlowType[] dontFollow = { RefType.COMPUTED_CALL, RefType.CONDITIONAL_CALL,
|
FlowType[] dontFollow = { RefType.COMPUTED_CALL, RefType.CONDITIONAL_CALL,
|
||||||
RefType.UNCONDITIONAL_CALL, RefType.INDIRECTION };
|
RefType.UNCONDITIONAL_CALL, RefType.INDIRECTION };
|
||||||
AddressSet start = new AddressSet(entry, entry);
|
AddressSet start = new AddressSet(entry, entry);
|
||||||
FollowFlow flow = new FollowFlow(program, start, dontFollow, includeOtherFunctions);
|
FollowFlow flow = new FollowFlow(program, start, dontFollow, includeOtherFunctions, false);
|
||||||
return flow.getFlowAddressSet(monitor);
|
return flow.getFlowAddressSet(monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,19 @@ public abstract class AbstractFollowFlowTest extends AbstractGhidraHeadedIntegra
|
||||||
return followFlow.getFlowAddressSet(TaskMonitor.DUMMY);
|
return followFlow.getFlowAddressSet(TaskMonitor.DUMMY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddressSetView getFlowsFrom(int startAddressOffset, FlowType[] excludedFlows, boolean includeFunctions, boolean includeData) {
|
||||||
|
return getFlowsFrom(addr(startAddressOffset), excludedFlows, includeFunctions, includeData);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddressSetView getFlowsFrom(Address startAddress, FlowType[] excludedFlows, boolean includeFunctions, boolean includeData) {
|
||||||
|
return getFlowsFrom(new AddressSet(startAddress), excludedFlows, includeFunctions, includeData);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddressSetView getFlowsFrom(AddressSet startSet, FlowType[] excludedFlows, boolean includeFunctions, boolean includeData) {
|
||||||
|
FollowFlow followFlow = new FollowFlow(program, startSet, excludedFlows, includeFunctions, includeData);
|
||||||
|
return followFlow.getFlowAddressSet(TaskMonitor.DUMMY);
|
||||||
|
}
|
||||||
|
|
||||||
AddressSetView getFlowsTo(int startAddressOffset, FlowType[] excludedFlows) {
|
AddressSetView getFlowsTo(int startAddressOffset, FlowType[] excludedFlows) {
|
||||||
return getFlowsTo(addr(startAddressOffset), excludedFlows);
|
return getFlowsTo(addr(startAddressOffset), excludedFlows);
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,33 @@ public class FollowFlowForwardTest extends AbstractFollowFlowTest {
|
||||||
assertEquals(new MySelection(expectedAddresses), new MySelection(flowAddresses));
|
assertEquals(new MySelection(expectedAddresses), new MySelection(flowAddresses));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFollowAllFlowsFromNoData0x10() {
|
||||||
|
|
||||||
|
AddressSetView flowAddresses = getFlowsFrom(0x10, followAllFlows(), true, false);
|
||||||
|
|
||||||
|
AddressSet expectedAddresses = new AddressSet();
|
||||||
|
expectedAddresses.add(addr(0x0), addr(0x24));
|
||||||
|
expectedAddresses.add(addr(0x26), addr(0x2f));
|
||||||
|
expectedAddresses.add(addr(0x30), addr(0x52));
|
||||||
|
expectedAddresses.add(addr(0x54), addr(0x5f));
|
||||||
|
expectedAddresses.add(addr(0x60), addr(0x84));
|
||||||
|
expectedAddresses.add(addr(0x86), addr(0x8f));
|
||||||
|
expectedAddresses.add(addr(0x90), addr(0xb4));
|
||||||
|
expectedAddresses.add(addr(0xb6), addr(0xbf));
|
||||||
|
expectedAddresses.add(addr(0x130), addr(0x131));
|
||||||
|
expectedAddresses.add(addr(0x160), addr(0x161));
|
||||||
|
expectedAddresses.add(addr(0x190), addr(0x191));
|
||||||
|
expectedAddresses.add(addr(0x230), addr(0x231));
|
||||||
|
expectedAddresses.add(addr(0x260), addr(0x261));
|
||||||
|
expectedAddresses.add(addr(0x290), addr(0x291));
|
||||||
|
expectedAddresses.add(addr(0x330), addr(0x331));
|
||||||
|
expectedAddresses.add(addr(0x360), addr(0x361));
|
||||||
|
expectedAddresses.add(addr(0x390), addr(0x391));
|
||||||
|
|
||||||
|
assertEquals(new MySelection(expectedAddresses), new MySelection(flowAddresses));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFollowAllFlowsFrom0x17() {
|
public void testFollowAllFlowsFrom0x17() {
|
||||||
|
|
||||||
|
@ -104,6 +131,27 @@ public class FollowFlowForwardTest extends AbstractFollowFlowTest {
|
||||||
|
|
||||||
assertEquals(new MySelection(expectedAddresses), new MySelection(flowAddresses));
|
assertEquals(new MySelection(expectedAddresses), new MySelection(flowAddresses));
|
||||||
}
|
}
|
||||||
|
@Test
|
||||||
|
public void testFollowAllFlowsFromNoData0x17() {
|
||||||
|
|
||||||
|
AddressSetView flowAddresses = getFlowsFrom(0x17, followAllFlows(), true, false);
|
||||||
|
|
||||||
|
AddressSet expectedAddresses = new AddressSet();
|
||||||
|
expectedAddresses.add(addr(0x17), addr(0x24));
|
||||||
|
expectedAddresses.add(addr(0x26), addr(0x2f));
|
||||||
|
expectedAddresses.add(addr(0x60), addr(0x84));
|
||||||
|
expectedAddresses.add(addr(0x86), addr(0x8f));
|
||||||
|
expectedAddresses.add(addr(0x90), addr(0xb4));
|
||||||
|
expectedAddresses.add(addr(0xb6), addr(0xbf));
|
||||||
|
expectedAddresses.add(addr(0x230), addr(0x231));
|
||||||
|
expectedAddresses.add(addr(0x260), addr(0x261));
|
||||||
|
expectedAddresses.add(addr(0x290), addr(0x291));
|
||||||
|
expectedAddresses.add(addr(0x330), addr(0x331));
|
||||||
|
expectedAddresses.add(addr(0x360), addr(0x361));
|
||||||
|
expectedAddresses.add(addr(0x390), addr(0x391));
|
||||||
|
|
||||||
|
assertEquals(new MySelection(expectedAddresses), new MySelection(flowAddresses));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFollowAllFlowsFrom0x2f() {
|
public void testFollowAllFlowsFrom0x2f() {
|
||||||
|
@ -160,6 +208,20 @@ public class FollowFlowForwardTest extends AbstractFollowFlowTest {
|
||||||
assertEquals(new MySelection(expectedAddresses), new MySelection(flowAddresses));
|
assertEquals(new MySelection(expectedAddresses), new MySelection(flowAddresses));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFollowAllFlowsFromNoData0x77() {
|
||||||
|
|
||||||
|
AddressSetView flowAddresses = getFlowsFrom(0x77, followAllFlows(), true, false);
|
||||||
|
|
||||||
|
AddressSet expectedAddresses = new AddressSet();
|
||||||
|
expectedAddresses.add(addr(0x77), addr(0x84));
|
||||||
|
expectedAddresses.add(addr(0x86), addr(0x8f));
|
||||||
|
expectedAddresses.add(addr(0x260), addr(0x261));
|
||||||
|
expectedAddresses.add(addr(0x290), addr(0x291));
|
||||||
|
|
||||||
|
assertEquals(new MySelection(expectedAddresses), new MySelection(flowAddresses));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFollowAllFlowsFrom0x5000() {
|
public void testFollowAllFlowsFrom0x5000() {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,197 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.app.cmd.function;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import generic.test.AbstractGenericTest;
|
||||||
|
import ghidra.app.plugin.core.analysis.AnalysisBackgroundCommand;
|
||||||
|
import ghidra.app.plugin.core.analysis.AutoAnalysisManager;
|
||||||
|
import ghidra.framework.cmd.Command;
|
||||||
|
import ghidra.framework.options.Options;
|
||||||
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
|
import ghidra.program.database.ProgramBuilder;
|
||||||
|
import ghidra.program.database.function.OverlappingFunctionException;
|
||||||
|
import ghidra.program.model.address.*;
|
||||||
|
import ghidra.program.model.listing.*;
|
||||||
|
import ghidra.program.model.symbol.SourceType;
|
||||||
|
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||||
|
import ghidra.test.TestEnv;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for the {@link CreateFunctionCmdWithFlowTest}.
|
||||||
|
*/
|
||||||
|
public class CreateFunctionCmdWithFlowTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
|
||||||
|
private TestEnv env;
|
||||||
|
private PluginTool tool;
|
||||||
|
|
||||||
|
private Program program;
|
||||||
|
private ProgramBuilder builder;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
env = new TestEnv();
|
||||||
|
tool = env.getTool();
|
||||||
|
|
||||||
|
builder = new ProgramBuilder("notepad.exe", ProgramBuilder._PPC_32);
|
||||||
|
builder.createMemory("test", "0x07000000", 1024);
|
||||||
|
|
||||||
|
program = builder.getProgram();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create some functions (byte patterns, not Ghidra objects) with varying separation
|
||||||
|
//
|
||||||
|
// single function
|
||||||
|
builder.setBytes("0x07000008", "3d 60 07 00 61 6b 00 20 7d 69 03 a6 4e 80 04 20");
|
||||||
|
builder.disassemble("0x07000008", 16);
|
||||||
|
builder.createMemoryJumpReference("0x070000014", "0x07000020");
|
||||||
|
|
||||||
|
// Thunk to above single function
|
||||||
|
builder.setBytes("0x07000020", "7c 69 1b 78 88 04 00 00 38 84 00 01 7c 00 07 74 2f 80 00 00 98 09 00 00 39 29 00 01 40 9e ff e8 4e 80 00 20");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void analyze() {
|
||||||
|
// turn off some analyzers
|
||||||
|
setAnalysisOptions("Stack");
|
||||||
|
setAnalysisOptions("Embedded Media");
|
||||||
|
setAnalysisOptions("DWARF");
|
||||||
|
setAnalysisOptions("Create Address Tables");
|
||||||
|
setAnalysisOptions("MIPS Constant Reference Analyzer");
|
||||||
|
|
||||||
|
AutoAnalysisManager analysisMgr = AutoAnalysisManager.getAnalysisManager(program);
|
||||||
|
analysisMgr.reAnalyzeAll(null);
|
||||||
|
|
||||||
|
Command cmd = new AnalysisBackgroundCommand(analysisMgr, false);
|
||||||
|
tool.execute(cmd, program);
|
||||||
|
waitForBusyTool(tool);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setAnalysisOptions(String optionName) {
|
||||||
|
int txId = program.startTransaction("Analyze");
|
||||||
|
Options analysisOptions = program.getOptions(Program.ANALYSIS_PROPERTIES);
|
||||||
|
analysisOptions.setBoolean(optionName, false);
|
||||||
|
program.endTransaction(txId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateFunction() {
|
||||||
|
|
||||||
|
int transactionID = program.startTransaction("Perform the TEST");
|
||||||
|
|
||||||
|
CreateFunctionCmd createCmd = new CreateFunctionCmd(addr(0x07000008));
|
||||||
|
createCmd.applyTo(program);
|
||||||
|
|
||||||
|
program.endTransaction(transactionID, true);
|
||||||
|
|
||||||
|
Function func8 = func(addr(0x07000008));
|
||||||
|
assertNotNull("Created normal function", func8);
|
||||||
|
|
||||||
|
assertEquals("Normal function body size", 16, func8.getBody().getNumAddresses());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateFunctionOneByte() throws OverlappingFunctionException {
|
||||||
|
|
||||||
|
int transactionID = program.startTransaction("Perform the TEST");
|
||||||
|
|
||||||
|
CreateFunctionCmd createCmd = new CreateFunctionCmd(addr(0x07000008));
|
||||||
|
createCmd.applyTo(program);
|
||||||
|
|
||||||
|
// doctor body
|
||||||
|
AddressSet body = new AddressSet(addr(0x07000008),addr(0x07000017));
|
||||||
|
body.add(addr(0x07000020));
|
||||||
|
|
||||||
|
Function func8 = func(addr(0x07000008));
|
||||||
|
|
||||||
|
func8.setBody(body);
|
||||||
|
|
||||||
|
assertEquals("Normal function body size", 17, func8.getBody().getNumAddresses());
|
||||||
|
|
||||||
|
builder.disassemble("0x07000020", 36);
|
||||||
|
|
||||||
|
createCmd = new CreateFunctionCmd(addr(0x07000020));
|
||||||
|
createCmd.applyTo(program);
|
||||||
|
|
||||||
|
program.endTransaction(transactionID, true);
|
||||||
|
|
||||||
|
assertNotNull("Created normal function", func8);
|
||||||
|
|
||||||
|
assertEquals("Normal function body size", 16, func8.getBody().getNumAddresses());
|
||||||
|
|
||||||
|
Function func20 = func(addr(0x07000020));
|
||||||
|
|
||||||
|
assertNotNull("Created normal function", func20);
|
||||||
|
|
||||||
|
assertEquals("Normal function body size", 36, func20.getBody().getNumAddresses());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPPCDisassemblyRef() throws OverlappingFunctionException {
|
||||||
|
|
||||||
|
int transactionID = program.startTransaction("Perform the TEST");
|
||||||
|
|
||||||
|
CreateFunctionCmd createCmd = new CreateFunctionCmd(addr(0x07000008));
|
||||||
|
createCmd.applyTo(program);
|
||||||
|
|
||||||
|
Function func8 = func(addr(0x07000008));
|
||||||
|
|
||||||
|
program.getMemory().getBlock(addr(0x07000000)).setExecute(true);
|
||||||
|
|
||||||
|
assertFalse("is not Thunk yet", func8.isThunk());
|
||||||
|
|
||||||
|
Instruction instructionAt = program.getListing().getInstructionAt(addr(0x07000020));
|
||||||
|
|
||||||
|
assertNull("Not disassembled yet", instructionAt);
|
||||||
|
|
||||||
|
builder.analyze();
|
||||||
|
|
||||||
|
assertNotNull("Created normal function", func8);
|
||||||
|
|
||||||
|
assertEquals("Normal function body size", 16, func8.getBody().getNumAddresses());
|
||||||
|
|
||||||
|
instructionAt = program.getListing().getInstructionAt(addr(0x07000020));
|
||||||
|
|
||||||
|
assertNotNull("Disassembled from computed branch", instructionAt);
|
||||||
|
|
||||||
|
createCmd = new CreateFunctionCmd(addr(0x07000020));
|
||||||
|
createCmd.applyTo(program);
|
||||||
|
|
||||||
|
Function func20 = func(addr(0x07000020));
|
||||||
|
|
||||||
|
builder.analyze();
|
||||||
|
|
||||||
|
program.endTransaction(transactionID, true);
|
||||||
|
|
||||||
|
assertTrue("is Thunk ", func8.isThunk());
|
||||||
|
|
||||||
|
assertEquals("Normal function body size", 36, func20.getBody().getNumAddresses());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Address addr(long l) {
|
||||||
|
AddressSpace addressSpace = program.getAddressFactory().getDefaultAddressSpace();
|
||||||
|
return addressSpace.getAddress(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Function func(Address a) {
|
||||||
|
FunctionManager fm = program.getFunctionManager();
|
||||||
|
return fm.getFunctionAt(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -46,11 +46,15 @@ public class FollowFlow {
|
||||||
private boolean followPointers = true;
|
private boolean followPointers = true;
|
||||||
|
|
||||||
private boolean followIntoFunction = true;
|
private boolean followIntoFunction = true;
|
||||||
|
private boolean includeData = true;
|
||||||
private Address nextSymbolAddr;
|
private Address nextSymbolAddr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
|
* Note: flow into existing functions will be included
|
||||||
|
* Note: flow into un-disassembled locations will be included
|
||||||
|
*
|
||||||
* @param program the program whose flow we are following.
|
* @param program the program whose flow we are following.
|
||||||
* @param addressSet the initial addresses that should be flowed from or flowed to.
|
* @param addressSet the initial addresses that should be flowed from or flowed to.
|
||||||
* @param doNotFollow array of flow types that are not to be followed.
|
* @param doNotFollow array of flow types that are not to be followed.
|
||||||
|
@ -63,6 +67,7 @@ public class FollowFlow {
|
||||||
* <BR>FlowType.CONDITIONAL_JUMP
|
* <BR>FlowType.CONDITIONAL_JUMP
|
||||||
* <BR>FlowType.UNCONDITIONAL_JUMP
|
* <BR>FlowType.UNCONDITIONAL_JUMP
|
||||||
* <BR>FlowType.INDIRECTION
|
* <BR>FlowType.INDIRECTION
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public FollowFlow(Program program, AddressSet addressSet, FlowType[] doNotFollow) {
|
public FollowFlow(Program program, AddressSet addressSet, FlowType[] doNotFollow) {
|
||||||
this.program = program;
|
this.program = program;
|
||||||
|
@ -73,6 +78,8 @@ public class FollowFlow {
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
|
* Note: flow into un-disassembled locations will be included
|
||||||
|
*
|
||||||
* @param program the program whose flow we are following.
|
* @param program the program whose flow we are following.
|
||||||
* @param addressSet the initial addresses that should be flowed from or flowed to.
|
* @param addressSet the initial addresses that should be flowed from or flowed to.
|
||||||
* @param doNotFollow array of flow types that are not to be followed.
|
* @param doNotFollow array of flow types that are not to be followed.
|
||||||
|
@ -94,6 +101,31 @@ public class FollowFlow {
|
||||||
this.followIntoFunction = followIntoFunctions;
|
this.followIntoFunction = followIntoFunctions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param program the program whose flow we are following.
|
||||||
|
* @param addressSet the initial addresses that should be flowed from or flowed to.
|
||||||
|
* @param doNotFollow array of flow types that are not to be followed.
|
||||||
|
* null or empty array indicates follow all flows. The following are valid
|
||||||
|
* flow types for the doNotFollow array:
|
||||||
|
* <BR>FlowType.COMPUTED_CALL
|
||||||
|
* <BR>FlowType.CONDITIONAL_CALL
|
||||||
|
* <BR>FlowType.UNCONDITIONAL_CALL
|
||||||
|
* <BR>FlowType.COMPUTED_JUMP
|
||||||
|
* <BR>FlowType.CONDITIONAL_JUMP
|
||||||
|
* <BR>FlowType.UNCONDITIONAL_JUMP
|
||||||
|
* <BR>FlowType.INDIRECTION
|
||||||
|
* @param followIntoFunctions true if flows into (or back from) defined functions
|
||||||
|
* should be followed.
|
||||||
|
* @param includeData true if instruction flows into un-disassembled data should be included
|
||||||
|
*/
|
||||||
|
public FollowFlow(Program program, AddressSet addressSet, FlowType[] doNotFollow,
|
||||||
|
boolean followIntoFunctions, boolean includeData) {
|
||||||
|
this(program, addressSet, doNotFollow, followIntoFunctions);
|
||||||
|
this.includeData = includeData;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* updateFollowFlags
|
* updateFollowFlags
|
||||||
*
|
*
|
||||||
|
@ -289,7 +321,9 @@ public class FollowFlow {
|
||||||
codeUnit = instructionStack.pop();
|
codeUnit = instructionStack.pop();
|
||||||
if (!(codeUnit instanceof Instruction)) {
|
if (!(codeUnit instanceof Instruction)) {
|
||||||
// Probably undefined data which should be disassembled
|
// Probably undefined data which should be disassembled
|
||||||
flowAddressSet.addRange(codeUnit.getMinAddress(), codeUnit.getMaxAddress());
|
if (includeData) {
|
||||||
|
flowAddressSet.addRange(codeUnit.getMinAddress(), codeUnit.getMaxAddress());
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,7 +509,7 @@ public class FollowFlow {
|
||||||
if (nextAddress != null) {
|
if (nextAddress != null) {
|
||||||
CodeUnit nextCodeUnit = program.getListing().getCodeUnitContaining(nextAddress);
|
CodeUnit nextCodeUnit = program.getListing().getCodeUnitContaining(nextAddress);
|
||||||
if (nextCodeUnit != null) {
|
if (nextCodeUnit != null) {
|
||||||
if (nextCodeUnit instanceof Data) {
|
if (nextCodeUnit instanceof Data && includeData) {
|
||||||
followData(instructionStack, flowAddressSet, (Data) nextCodeUnit,
|
followData(instructionStack, flowAddressSet, (Data) nextCodeUnit,
|
||||||
nextAddress);
|
nextAddress);
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,7 +226,9 @@ public class PowerPCAddressAnalyzer extends ConstantPropagationAnalyzer {
|
||||||
public boolean evaluateReference(VarnodeContext context, Instruction instr,
|
public boolean evaluateReference(VarnodeContext context, Instruction instr,
|
||||||
int pcodeop, Address address, int size, DataType dataType, RefType refType) {
|
int pcodeop, Address address, int size, DataType dataType, RefType refType) {
|
||||||
|
|
||||||
if (instr.getFlowType().isJump()) {
|
if (refType.isJump() && refType.isComputed() &&
|
||||||
|
program.getMemory().contains(address) && address.getOffset() != 0) {
|
||||||
|
super.evaluateReference(context, instr, pcodeop, address, size, dataType, refType);
|
||||||
// for branching instructions, if we have a good target, mark it
|
// for branching instructions, if we have a good target, mark it
|
||||||
// if this isn't straight code (thunk computation), let someone else lay down the reference
|
// if this isn't straight code (thunk computation), let someone else lay down the reference
|
||||||
return !symEval.encounteredBranch();
|
return !symEval.encounteredBranch();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue