mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-22 04:05:39 +00:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
commit
5b9dfc92dd
@ -637,7 +637,7 @@ public class CreateFunctionCmd extends BackgroundCommand {
|
||||
FlowType[] dontFollow = { RefType.COMPUTED_CALL, RefType.CONDITIONAL_CALL,
|
||||
RefType.UNCONDITIONAL_CALL, RefType.INDIRECTION };
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1383,15 +1383,9 @@ public class VarnodeContext implements ProcessorContext {
|
||||
return result;
|
||||
}
|
||||
|
||||
// This is bad since registers could have multiple associated spaces
|
||||
// private int getSymbolSpaceID(Varnode val) {
|
||||
// Register reg = trans.getRegister(val);
|
||||
// if (reg == null) {
|
||||
// return -1;
|
||||
// }
|
||||
// return getAddressSpace(reg.getName());
|
||||
// }
|
||||
|
||||
// flag running out of address spaces, so error only printed once
|
||||
private boolean hitMaxAddressSpaces = false;
|
||||
|
||||
public int getAddressSpace(String name) {
|
||||
int spaceID;
|
||||
AddressSpace regSpace = addrFactory.getAddressSpace(name);
|
||||
@ -1399,7 +1393,10 @@ public class VarnodeContext implements ProcessorContext {
|
||||
regSpace = ((OffsetAddressFactory) addrFactory).createNewOffsetSpace(name);
|
||||
}
|
||||
if (regSpace == null) {
|
||||
Msg.error(this, "VarnodeContext: out of address spaces for: " + name);
|
||||
if (!hitMaxAddressSpaces) {
|
||||
Msg.error(this, "VarnodeContext: out of address spaces at @" + currentAddress +" for: " + name);
|
||||
hitMaxAddressSpaces = true;
|
||||
}
|
||||
return BAD_SPACE_ID_VALUE;
|
||||
}
|
||||
spaceID = regSpace.getSpaceID();
|
||||
@ -1762,13 +1759,18 @@ class OffsetAddressFactory extends DefaultAddressFactory {
|
||||
}
|
||||
}
|
||||
|
||||
// Maximum space ID used to create spaces
|
||||
private int curMaxID = 0;
|
||||
|
||||
private int getNextUniqueID() {
|
||||
int maxID = 0;
|
||||
AddressSpace[] spaces = getAllAddressSpaces();
|
||||
for (AddressSpace space : spaces) {
|
||||
maxID = Math.max(maxID, space.getUnique());
|
||||
if (curMaxID == 0) {
|
||||
AddressSpace[] spaces = getAllAddressSpaces();
|
||||
for (AddressSpace space : spaces) {
|
||||
curMaxID = Math.max(curMaxID, space.getUnique());
|
||||
}
|
||||
}
|
||||
return maxID + 1;
|
||||
curMaxID += 1;
|
||||
return curMaxID;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -74,6 +74,19 @@ public abstract class AbstractFollowFlowTest extends AbstractGhidraHeadedIntegra
|
||||
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) {
|
||||
return getFlowsTo(addr(startAddressOffset), excludedFlows);
|
||||
}
|
||||
|
@ -80,6 +80,33 @@ public class FollowFlowForwardTest extends AbstractFollowFlowTest {
|
||||
|
||||
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
|
||||
public void testFollowAllFlowsFrom0x17() {
|
||||
@ -104,6 +131,27 @@ public class FollowFlowForwardTest extends AbstractFollowFlowTest {
|
||||
|
||||
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
|
||||
public void testFollowAllFlowsFrom0x2f() {
|
||||
@ -159,6 +207,20 @@ public class FollowFlowForwardTest extends AbstractFollowFlowTest {
|
||||
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
<opinions>
|
||||
<constraint loader="Dump File Loader">
|
||||
<constraint compilerSpecID="linux">
|
||||
<constraint primary="amd64" processor="x86" endian="little" size="64" />
|
||||
<constraint primary="amd64" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
</constraint>
|
||||
</opinions>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<!-- constraint primary="6" processor="IA64" endian="little" size="32" -->
|
||||
<!-- constraint primary="7" processor="ALPHA64" endian="little" size="32" -->
|
||||
<!-- constraint primary="8" processor="MSIL" endian="little" size="32" -->
|
||||
<constraint primary="9" processor="x86" endian="little" size="64" />
|
||||
<constraint primary="9" processor="x86" endian="little" size="64" variant="default" />
|
||||
<!-- constraint primary="10" processor="IA32/64" endian="little" size="32" -->
|
||||
<!-- constraint primary="11" processor="NEUTRAL" endian="little" size="32" -->
|
||||
<constraint primary="12" processor="ARM" endian="little" size="64" />
|
||||
|
@ -19,7 +19,7 @@
|
||||
<constraint primary="386" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="486" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="586" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="8664" processor="x86" endian="little" size="64" />
|
||||
<constraint primary="8664" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
<constraint compilerSpecID="default">
|
||||
<constraint primary="601" processor="PowerPC" endian="little" size="32" />
|
||||
|
@ -46,10 +46,14 @@ public class FollowFlow {
|
||||
private boolean followPointers = true;
|
||||
|
||||
private boolean followIntoFunction = true;
|
||||
private boolean includeData = true;
|
||||
private Address nextSymbolAddr;
|
||||
|
||||
/**
|
||||
* 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 addressSet the initial addresses that should be flowed from or flowed to.
|
||||
@ -63,6 +67,7 @@ public class FollowFlow {
|
||||
* <BR>FlowType.CONDITIONAL_JUMP
|
||||
* <BR>FlowType.UNCONDITIONAL_JUMP
|
||||
* <BR>FlowType.INDIRECTION
|
||||
*
|
||||
*/
|
||||
public FollowFlow(Program program, AddressSet addressSet, FlowType[] doNotFollow) {
|
||||
this.program = program;
|
||||
@ -73,6 +78,8 @@ public class FollowFlow {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Note: flow into un-disassembled locations will be included
|
||||
*
|
||||
* @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.
|
||||
@ -93,6 +100,31 @@ public class FollowFlow {
|
||||
this(program, addressSet, doNotFollow);
|
||||
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
|
||||
@ -289,7 +321,9 @@ public class FollowFlow {
|
||||
codeUnit = instructionStack.pop();
|
||||
if (!(codeUnit instanceof Instruction)) {
|
||||
// Probably undefined data which should be disassembled
|
||||
flowAddressSet.addRange(codeUnit.getMinAddress(), codeUnit.getMaxAddress());
|
||||
if (includeData) {
|
||||
flowAddressSet.addRange(codeUnit.getMinAddress(), codeUnit.getMaxAddress());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -475,7 +509,7 @@ public class FollowFlow {
|
||||
if (nextAddress != null) {
|
||||
CodeUnit nextCodeUnit = program.getListing().getCodeUnitContaining(nextAddress);
|
||||
if (nextCodeUnit != null) {
|
||||
if (nextCodeUnit instanceof Data) {
|
||||
if (nextCodeUnit instanceof Data && includeData) {
|
||||
followData(instructionStack, flowAddressSet, (Data) nextCodeUnit,
|
||||
nextAddress);
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ public class ArmAnalyzer extends ConstantPropagationAnalyzer {
|
||||
public AddressSet flowConstants(final Program program, Address flowStart,
|
||||
AddressSetView flowSet, final SymbolicPropogator symEval, final TaskMonitor monitor)
|
||||
throws CancelledException {
|
||||
|
||||
// follow all flows building up context
|
||||
// use context to fill out addresses on certain instructions
|
||||
ConstantPropagationContextEvaluator eval =
|
||||
@ -229,11 +230,16 @@ public class ArmAnalyzer extends ConstantPropagationAnalyzer {
|
||||
@Override
|
||||
public boolean evaluateReturn(Varnode retVN, VarnodeContext context, Instruction instruction) {
|
||||
// check if a return is actually returning, or is branching with a constant PC
|
||||
|
||||
|
||||
// if flow already overridden, don't override again
|
||||
if (instruction.getFlowOverride() != FlowOverride.NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (retVN != null && context.isConstant(retVN)) {
|
||||
long offset = retVN.getOffset();
|
||||
if (offset > 3 && offset != -1) {
|
||||
// need to override the return to a branch
|
||||
// need to override the return flow to a branch
|
||||
instruction.setFlowOverride(FlowOverride.BRANCH);
|
||||
}
|
||||
}
|
||||
|
@ -226,7 +226,9 @@ public class PowerPCAddressAnalyzer extends ConstantPropagationAnalyzer {
|
||||
public boolean evaluateReference(VarnodeContext context, Instruction instr,
|
||||
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
|
||||
// if this isn't straight code (thunk computation), let someone else lay down the reference
|
||||
return !symEval.encounteredBranch();
|
||||
|
@ -99,7 +99,7 @@
|
||||
<external_name tool="DWARF.register.mapping.file" name="x86-64.dwarf"/>
|
||||
<external_name tool="Golang.register.info.file" name="x86-64-golang.register.info"/>
|
||||
</language>
|
||||
<language processor="x86-compat32"
|
||||
<language processor="x86"
|
||||
endian="little"
|
||||
size="64"
|
||||
variant="compat32"
|
||||
|
@ -1,16 +1,17 @@
|
||||
<opinions>
|
||||
<!-- NOTE: variant="default" is specified for 64-bit to give preference to the default variant -->
|
||||
<constraint loader="Portable Executable (PE)">
|
||||
<constraint compilerSpecID="windows">
|
||||
<constraint primary="332" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="333" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="334" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="34404" processor="x86" endian="little" size="64" />
|
||||
<constraint primary="34404" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
<constraint compilerSpecID="clangwindows">
|
||||
<constraint primary="332" secondary="clang" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="333" secondary="clang" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="334" secondary="clang" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="34404" secondary="clang" processor="x86" endian="little" size="64" />
|
||||
<constraint primary="34404" secondary="clang" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
<constraint compilerSpecID="borlandcpp">
|
||||
<constraint primary="332" secondary="borlandcpp" processor="x86" endian="little" size="32" />
|
||||
@ -24,18 +25,18 @@
|
||||
</constraint>
|
||||
<constraint compilerSpecID="golang">
|
||||
<constraint primary="332" secondary="golang" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="34404" secondary="golang" processor="x86" endian="little" size="64" />
|
||||
<constraint primary="34404" secondary="golang" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
</constraint>
|
||||
<constraint loader="Debug Symbols (DBG)" compilerSpecID="windows">
|
||||
<constraint primary="332" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="333" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="334" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="34404" processor="x86" endian="little" size="64" />
|
||||
<constraint primary="34404" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="gcc">
|
||||
<constraint primary="3" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="62" processor="x86" endian="little" size="64" />
|
||||
<constraint primary="62" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
<constraint loader="Module Definition (DEF)" compilerSpecID="windows">
|
||||
<constraint primary="0" processor="x86" endian="little" size="32" />
|
||||
@ -51,18 +52,18 @@
|
||||
</constraint>
|
||||
<constraint loader="Mac OS X Mach-O" compilerSpecID="gcc">
|
||||
<constraint primary="7" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="16777223" processor="x86" endian="little" size="64" />
|
||||
<constraint primary="16777223" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
<constraint loader="DYLD Cache" compilerSpecID="gcc">
|
||||
<constraint primary="x86_64" processor="x86" endian="little" size="64" />
|
||||
<constraint primary="x86_64" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
<constraint loader="Common Object File Format (COFF)" compilerSpecID="gcc">
|
||||
<constraint primary="332" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="-31132" processor="x86" endian="little" size="64" />
|
||||
<constraint primary="-31132" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
<constraint loader="MS Common Object File Format (COFF)" compilerSpecID="windows">
|
||||
<constraint primary="332" processor="x86" endian="little" size="32" />
|
||||
<constraint primary="-31132" processor="x86" endian="little" size="64" />
|
||||
<constraint primary="-31132" processor="x86" endian="little" size="64" variant="default" />
|
||||
</constraint>
|
||||
<constraint loader="Assembler Output (AOUT)" compilerSpecID="gcc">
|
||||
<constraint primary="134" processor="x86" endian="little" size="32" />
|
||||
|
Loading…
Reference in New Issue
Block a user