Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions UEFITool/ffsfinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/

#include "ffsfinder.h"
#include "../common/utility.h"

#if QT_VERSION_MAJOR >= 6
#include <QRegularExpression>
Expand All @@ -36,7 +37,7 @@ USTATUS FfsFinder::findHexPattern(const UModelIndex & index, const UByteArray &
return U_INVALID_PARAMETER;

// Check for "all substrings" pattern
if (hexPattern.count('.') == hexPattern.length())
if (uniformByte(hexPattern) == '.')
return U_SUCCESS;

USTATUS ret = U_ITEM_NOT_FOUND;
Expand Down Expand Up @@ -165,7 +166,7 @@ USTATUS FfsFinder::findGuidPattern(const UModelIndex & index, const UByteArray &
hexPattern.append(list.at(3)).append(list.at(4));

// Check for "all substrings" pattern
if (hexPattern.count('.') == hexPattern.length())
if (uniformByte(hexPattern) == '.')
return U_SUCCESS;

#if QT_VERSION_MAJOR >= 6
Expand Down
54 changes: 19 additions & 35 deletions common/ffsparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -709,15 +709,11 @@ USTATUS FfsParser::parseMeRegion(const UByteArray & me, const UINT32 localOffset
bool versionFound = true;
bool emptyRegion = false;
// Check for empty region
if (me.size() == me.count('\xFF')) {
auto c = uniformByte(me);
if (c <= UINT8_MAX) {
// Further parsing not needed
emptyRegion = true;
info += ("\nState: empty (FFh)");
}
else if (me.size() == me.count('\x00')) {
// Further parsing not needed
emptyRegion = true;
info += ("\nState: empty (00h)");
info += usprintf("\nState: empty (%02Xh)", (UINT8)c);
}
else {
// Search for new signature
Expand Down Expand Up @@ -778,17 +774,13 @@ USTATUS FfsParser::parsePdrRegion(const UByteArray & pdr, const UINT32 localOffs

// Check for empty region
bool emptyRegion = false;
if (pdr.size() == pdr.count('\xFF')) {
// Further parsing not needed
emptyRegion = true;
info += ("\nState: empty (FFh)");
}
else if (pdr.size() == pdr.count('\x00')) {
auto c = uniformByte(pdr);
if (c <= UINT8_MAX) {
// Further parsing not needed
emptyRegion = true;
info += ("\nState: empty (00h)");
info += usprintf("\nState: empty (%02Xh)", (UINT8)c);
}

// Add tree item
index = model->addItem(localOffset, Types::Region, Subtypes::PdrRegion, name, UString(), info, UByteArray(), pdr, UByteArray(), Fixed, parent);

Expand All @@ -814,15 +806,11 @@ USTATUS FfsParser::parseDevExp1Region(const UByteArray & devExp1, const UINT32 l

// Check for empty region
bool emptyRegion = false;
if (devExp1.size() == devExp1.count('\xFF')) {
auto c = uniformByte(devExp1);
if (c <= UINT8_MAX) {
// Further parsing not needed
emptyRegion = true;
info += ("\nState: empty (FFh)");
}
else if (devExp1.size() == devExp1.count('\x00')) {
// Further parsing not needed
emptyRegion = true;
info += ("\nState: empty (00h)");
info += usprintf("\nState: empty (%02Xh)", (UINT8)c);
}

// Add tree item
Expand All @@ -846,17 +834,13 @@ USTATUS FfsParser::parseGenericRegion(const UINT8 subtype, const UByteArray & re

// Check for empty region
bool emptyRegion = false;
if (region.size() == region.count('\xFF')) {
// Further parsing not needed
emptyRegion = true;
info += ("\nState: empty (FFh)");
}
else if (region.size() == region.count('\x00')) {
auto c = uniformByte(region);
if (c <= UINT8_MAX) {
// Further parsing not needed
emptyRegion = true;
info += ("\nState: empty (00h)");
info += usprintf("\nState: empty (%02Xh)", (UINT8)c);
}

// Add tree item
index = model->addItem(localOffset, Types::Region, subtype, name, UString(), info, UByteArray(), region, UByteArray(), Fixed, parent);

Expand Down Expand Up @@ -1166,7 +1150,7 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());

// Check that remaining unparsed bytes are actually empty
if (freeSpace.count(emptyByte) == freeSpace.size()) { // Free space
if (uniformByte(freeSpace) == emptyByte) { // Free space
// Add tree item
model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex);
}
Expand Down Expand Up @@ -1972,7 +1956,7 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index)

// Check that we are at the empty space
UByteArray header = volumeBody.mid(fileOffset, (int)std::min(sizeof(EFI_FFS_FILE_HEADER), (size_t)volumeBodySize - fileOffset));
if (header.count(emptyByte) == header.size()) { //Empty space
if (uniformByte(header) == emptyByte) { // Empty space
// Check volume usedSpace entry to be valid
if (usedSpace > 0 && usedSpace == fileOffset + volumeHeaderSize) {
if (model->hasEmptyParsingData(index) == false) {
Expand All @@ -1986,7 +1970,7 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index)

// Check free space to be actually free
UByteArray freeSpace = volumeBody.mid(fileOffset);
if (freeSpace.count(emptyByte) != freeSpace.size()) {
if (uniformByte(freeSpace) != emptyByte) {
// Search for the first non-empty byte
UINT32 i;
UINT32 size = (UINT32)freeSpace.size();
Expand Down Expand Up @@ -2440,7 +2424,7 @@ USTATUS FfsParser::parsePadFileBody(const UModelIndex & index)
}

// Check if the while padding file is empty
if (body.size() == body.count(emptyByte))
if (uniformByte(body) == emptyByte)
return U_SUCCESS;

// Search for the first non-empty byte
Expand Down Expand Up @@ -4501,7 +4485,7 @@ USTATUS FfsParser::parseMicrocodeVolumeBody(const UModelIndex & index)
UByteArray ucode = model->body(index).mid(offset);

// Check for empty area
if (ucode.size() == ucode.count('\xFF') || ucode.size() == ucode.count('\x00')) {
if (getPaddingType(ucode) != Subtypes::DataPadding) {
result = U_INVALID_MICROCODE;
}
else {
Expand Down
9 changes: 3 additions & 6 deletions common/fitparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -709,8 +709,7 @@ USTATUS FitParser::parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolic
else {
// Add postIbbHash protected range
UByteArray postIbbHash(ibbs_body->post_ibb_hash()->hash().data(), ibbs_body->post_ibb_hash()->len_hash());
if (postIbbHash.count('\x00') != postIbbHash.size()
&& postIbbHash.count('\xFF') != postIbbHash.size()) {
if (getPaddingType(postIbbHash) == Subtypes::DataPadding) {
PROTECTED_RANGE range = {};
range.Type = PROTECTED_RANGE_INTEL_BOOT_GUARD_POST_IBB;
range.AlgorithmId = ibbs_body->post_ibb_hash()->hash_algorithm_id();
Expand Down Expand Up @@ -990,8 +989,7 @@ USTATUS FitParser::parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolic
else {
// Add postIbbHash protected range
UByteArray postIbbHash(ibbs_body->post_ibb_digest()->hash().data(), ibbs_body->post_ibb_digest()->len_hash());
if (postIbbHash.count('\x00') != postIbbHash.size()
&& postIbbHash.count('\xFF') != postIbbHash.size()) {
if (getPaddingType(postIbbHash) == Subtypes::DataPadding) {
PROTECTED_RANGE range = {};
range.Type = PROTECTED_RANGE_INTEL_BOOT_GUARD_POST_IBB;
range.AlgorithmId = ibbs_body->post_ibb_digest()->hash_algorithm_id();
Expand Down Expand Up @@ -1021,8 +1019,7 @@ USTATUS FitParser::parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolic

// Add ObbHash protected range
UByteArray obbHash(ibbs_body->obb_digest()->hash().data(), ibbs_body->obb_digest()->len_hash());
if (obbHash.count('\x00') != obbHash.size()
&& obbHash.count('\xFF') != obbHash.size()) {
if (getPaddingType(obbHash) == Subtypes::DataPadding) {
PROTECTED_RANGE range = {};
range.Type = PROTECTED_RANGE_INTEL_BOOT_GUARD_OBB;
range.AlgorithmId = ibbs_body->obb_digest()->hash_algorithm_id();
Expand Down
12 changes: 6 additions & 6 deletions common/nvramparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
// Get info
UString info = usprintf("Full size: %Xh (%u)", (UINT32)padding.size(), (UINT32)padding.size());

if ((UINT32)padding.count(emptyByte) == unparsedSize) { // Free space
if (uniformByte(padding) == emptyByte) { // Free space
// Add tree item
model->addItem(localOffset + entry->offset(), Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
}
Expand Down Expand Up @@ -422,7 +422,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());

// Check that remaining unparsed bytes are actually empty
if (freeSpace.count(emptyByte) == freeSpace.size()) { // Free space
if (uniformByte(freeSpace) == emptyByte) { // Free space
// Add tree item
model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex);
}
Expand Down Expand Up @@ -625,7 +625,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());

// Check that remaining unparsed bytes are actually empty
if (freeSpace.count(emptyByte) == freeSpace.size()) { // Free space
if (uniformByte(freeSpace) == emptyByte) { // Free space
// Add tree item
model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex);
}
Expand Down Expand Up @@ -951,7 +951,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());

// Check that remaining unparsed bytes are actually zeroes
if (freeSpace.count('\x00') == freeSpace.size() - 4) { // Free space, 4 last bytes are always CRC32
if (uniformByte(freeSpace.left(freeSpace.size() - 4)) == 0) { // Free space, 4 last bytes are always CRC32
// Add tree item
model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex);
}
Expand Down Expand Up @@ -1121,7 +1121,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());

// Check that remaining unparsed bytes are actually empty
if (freeSpace.count(emptyByte) == freeSpace.size()) { // Free space
if (uniformByte(freeSpace) == emptyByte) { // Free space
// Add tree item
model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex);
}
Expand Down Expand Up @@ -1526,7 +1526,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
UString info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size());

// Check that remaining unparsed bytes are actually empty
if (outerPadding.count(emptyByte) == outerPadding.size()) {
if (uniformByte(outerPadding) == emptyByte) {
// Add tree item
model->addItem(localOffset + previousStoreEndOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), outerPadding, UByteArray(), Fixed, index);
}
Expand Down
1 change: 0 additions & 1 deletion common/ubytearray.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ class UByteArray
uint32_t toUInt(bool* ok = NULL, const uint8_t base = 10) { return (uint32_t)strtoul(d.c_str(), NULL, base); }

int32_t size() const { return (int32_t)d.size(); }
int32_t count(char ch) const { return (int32_t)std::count(d.begin(), d.end(), ch); }
char at(uint32_t i) const { return d.at(i); }
char operator[](uint32_t i) const { return d[i]; }
char& operator[](uint32_t i) { return d[i]; }
Expand Down
19 changes: 15 additions & 4 deletions common/utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,13 +429,24 @@ UINT32 calculateChecksum32(const UINT32* buffer, UINT32 bufferSize)
return (UINT32)(0x100000000ULL - counter);
}

// Returns 0x00..0xFF if an array is filled by a single repeated value, and 0xFFFFFFFF if not
UINT32 uniformByte(const UByteArray& a)
{
size_t s = a.size();
if ((s == 1) || (s > 1 && memcmp(a.constData(), a.constData() + 1, s - 1) == 0))
return (UINT8)a.at(0);
return UINT32_MAX;
}

// Get padding type for a given padding
UINT8 getPaddingType(const UByteArray & padding)
{
if (padding.count('\x00') == padding.size())
return Subtypes::ZeroPadding;
if (padding.count('\xFF') == padding.size())
return Subtypes::OnePadding;
switch (uniformByte(padding)) {
case 0:
return Subtypes::ZeroPadding;
case 0xFF:
return Subtypes::OnePadding;
}
return Subtypes::DataPadding;
}

Expand Down
3 changes: 3 additions & 0 deletions common/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ UINT16 calculateChecksum16(const UINT16* buffer, UINT32 bufferSize);
// 32bit checksum calculation routine
UINT32 calculateChecksum32(const UINT32* buffer, UINT32 bufferSize);

// Returns 0x00..0xFF if an array is filled by a single repeated value, and 0xFFFFFFFF if not
UINT32 uniformByte(const UByteArray& a);

// Returns padding type from it's contents
UINT8 getPaddingType(const UByteArray & padding);

Expand Down
Loading