mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-04-25 17:25:17 +02:00
Updated the Bytes table column to not read too many bytes
This commit is contained in:
@@ -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.
|
||||
@@ -40,6 +40,9 @@ public class BytesTableColumn extends ProgramLocationTableColumnExtensionPoint<A
|
||||
private static SettingsDefinition[] SETTINGS_DEFS =
|
||||
{ BYTE_COUNT, MEMORY_OFFSET, ENDIANNESS, FORMAT };
|
||||
|
||||
// arbitrary limit to keep the table from reading too many bytes and becoming sluggish
|
||||
private static final int BYTE_LIMIT = 20;
|
||||
|
||||
private final GColumnRenderer<Byte[]> monospacedRenderer = new MonospacedByteRenderer();
|
||||
|
||||
/**
|
||||
@@ -68,50 +71,32 @@ public class BytesTableColumn extends ProgramLocationTableColumnExtensionPoint<A
|
||||
}
|
||||
|
||||
@Override
|
||||
public Byte[] getValue(Address rowObject, Settings settings, Program pgm,
|
||||
public Byte[] getValue(Address rowObject, Settings settings, Program program,
|
||||
ServiceProvider serviceProvider) throws IllegalArgumentException {
|
||||
|
||||
Address addr = rowObject;
|
||||
try {
|
||||
|
||||
int offset = MEMORY_OFFSET.getOffset(settings);
|
||||
int byteCnt = BYTE_COUNT.getChoice(settings);
|
||||
byte[] bytes = null;
|
||||
int byteCount = BYTE_COUNT.getChoice(settings);
|
||||
|
||||
Address addr = rowObject;
|
||||
if (offset != 0) {
|
||||
addr = addr.add(offset);
|
||||
}
|
||||
|
||||
if (byteCnt == 0) {
|
||||
if (offset != 0) {
|
||||
byteCnt = 1;
|
||||
}
|
||||
else {
|
||||
CodeUnit cu = pgm.getListing().getCodeUnitContaining(addr);
|
||||
if (cu == null) { // can happen for 'SpecialAddress'es
|
||||
return new Byte[0];
|
||||
}
|
||||
if (cu instanceof Instruction instr) {
|
||||
bytes = instr.getParsedBytes();
|
||||
}
|
||||
else {
|
||||
bytes = cu.getBytes();
|
||||
}
|
||||
if (byteCount == 0) {
|
||||
// note: would be nice to know why we only read one byte when there is an offset
|
||||
byteCount = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (bytes == null) {
|
||||
bytes = new byte[byteCnt];
|
||||
pgm.getMemory().getBytes(addr, bytes);
|
||||
if (byteCount == 0) {
|
||||
return getBytesFromCodeUnit(program, addr);
|
||||
}
|
||||
|
||||
Byte[] bytesObj = new Byte[bytes.length];
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
bytesObj[i] = Byte.valueOf(bytes[i]);
|
||||
}
|
||||
|
||||
return bytesObj;
|
||||
// read bytes; one of: 1, 2, 3, 4, 5, 6, 7, 8
|
||||
byte[] bytes = new byte[byteCount];
|
||||
program.getMemory().getBytes(addr, bytes);
|
||||
|
||||
return toBigBytes(bytes);
|
||||
}
|
||||
catch (MemoryAccessException e) {
|
||||
// handled below
|
||||
@@ -123,6 +108,36 @@ public class BytesTableColumn extends ProgramLocationTableColumnExtensionPoint<A
|
||||
return new Byte[0];
|
||||
}
|
||||
|
||||
private Byte[] getBytesFromCodeUnit(Program p, Address addr) throws MemoryAccessException {
|
||||
|
||||
Listing listing = p.getListing();
|
||||
CodeUnit cu = listing.getCodeUnitContaining(addr);
|
||||
if (cu == null) { // can happen for 'SpecialAddress'es
|
||||
return new Byte[0];
|
||||
}
|
||||
|
||||
byte[] bytes;
|
||||
int n = Math.min(cu.getLength(), BYTE_LIMIT);
|
||||
if (cu instanceof Instruction instr) {
|
||||
bytes = instr.getParsedBytes();
|
||||
}
|
||||
else {
|
||||
bytes = new byte[n];
|
||||
cu.getBytes(bytes, 0);
|
||||
}
|
||||
|
||||
return toBigBytes(bytes);
|
||||
}
|
||||
|
||||
private Byte[] toBigBytes(byte[] b) {
|
||||
|
||||
Byte[] bigBytes = new Byte[b.length];
|
||||
for (int i = 0; i < b.length; i++) {
|
||||
bigBytes[i] = Byte.valueOf(b[i]);
|
||||
}
|
||||
return bigBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GColumnRenderer<Byte[]> getColumnRenderer() {
|
||||
return monospacedRenderer;
|
||||
|
||||
@@ -59,7 +59,7 @@ public class MemoryMapDB implements Memory, ManagerDB {
|
||||
|
||||
private MemoryBlock lastBlock;// the last accessed block
|
||||
|
||||
// lazy hashmap of block names to blocks, must be reloaded if blocks are removed or added
|
||||
// lazy map of block names to blocks, must be reloaded if blocks are removed or added
|
||||
private HashMap<String, MemoryBlock> nameBlockMap = new HashMap<>();
|
||||
private final static MemoryBlock NoBlock = new MemoryBlockStub(); // placeholder for no block, not given out
|
||||
|
||||
@@ -135,9 +135,8 @@ public class MemoryMapDB implements Memory, ManagerDB {
|
||||
* <br>
|
||||
* NOTE: The {@link #initializeBlocks()} method is used to invalidate the {code addrSetViews}
|
||||
* without affecting {@code allAddrSet}, while {@link #reloadAll()} will force a complete
|
||||
* rebuild of all addresss sets.
|
||||
* rebuild of all address sets.
|
||||
*
|
||||
* @param rebuildAllAddrSets if true all address sets will be rebuilt before returning the
|
||||
* address set view object.
|
||||
* @return the address set view object
|
||||
*/
|
||||
@@ -2126,8 +2125,6 @@ public class MemoryMapDB implements Memory, ManagerDB {
|
||||
* In addition, allAddrSet will be updated if addToAll parameter is true.
|
||||
*
|
||||
* @param block memory block to be added
|
||||
* @param newAddrSetViews address set views which should be built-up
|
||||
* @param newAllAddrs if not null this set will be updated with the specified block's address range,
|
||||
* otherwise only the {@code addrSetView} sets will be updated.
|
||||
*/
|
||||
private void addBlockAddresses(MemoryBlockDB block) {
|
||||
|
||||
@@ -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.
|
||||
@@ -97,7 +97,7 @@ abstract class SubMemoryBlock implements Comparable<SubMemoryBlock> {
|
||||
throws IndexOutOfBoundsException, MemoryAccessException, IOException;
|
||||
|
||||
/**
|
||||
* Tries to get len bytes from this block at the given offset (relative to the containing
|
||||
* Tries to get {@code len} bytes from this block at the given offset (relative to the containing
|
||||
* {@link MemoryBlockDB} and put them into the given byte array at the specified offset.
|
||||
* May return fewer bytes if the requested length is beyond the end of the block.
|
||||
* @param memBlockOffset the offset relative to the containing {@link MemoryBlockDB}
|
||||
@@ -130,7 +130,7 @@ abstract class SubMemoryBlock implements Comparable<SubMemoryBlock> {
|
||||
throws IndexOutOfBoundsException, MemoryAccessException, IOException;
|
||||
|
||||
/**
|
||||
* Tries to write len bytes to this block at the given offset (relative to the containing
|
||||
* Tries to write {@code len} bytes to this block at the given offset (relative to the containing
|
||||
* {@link MemoryBlockDB} using the bytes contained in the given byte array at the specified byte
|
||||
* array offset.
|
||||
* May write fewer bytes if the requested length is beyond the end of the block.
|
||||
@@ -157,7 +157,7 @@ abstract class SubMemoryBlock implements Comparable<SubMemoryBlock> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the length of a subblock (Used by the split command)
|
||||
* Sets the length of a sub-block (Used by the split command)
|
||||
* @param length the new length of the block
|
||||
* @throws IOException if a database error occurs
|
||||
*/
|
||||
|
||||
@@ -266,9 +266,9 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
|
||||
public int getBytes(Address addr, byte[] b) throws MemoryAccessException;
|
||||
|
||||
/**
|
||||
* Tries to get len bytes from this block at the given address and put them into the given byte
|
||||
* array at the specified offet. May return fewer bytes if the requested length is beyond the
|
||||
* end of the block.
|
||||
* Tries to get {@code len} bytes from this block at the given address and put them into the
|
||||
* given byte array at the specified offset. May return fewer bytes if the requested length is
|
||||
* beyond the end of the block.
|
||||
*
|
||||
* @param addr the address from which to get the bytes.
|
||||
* @param b the byte array to populate.
|
||||
|
||||
Reference in New Issue
Block a user