mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-19 17:41:54 +08:00
Merge remote-tracking branch 'origin/Ghidra_12.1'
This commit is contained in:
+1
-6
@@ -486,12 +486,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
}
|
||||
|
||||
protected void forgetAllBreakpoints(RemoveCollector r) {
|
||||
Collection<TraceBreakpointLocation> toForget = new ArrayList<>();
|
||||
for (AddressRange range : trace.getBaseAddressFactory().getAddressSet()) {
|
||||
toForget.addAll(
|
||||
trace.getBreakpointManager().getBreakpointsIntersecting(Lifespan.ALL, range));
|
||||
}
|
||||
for (TraceBreakpointLocation tb : toForget) {
|
||||
for (TraceBreakpointLocation tb : List.copyOf(logicalByBreakpoint.keySet())) {
|
||||
forgetTraceBreakpoint(r, tb);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -90,7 +90,7 @@ public class ExceptionDataDirectory extends DataDirectory {
|
||||
}
|
||||
createDirectoryBookmark(program, addr);
|
||||
if (functionEntries != null) {
|
||||
functionEntries.markup(program, addr);
|
||||
functionEntries.markup(program, addr, log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-4
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -17,6 +17,7 @@ package ghidra.app.util.bin.format.pe;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||
@@ -33,10 +34,11 @@ public interface ImageRuntimeFunctionEntries {
|
||||
*
|
||||
* @param program The {@link Program}
|
||||
* @param start The start {@link Address}
|
||||
* @param log The log
|
||||
* @throws IOException If there was an IO-related error creating the data
|
||||
* @throws DuplicateNameException If a data type of the same name already exists
|
||||
* @throws CodeUnitInsertionException If data creation failed
|
||||
*/
|
||||
public void markup(Program program, Address start) throws CodeUnitInsertionException,
|
||||
IOException, DuplicateNameException;
|
||||
public void markup(Program program, Address start, MessageLog log)
|
||||
throws CodeUnitInsertionException, IOException, DuplicateNameException;
|
||||
}
|
||||
|
||||
+57
-41
@@ -4,9 +4,9 @@
|
||||
* 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.
|
||||
@@ -21,6 +21,7 @@ import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.listing.Program;
|
||||
@@ -65,49 +66,33 @@ public class ImageRuntimeFunctionEntries_ARM implements ImageRuntimeFunctionEntr
|
||||
*/
|
||||
ImageRuntimeFunctionEntries_ARM(BinaryReader reader, int size, NTHeader ntHeader)
|
||||
throws IOException {
|
||||
int numEntries = size / ENTRY_SIZE;
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
for (int i = 0; i < size / ENTRY_SIZE; i++) {
|
||||
long beginAddress = reader.readNextUnsignedInt() & ~0x1L; // low bit is set when thumb
|
||||
int data = reader.readNextInt();
|
||||
if (beginAddress == 0 && data == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
functionEntries.add(new ImageRuntimeFunctionEntry_ARM(beginAddress, data));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markup(Program program, Address headerStart) throws CodeUnitInsertionException,
|
||||
IOException, DuplicateNameException {
|
||||
StructureDataType exceptionInfoStruct = new StructureDataType("_IMAGE_RUNTIME_FUNCTION_ENTRY", 0);
|
||||
exceptionInfoStruct.setPackingEnabled(true);
|
||||
exceptionInfoStruct.add(StructConverter.IBO32, "BeginAddress", null);
|
||||
exceptionInfoStruct.add(StructConverter.IBO32, "ExceptionInfo", null);
|
||||
|
||||
StructureDataType unwindDataStruct = new StructureDataType("_IMAGE_RUNTIME_FUNCTION_ENTRY_2", 0);
|
||||
unwindDataStruct.setPackingEnabled(true);
|
||||
unwindDataStruct.add(StructConverter.IBO32, "BeginAddress", null);
|
||||
try {
|
||||
unwindDataStruct.addBitField(StructConverter.DWORD, 2, "Flag", null);
|
||||
unwindDataStruct.addBitField(StructConverter.DWORD, 11, "FunctionLength", null);
|
||||
unwindDataStruct.addBitField(StructConverter.DWORD, 2, "Ret", null);
|
||||
unwindDataStruct.addBitField(StructConverter.DWORD, 1, "H", null);
|
||||
unwindDataStruct.addBitField(StructConverter.DWORD, 3, "Reg", null);
|
||||
unwindDataStruct.addBitField(StructConverter.DWORD, 1, "R", null);
|
||||
unwindDataStruct.addBitField(StructConverter.DWORD, 1, "L", null);
|
||||
unwindDataStruct.addBitField(StructConverter.DWORD, 1, "C", null);
|
||||
unwindDataStruct.addBitField(StructConverter.DWORD, 10, "StackAdjust", null);
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
||||
public void markup(Program program, Address headerStart, MessageLog log)
|
||||
throws CodeUnitInsertionException, IOException, DuplicateNameException {
|
||||
Address addr = headerStart;
|
||||
DataType exceptionInfoDt = null;
|
||||
DataType packedUnwindDt = null;
|
||||
for (ImageRuntimeFunctionEntry_ARM entry : functionEntries) {
|
||||
DataType struct = entry.isExceptionInfoRVA() ? exceptionInfoStruct : unwindDataStruct;
|
||||
DataUtilities.createData(program, addr, struct, struct.getLength(), true,
|
||||
DataUtilities.ClearDataMode.CHECK_FOR_SPACE);
|
||||
if (entry.isExceptionInfoRVA()) {
|
||||
if (exceptionInfoDt == null) {
|
||||
exceptionInfoDt = entry.toDataType();
|
||||
}
|
||||
PeUtils.createData(program, addr, exceptionInfoDt, log);
|
||||
}
|
||||
else {
|
||||
if (packedUnwindDt == null) {
|
||||
packedUnwindDt = entry.toDataType();
|
||||
}
|
||||
PeUtils.createData(program, addr, packedUnwindDt, log);
|
||||
}
|
||||
entry.markup(program, log);
|
||||
addr = addr.add(ENTRY_SIZE);
|
||||
}
|
||||
}
|
||||
@@ -118,12 +103,10 @@ public class ImageRuntimeFunctionEntries_ARM implements ImageRuntimeFunctionEntr
|
||||
* @param beginAddress The RVA of the corresponding function
|
||||
* @param data The exception info RVA or the packed unwind data, depending on lower 2 bit flag
|
||||
*/
|
||||
record ImageRuntimeFunctionEntry_ARM(long beginAddress, int data) {
|
||||
record ImageRuntimeFunctionEntry_ARM(long beginAddress, int data) implements StructConverter {
|
||||
|
||||
/**
|
||||
* Checks whether or not this entry is an exception info RVA or packed unwind data
|
||||
*
|
||||
* @return True if this entry is an exception info RVA, or false if it's packed unwind data
|
||||
* {@return whether or not this entry is an exception info RVA or packed unwind data}
|
||||
*/
|
||||
public boolean isExceptionInfoRVA() {
|
||||
return (data & 0x3) == 0;
|
||||
@@ -133,15 +116,48 @@ public class ImageRuntimeFunctionEntries_ARM implements ImageRuntimeFunctionEntr
|
||||
* Marks up this entry
|
||||
*
|
||||
* @param program The {@link Program}
|
||||
* @param log The log
|
||||
* @throws IOException If there was an IO-related error creating the data
|
||||
* @throws DuplicateNameException If a data type of the same name already exists
|
||||
* @throws CodeUnitInsertionException If data creation failed
|
||||
*/
|
||||
public void markup(Program program)
|
||||
public void markup(Program program, MessageLog log)
|
||||
throws DuplicateNameException, IOException, CodeUnitInsertionException {
|
||||
if (isExceptionInfoRVA()) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct;
|
||||
if (isExceptionInfoRVA()) {
|
||||
struct = new StructureDataType("_IMAGE_RUNTIME_FUNCTION_ENTRY", 0);
|
||||
struct.setPackingEnabled(true);
|
||||
struct.add(StructConverter.IBO32, "BeginAddress", null);
|
||||
struct.add(StructConverter.IBO32, "ExceptionInfo", null);
|
||||
}
|
||||
else {
|
||||
struct = new StructureDataType("_IMAGE_RUNTIME_FUNCTION_ENTRY_2", 0);
|
||||
struct.setPackingEnabled(true);
|
||||
struct.add(StructConverter.IBO32, "BeginAddress", null);
|
||||
try {
|
||||
struct.addBitField(StructConverter.DWORD, 2, "Flag", null);
|
||||
struct.addBitField(StructConverter.DWORD, 11, "FunctionLength", null);
|
||||
struct.addBitField(StructConverter.DWORD, 2, "Ret", null);
|
||||
struct.addBitField(StructConverter.DWORD, 1, "H", null);
|
||||
struct.addBitField(StructConverter.DWORD, 3, "Reg", null);
|
||||
struct.addBitField(StructConverter.DWORD, 1, "R", null);
|
||||
struct.addBitField(StructConverter.DWORD, 1, "L", null);
|
||||
struct.addBitField(StructConverter.DWORD, 1, "C", null);
|
||||
struct.addBitField(StructConverter.DWORD, 10, "StackAdjust", null);
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
struct.setCategoryPath(new CategoryPath("/PE"));
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+35
-37
@@ -21,6 +21,7 @@ import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.app.util.opinion.AbstractProgramLoader;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.*;
|
||||
@@ -85,42 +86,34 @@ public class ImageRuntimeFunctionEntries_X86 implements ImageRuntimeFunctionEntr
|
||||
*/
|
||||
ImageRuntimeFunctionEntries_X86(BinaryReader reader, int size, NTHeader ntHeader)
|
||||
throws IOException {
|
||||
|
||||
int numEntries = size / ENTRY_SIZE;
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
for (int i = 0; i < size / ENTRY_SIZE; i++) {
|
||||
long beginAddress = reader.readNextUnsignedInt();
|
||||
long endAddress = reader.readNextUnsignedInt();
|
||||
long unwindInfoAddressOrData = reader.readNextUnsignedInt();
|
||||
PEx64UnwindInfo unwindInfo = null;
|
||||
|
||||
if (beginAddress == 0 && endAddress == 0 && unwindInfoAddressOrData == 0) {
|
||||
break;
|
||||
if (unwindInfoAddressOrData != 0) {
|
||||
unwindInfo =
|
||||
PEx64UnwindInfo.readUnwindInfo(reader, unwindInfoAddressOrData, ntHeader);
|
||||
}
|
||||
|
||||
PEx64UnwindInfo unwindInfo =
|
||||
PEx64UnwindInfo.readUnwindInfo(reader, unwindInfoAddressOrData, ntHeader);
|
||||
|
||||
ImageRuntimeFunctionEntry_X86 entry = new ImageRuntimeFunctionEntry_X86(beginAddress,
|
||||
endAddress, unwindInfoAddressOrData, unwindInfo);
|
||||
functionEntries.add(entry);
|
||||
functionEntries.add(new ImageRuntimeFunctionEntry_X86(beginAddress, endAddress,
|
||||
unwindInfoAddressOrData, unwindInfo));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markup(Program program, Address headerStart) throws CodeUnitInsertionException,
|
||||
IOException, DuplicateNameException {
|
||||
StructureDataType struct = new StructureDataType("_IMAGE_RUNTIME_FUNCTION_ENTRY", 0);
|
||||
struct.add(StructConverter.IBO32, "BeginAddress", null);
|
||||
struct.add(StructConverter.DWORD, "EndAddress",
|
||||
"Apply ImageBaseOffset32 to see reference");
|
||||
struct.add(StructConverter.IBO32, "UnwindInfoAddressOrData", null);
|
||||
|
||||
ArrayDataType arr = new ArrayDataType(struct, functionEntries.size(), struct.getLength());
|
||||
|
||||
DataUtilities.createData(program, headerStart, arr, arr.getLength(), true,
|
||||
DataUtilities.ClearDataMode.CHECK_FOR_SPACE);
|
||||
|
||||
public void markup(Program program, Address headerStart, MessageLog log)
|
||||
throws CodeUnitInsertionException, IOException, DuplicateNameException {
|
||||
Address addr = headerStart;
|
||||
DataType dt = null;
|
||||
for (ImageRuntimeFunctionEntry_X86 entry : functionEntries) {
|
||||
entry.markup(program);
|
||||
if (dt == null) {
|
||||
dt = entry.toDataType();
|
||||
}
|
||||
PeUtils.createData(program, addr, dt, log);
|
||||
entry.markup(program, log);
|
||||
addr = addr.add(ENTRY_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,34 +126,39 @@ public class ImageRuntimeFunctionEntries_X86 implements ImageRuntimeFunctionEntr
|
||||
* @param unwindInfo The parsed {@link PEx64UnwindInfo unwind information}
|
||||
*/
|
||||
record ImageRuntimeFunctionEntry_X86(long beginAddress, long endAddress,
|
||||
long unwindInfoAddressOrData, PEx64UnwindInfo unwindInfo) {
|
||||
long unwindInfoAddressOrData, PEx64UnwindInfo unwindInfo) implements StructConverter {
|
||||
|
||||
/**
|
||||
* Marks up this entry
|
||||
*
|
||||
* @param program The {@link Program}
|
||||
* @param log The log
|
||||
* @throws IOException If there was an IO-related error creating the data
|
||||
* @throws DuplicateNameException If a data type of the same name already exists
|
||||
*/
|
||||
public void markup(Program program) throws DuplicateNameException, IOException {
|
||||
public void markup(Program program, MessageLog log)
|
||||
throws DuplicateNameException, IOException {
|
||||
|
||||
if (beginAddress != 0 && !unwindInfo.hasChainedUnwindInfo()) {
|
||||
AbstractProgramLoader.markAsFunction(program, null,
|
||||
program.getImageBase().add(beginAddress));
|
||||
}
|
||||
|
||||
if (unwindInfoAddressOrData > 0) {
|
||||
DataType dt = unwindInfo.toDataType();
|
||||
if (unwindInfo != null) {
|
||||
Address start = program.getImageBase().add(unwindInfoAddressOrData);
|
||||
|
||||
try {
|
||||
DataUtilities.createData(program, start, dt, dt.getLength(), true,
|
||||
DataUtilities.ClearDataMode.CHECK_FOR_SPACE);
|
||||
}
|
||||
catch (CodeUnitInsertionException e) {
|
||||
// expected...ignore
|
||||
}
|
||||
PeUtils.createData(program, start, unwindInfo.toDataType(), log);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType("_IMAGE_RUNTIME_FUNCTION_ENTRY", 0);
|
||||
struct.add(StructConverter.IBO32, "BeginAddress", null);
|
||||
struct.add(StructConverter.DWORD, "EndAddress",
|
||||
"Apply ImageBaseOffset32 to see reference");
|
||||
struct.add(StructConverter.IBO32, "UnwindInfoAddressOrData", null);
|
||||
struct.setCategoryPath(new CategoryPath("/PE"));
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
@@ -110,6 +110,22 @@ public class PEx64UnwindInfoDataType extends DynamicDataType {
|
||||
if (hasUnwindHandler(flags)) {
|
||||
struct.add(new ArrayDataType(UnsignedLongDataType.dataType, 0, -1),
|
||||
"ExceptionData", null);
|
||||
// TODO: somehow check for __C_specific_handler and markup:
|
||||
/*-----------------------------------------------------------------------------
|
||||
// C Scope table entry
|
||||
typedef struct _C_SCOPE_TABLE_ENTRY {
|
||||
ULONG Begin; // +0x00 - Begin of guarded code block
|
||||
ULONG End; // +0x04 - End of target code block
|
||||
ULONG Handler; // +0x08 - Exception filter function (or “__finally” handler)
|
||||
ULONG Target; // +0x0C - Exception handler pointer (the code inside __except block)
|
||||
} C_SCOPE_TABLE_ENTRY, *PC_SCOPE_TABLE_ENTRY;
|
||||
|
||||
// C Scope table
|
||||
typedef struct _C_SCOPE_TABLE {
|
||||
ULONG NumEntries; // +0x00 - Number of entries
|
||||
C_SCOPE_TABLE_ENTRY Table[1]; // +0x04 - Scope table array
|
||||
} C_SCOPE_TABLE, *PC_SCOPE_TABLE;
|
||||
----------------------------------------------------------------------------*/
|
||||
}
|
||||
}
|
||||
else if (hasChainedUnwindInfo(flags)) {
|
||||
|
||||
Reference in New Issue
Block a user