mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-30 16:47:43 +08:00
Merge remote-tracking branch 'origin/GP-5664_ghizard_PdbReader_parse_NewFramePointerOmission_data'
This commit is contained in:
+53
-3
@@ -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.
|
||||
@@ -47,7 +47,8 @@ public class DebugData {
|
||||
X_DATA(7),
|
||||
P_DATA(8),
|
||||
NEW_FRAME_POINTER_OMISSION(9),
|
||||
SECTION_HEADER_ORIG(10);
|
||||
SECTION_HEADER_ORIG(10),
|
||||
UNKNOWN_DEBUG_11(11); // should be renamed when identified
|
||||
|
||||
private final int value;
|
||||
|
||||
@@ -180,6 +181,20 @@ public class DebugData {
|
||||
return deserializeSectionHeaders(streamNum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the New Frame Pointer Omission data (FrameDataRecord)
|
||||
* @return the frame data or null if does not exist or problem parsing
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public List<FrameDataRecord> getNewFramePointerOmissionData()
|
||||
throws CancelledException {
|
||||
int streamNum = getDebugStream(DebugType.NEW_FRAME_POINTER_OMISSION);
|
||||
if (streamNum == MsfStream.NIL_STREAM_NUMBER) {
|
||||
return null;
|
||||
}
|
||||
return deserializeNewFramePointerOmissionData(streamNum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize {@link DebugData} header from the {@link PdbByteReader} input. This parses
|
||||
* stream numbers for varying Debug Types--the order/location of the stream number is for
|
||||
@@ -259,6 +274,9 @@ public class DebugData {
|
||||
case SECTION_HEADER_ORIG:
|
||||
// imageSectionHeadersOrig = deserializeSectionHeaders(streamNum);
|
||||
break;
|
||||
case UNKNOWN_DEBUG_11:
|
||||
// unknown
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -426,6 +444,28 @@ public class DebugData {
|
||||
|
||||
}
|
||||
|
||||
private List<FrameDataRecord> deserializeNewFramePointerOmissionData(int streamNum)
|
||||
throws CancelledException {
|
||||
// TODO: check implementation for completeness.
|
||||
try {
|
||||
PdbByteReader reader = pdb.getReaderForStreamNumber(streamNum);
|
||||
List<FrameDataRecord> frameData = new ArrayList<>();
|
||||
while (reader.hasMore()) {
|
||||
pdb.checkCancelled();
|
||||
FrameDataRecord frameDataRecord = new FrameDataRecord();
|
||||
frameDataRecord.parse(reader);
|
||||
frameData.add(frameDataRecord);
|
||||
}
|
||||
return frameData;
|
||||
}
|
||||
catch (PdbException | IOException e) {
|
||||
//catch (IOException e) {
|
||||
PdbLog.message("Returning null Debug New Frame Pointer Omission Data due to" +
|
||||
" problem during deserialization from stream" + streamNum + ": " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the {@link DebugData}. This package-protected method is for debugging only
|
||||
* @param writer {@link Writer} to which to write the debug dump
|
||||
@@ -504,6 +544,16 @@ public class DebugData {
|
||||
}
|
||||
writer.write("End PData---------------------------------------------------\n");
|
||||
|
||||
writer.write("NewFramePointerOmissionData---------------------------------\n");
|
||||
List<FrameDataRecord> frameData = getNewFramePointerOmissionData();
|
||||
if (frameData != null) {
|
||||
for (FrameDataRecord frameDataRecord : frameData) {
|
||||
pdb.checkCancelled();
|
||||
frameDataRecord.dump(writer);
|
||||
}
|
||||
}
|
||||
writer.write("End NewFramePointerOmissionData-----------------------------\n");
|
||||
|
||||
writer.write("End DebugData-----------------------------------------------\n");
|
||||
}
|
||||
|
||||
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
/* ###
|
||||
* 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.util.bin.format.pdb2.pdbreader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* FRAMEDATA from cvinfo.h
|
||||
* Most members are coded as unsigned long or unsigned long bit-fields; two are coded as
|
||||
* unsigned short: prolog and saved regs.
|
||||
*/
|
||||
public class FrameDataRecord {
|
||||
|
||||
private long rvaStart; // unsigned long
|
||||
private long numBlockBytes; // unsigned long
|
||||
private long numLocalBytes; // unsigned long
|
||||
private long numParamBytes; // unsigned long
|
||||
private long maxStackBytes; // unsigned long
|
||||
private long frameFunc; // ? // unsigned long
|
||||
private int numPrologBytes; // unsigned short
|
||||
private int numSavedRegBytes; // unsigned short
|
||||
private boolean hasSEH; // unsigned long bit-field
|
||||
private boolean hasEH; // unsigned long bit-field
|
||||
private boolean isFunctionStart; // unsigned long bit-field
|
||||
private long reserved; // contains shifted/masked remainder of unsigned long
|
||||
|
||||
/**
|
||||
* Returns the RVA start
|
||||
* @return the RVA start
|
||||
*/
|
||||
public long getRvaStart() {
|
||||
return rvaStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes in the block (function)
|
||||
* @return the number of bytes in the block
|
||||
*/
|
||||
public long getNumberBlockBytes() {
|
||||
return numBlockBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes used by local variables
|
||||
* @return the number of bytes used by locals
|
||||
*/
|
||||
public long getNumberLocalBytes() {
|
||||
return numLocalBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes used by the parameters
|
||||
* @return the number of bytes used by parameters
|
||||
*/
|
||||
public long getNumberParameterBytes() {
|
||||
return numParamBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns max number of stack bytes
|
||||
* @return max stack bytes
|
||||
*/
|
||||
public long getMaxStackBytes() {
|
||||
return maxStackBytes;
|
||||
}
|
||||
|
||||
// TODO: change javadoc and method name and underlying variable once we've determined what
|
||||
// this is
|
||||
/**
|
||||
* Returns the frame func... not yet sure what this is
|
||||
* @return the frame func
|
||||
*/
|
||||
public long getFrameFunc() {
|
||||
return frameFunc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes in the function prolog
|
||||
* @return the number of bytes in the prolog
|
||||
*/
|
||||
public int getNumberFunctionPrologBytes() {
|
||||
return numPrologBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes for saved registers
|
||||
* @return the number of bytes used by saved registers
|
||||
*/
|
||||
public int getNumberSavedRegisterBytes() {
|
||||
return numSavedRegBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether has SEH
|
||||
* @return {@code true} if has SEH
|
||||
*/
|
||||
public boolean hasSEH() {
|
||||
return hasSEH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether has EH
|
||||
* @return {@code true} if has EH
|
||||
*/
|
||||
public boolean hasEH() {
|
||||
return hasEH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether is function start
|
||||
* @return {@code true} if us function start
|
||||
*/
|
||||
public boolean isFunctionStart() {
|
||||
return isFunctionStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the reserved, remaining 29 bit-field bits
|
||||
* @return the value of the reserved field
|
||||
*/
|
||||
public long reserved() {
|
||||
return reserved;
|
||||
}
|
||||
|
||||
public void parse(PdbByteReader reader) throws PdbException {
|
||||
if (reader.numRemaining() < 32) {
|
||||
throw new PdbException("Not enough data for FrameDataRecord");
|
||||
}
|
||||
rvaStart = reader.parseUnsignedIntVal();
|
||||
numBlockBytes = reader.parseUnsignedIntVal();
|
||||
numLocalBytes = reader.parseUnsignedIntVal();
|
||||
numParamBytes = reader.parseUnsignedIntVal();
|
||||
maxStackBytes = reader.parseUnsignedIntVal();
|
||||
frameFunc = reader.parseUnsignedIntVal();
|
||||
numPrologBytes = reader.parseUnsignedShortVal();
|
||||
numSavedRegBytes = reader.parseUnsignedShortVal();
|
||||
reserved = reader.parseUnsignedIntVal();
|
||||
hasSEH = (reserved & 0x01) == 0x01;
|
||||
reserved >>= 1;
|
||||
hasEH = (reserved & 0x01) == 0x01;
|
||||
reserved >>= 1;
|
||||
isFunctionStart = (reserved & 0x01) == 0x01;
|
||||
reserved >>= 1;
|
||||
reserved &= 0x01ffffff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the {@link FramePointerOmissionRecord}. This package-protected method is for
|
||||
* debugging only.
|
||||
* @param writer {@link Writer} to which to write the debug dump.
|
||||
* @throws IOException On issue writing to the {@link Writer}.
|
||||
*/
|
||||
void dump(Writer writer) throws IOException {
|
||||
writer.write("FrameDataRecord---------------------------------------------\n");
|
||||
writer.write(String.format("rvaStart: 0X%08X\n", rvaStart));
|
||||
writer.write(String.format("numBlockBytes: 0X%08X\n", numBlockBytes));
|
||||
writer.write(String.format("numLocalBytes: 0X%08X\n", numLocalBytes));
|
||||
writer.write(String.format("numParamBytes: 0X%08X\n", numParamBytes));
|
||||
writer.write(String.format("maxStackBytes: 0X%08X\n", maxStackBytes));
|
||||
writer.write(String.format("frameFunc: 0X%08X\n", frameFunc));
|
||||
writer.write(String.format("numPrologBytes: 0X%04X\n", numPrologBytes));
|
||||
writer.write(String.format("numSavedRegBytes: 0X%04X\n", numSavedRegBytes));
|
||||
writer.write(
|
||||
String.format("hasStructuedExceptionHandling: %s\n", Boolean.toString(hasSEH)));
|
||||
writer.write(String.format("hasExceptionHandling: %s\n", Boolean.toString(hasEH)));
|
||||
writer.write(String.format("isFunctionStart: %s\n", Boolean.toString(isFunctionStart)));
|
||||
writer.write("End FrameDataRecord-----------------------------------------\n");
|
||||
}
|
||||
}
|
||||
+5
-6
@@ -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.
|
||||
@@ -38,7 +38,7 @@ import java.util.Map;
|
||||
* WORD reserved : 1;
|
||||
* WORD cbFrame : 2;
|
||||
* } FPO_DATA, *PFPO_DATA;
|
||||
*
|
||||
*
|
||||
* where...
|
||||
* ulOffStart = The offset of the first byte of the function code.
|
||||
* cbProcSize = The number of bytes in the function.
|
||||
@@ -52,7 +52,7 @@ import java.util.Map;
|
||||
* cbFrame = A variable that indicates the frame type, where...
|
||||
* FRAME_FPO (0) = FPO frame
|
||||
* FRAME_TRAP (1) = Trap frame
|
||||
* FRAME_TSS (2) = TSS frame
|
||||
* FRAME_TSS (2) = TSS frame
|
||||
* FRAME_NONFPO (3) = non-FPO frame
|
||||
* </PRE>
|
||||
*/
|
||||
@@ -198,8 +198,7 @@ public class FramePointerOmissionRecord {
|
||||
void dump(Writer writer) throws IOException {
|
||||
writer.write("FramePointerOmissionRecord----------------------------------\n");
|
||||
writer.write(String.format("firstFunctionByteOffset: 0X%08X\n", firstFunctionByteOffset));
|
||||
writer.write(String.format("firstFunctionByteOffset: 0X%08X\n", firstFunctionByteOffset));
|
||||
writer.write(String.format("numFunctionBytes: 0X%08XX\n", numFunctionBytes));
|
||||
writer.write(String.format("numFunctionBytes: 0X%08X\n", numFunctionBytes));
|
||||
writer.write(String.format("numLocalVariables: 0X%08X\n", numLocalVariables));
|
||||
writer.write(String.format("sizeOfParametersInDwords: 0X%08X\n", sizeOfParametersInDwords));
|
||||
writer.write(String.format("numFunctionPrologBytes: 0X%04X\n", numFunctionPrologBytes));
|
||||
|
||||
Reference in New Issue
Block a user