in jsign-core/src/main/java/net/jsign/pe/PEFile.java [652:709]
public synchronized void writeDataDirectory(DataDirectoryType type, byte[] data) throws IOException {
DataDirectory directory = getDataDirectory(type);
if (!directory.exists()) {
// append the data directory at the end of the file
long offset = channel.size();
channel.position(offset);
channel.write(ByteBuffer.wrap(data));
// update the entry in the data directory table
directory.write(offset, data.length);
} else {
if (data.length == directory.getSize()) {
// same size as before, just overwrite
channel.position(directory.getVirtualAddress());
channel.write(ByteBuffer.wrap(data));
} else if (data.length < directory.getSize() && type != DataDirectoryType.CERTIFICATE_TABLE) {
// the new data is smaller, erase and rewrite in-place
// this doesn't work with the certificate table since it changes the file digest
directory.erase();
channel.position(directory.getVirtualAddress());
channel.write(ByteBuffer.wrap(data));
// update the size in the data directory table
directory.write(directory.getVirtualAddress(), data.length);
} else if (directory.isTrailing()) {
// the data is at the end of the file, overwrite it
channel.position(directory.getVirtualAddress());
channel.write(ByteBuffer.wrap(data));
channel.truncate(directory.getVirtualAddress() + data.length); // trim the file if the data shrunk
// update the size in the data directory table
directory.write(directory.getVirtualAddress(), data.length);
} else {
if (type == DataDirectoryType.CERTIFICATE_TABLE) {
throw new IOException("The certificate table isn't at the end of the file and can't be moved without invalidating the signature");
}
// the new data is larger, erase and relocate it at the end
directory.erase();
long offset = channel.size();
channel.position(offset);
channel.write(ByteBuffer.wrap(data));
// update the entry in the data directory table
directory.write(offset, data.length);
}
}
updateChecksum();
}