mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-22 12:11:55 +00:00
GP-4743 - PDB - Developer stream and offset locator for file offset
This commit is contained in:
parent
d58923419c
commit
8a62ed795f
@ -20,8 +20,7 @@ import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.msf.Msf;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.msf.MsfStream;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.msf.*;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
|
||||
import ghidra.app.util.datatype.microsoft.GUID;
|
||||
@ -469,6 +468,35 @@ public abstract class AbstractPdb implements AutoCloseable {
|
||||
return msf.getMonitor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Developer mechanism to locate stream and offset within that stream that is associated with
|
||||
* the given absolute file offset
|
||||
* @param fileOffset the absolute file offset that we are trying to locate
|
||||
* @return the stream and offset or {@code null} if not located
|
||||
*/
|
||||
public StreamAndOffset getStreamOffsetForAbsoluteFileOffset(long fileOffset) {
|
||||
if (msf instanceof AbstractMsf myMsf) {
|
||||
return myMsf.getStreamOffsetForAbsoluteFileOffset(fileOffset);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Developer mechanism to get a {@code PdbByteReader} for the particular stream, offset, and
|
||||
* length.
|
||||
* @param streamNumber the stream number
|
||||
* @param offset the offset in the stream
|
||||
* @param length the number of bytes to include from the stream
|
||||
* @return the reader
|
||||
* @throws CancelledException upon user cancellation
|
||||
* @throws IOException upon issue getting the stream for the PDB
|
||||
*/
|
||||
public PdbByteReader getDeveloperBytes(int streamNumber, int offset, int length)
|
||||
throws CancelledException, IOException {
|
||||
PdbByteReader reader = getReaderForStreamNumber(streamNumber, offset, length);
|
||||
return reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if this monitor has been canceled
|
||||
* @throws CancelledException if monitor has been cancelled
|
||||
|
@ -238,6 +238,26 @@ public abstract class AbstractMsf implements Msf {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Developer mechanism to locate stream and offset within the stream that contains the
|
||||
* absolute file offset
|
||||
* @param fileOffset the absolute file offset that we are trying to locate
|
||||
* @return the offset in the stream of the file offset or {@code null} if not in the stream
|
||||
*/
|
||||
public StreamAndOffset getStreamOffsetForAbsoluteFileOffset(long fileOffset) {
|
||||
if (fileOffset < 0L || fileOffset > (long) numPages * pageSize) {
|
||||
return null;
|
||||
}
|
||||
for (int number = 0; number < streamTable.getNumStreams(); number++) {
|
||||
MsfStream s = getStream(number);
|
||||
Integer offset = s.getStreamOffsetForAbsoluteFileOffset(fileOffset);
|
||||
if (offset != null) {
|
||||
return new StreamAndOffset(number, offset);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
// Class Internals
|
||||
//==============================================================================================
|
||||
|
@ -72,8 +72,7 @@ public class MsfStream {
|
||||
* inability to read required bytes
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public byte[] read(int streamOffset, int numToRead)
|
||||
throws IOException, CancelledException {
|
||||
public byte[] read(int streamOffset, int numToRead) throws IOException, CancelledException {
|
||||
if (numToRead <= 0) {
|
||||
return null;
|
||||
}
|
||||
@ -231,12 +230,10 @@ public class MsfStream {
|
||||
* @throws PdbException upon not enough data left to parse
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
void deserializePageNumbers(PdbByteReader reader)
|
||||
throws PdbException, CancelledException {
|
||||
void deserializePageNumbers(PdbByteReader reader) throws PdbException, CancelledException {
|
||||
// This calculations works fine for streamLength = 0
|
||||
// and even streamLength = -1 (0xffffffff).
|
||||
int numPages =
|
||||
Msf.floorDivisionWithLog2Divisor(streamLength, msf.getLog2PageSize());
|
||||
int numPages = Msf.floorDivisionWithLog2Divisor(streamLength, msf.getLog2PageSize());
|
||||
if (msf.getPageNumberSize() == 2) {
|
||||
for (int i = 0; i < numPages; i++) {
|
||||
msf.checkCancelled();
|
||||
@ -276,4 +273,27 @@ public class MsfStream {
|
||||
deserializePageNumbers(reader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Developer mechanism to see if the stream hold the absolute file offset and what the
|
||||
* corresponding stream offset is
|
||||
* @param fileOffset the absolute file offset that we are trying to locate
|
||||
* @return the offset in the stream of the file offset or {@code null} if not in the stream
|
||||
*/
|
||||
Integer getStreamOffsetForAbsoluteFileOffset(long fileOffset) {
|
||||
long pageSize = msf.getPageSize();
|
||||
for (int pageCount = 0; pageCount < pageList.size(); pageCount++) {
|
||||
int page = pageList.get(pageCount);
|
||||
long pageStart = page * pageSize;
|
||||
long pageEndExclusive = pageStart + pageSize;
|
||||
if (pageStart <= fileOffset && fileOffset < pageEndExclusive) {
|
||||
// We must get the offset within page, but then must use the pageCount to determine
|
||||
// the rest of the streamOffset
|
||||
Long pageOffset = fileOffset - pageStart;
|
||||
Long streamOffset = pageCount * pageSize + pageOffset;
|
||||
return streamOffset.intValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
/* ###
|
||||
* 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.msf;
|
||||
|
||||
public record StreamAndOffset(int number, int offset) {}
|
Loading…
Reference in New Issue
Block a user