decodePieces returns logicalsize

This commit is contained in:
caheckman 2023-07-19 18:52:24 +00:00
parent 76feae3d49
commit a9622f89a3
2 changed files with 31 additions and 12 deletions

View file

@ -421,8 +421,8 @@ public class AddressXML {
}
else {
decoder.rewindAttributes();
Varnode[] pieces = Varnode.decodePieces(decoder);
storage = pcodeFactory.getJoinStorage(pieces);
Varnode.Join join = Varnode.decodePieces(decoder);
storage = pcodeFactory.getJoinStorage(join.pieces);
}
}
catch (InvalidInputException e) {

View file

@ -19,7 +19,8 @@ import static ghidra.program.model.pcode.AttributeId.*;
import static ghidra.program.model.pcode.ElementId.*;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.Iterator;
import ghidra.program.model.address.*;
import ghidra.program.model.lang.Language;
@ -38,6 +39,15 @@ public class Varnode {
private static final long masks[] = { 0L, 0xffL, 0xffffL, 0xffffffL, 0xffffffffL, 0xffffffffffL,
0xffffffffffffL, 0xffffffffffffffL, 0xffffffffffffffffL };
/**
* Set of Varnode pieces referred to by a single Varnode in join space
* as returned by Varnode.decodePieces
*/
public static class Join {
public Varnode[] pieces; // The list of individual Varnodes being joined
public int logicalSize; // The size (in bytes) of the logical whole.
}
private Address address;
private int size;
private int spaceID;
@ -384,12 +394,12 @@ public class Varnode {
if ((spc != null) && (spc.getType() == AddressSpace.TYPE_VARIABLE)) { // Check for a composite Address
decoder.rewindAttributes();
try {
Varnode[] pieces = decodePieces(decoder);
VariableStorage storage = factory.getJoinStorage(pieces);
Join join = decodePieces(decoder);
VariableStorage storage = factory.getJoinStorage(join.pieces);
// Update "join" address to the one just registered with the pieces
addr = factory.getJoinAddress(storage);
// Update size to be the size of the pieces
sz = Arrays.stream(pieces).map(x -> x.getSize()).reduce(0, Integer::sum);
sz = join.logicalSize;
}
catch (InvalidInputException e) {
throw new DecoderException("Invalid varnode pieces: " + e.getMessage());
@ -488,16 +498,21 @@ public class Varnode {
* space, a contiguous sequence of bytes, at a specific Address, represent a logical value
* that may physically be split across multiple registers or other storage locations.
* @param decoder is the stream decoder
* @return an array of decoded Varnodes
* @return an array of decoded Varnodes and the logical size
* @throws DecoderException for any errors in the encoding
*/
public static Varnode[] decodePieces(Decoder decoder) throws DecoderException {
public static Join decodePieces(Decoder decoder) throws DecoderException {
ArrayList<Varnode> list = new ArrayList<>();
int sizeAccum = 0;
int logicalSize = 0;
for (;;) {
int attribId = decoder.getNextAttributeId();
if (attribId == 0) {
break;
}
else if (attribId == ATTRIB_LOGICALSIZE.id()) {
logicalSize = (int) decoder.readUnsignedInteger();
}
else if (attribId == ATTRIB_UNKNOWN.id()) {
attribId = decoder.getIndexedAttributeId(ATTRIB_PIECE);
}
@ -510,12 +525,16 @@ public class Varnode {
if (index != list.size()) {
throw new DecoderException("\"piece\" attributes must be in order");
}
list.add(decodePiece(decoder.readString(), decoder.getAddressFactory()));
Varnode vn = decodePiece(decoder.readString(), decoder.getAddressFactory());
list.add(vn);
sizeAccum += vn.getSize();
}
}
Varnode[] pieces = new Varnode[list.size()];
list.toArray(pieces);
return pieces;
Join join = new Join();
join.pieces = new Varnode[list.size()];
join.logicalSize = (logicalSize != 0) ? logicalSize : sizeAccum;
list.toArray(join.pieces);
return join;
}
/**