NE Alpha 37

This commit is contained in:
Cr4sh 2016-12-23 01:34:24 +03:00
parent 0e60013311
commit f410b0f969
12 changed files with 121 additions and 52 deletions

View File

@ -18,7 +18,7 @@
UEFITool::UEFITool(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::UEFITool),
version(tr("NE Alpha36"))
version(tr("NE Alpha 37"))
{
clipboard = QApplication::clipboard();
@ -128,7 +128,7 @@ void UEFITool::init()
ui->menuFileActions->setEnabled(false);
ui->menuSectionActions->setEnabled(false);
ui->menuStoreActions->setEnabled(false);
ui->menuVariableActions->setEnabled(false);
ui->menuEntryActions->setEnabled(false);
ui->menuMessageActions->setEnabled(false);
// Create new model ...
@ -182,7 +182,7 @@ void UEFITool::populateUi(const QModelIndex &current)
ui->menuVolumeActions->setEnabled(type == Types::Volume);
ui->menuFileActions->setEnabled(type == Types::File);
ui->menuSectionActions->setEnabled(type == Types::Section);
ui->menuVariableActions->setEnabled(type == Types::NvarEntry
ui->menuEntryActions->setEnabled(type == Types::NvarEntry
|| type == Types::VssEntry
|| type == Types::FsysEntry
|| type == Types::EvsaEntry
@ -997,7 +997,7 @@ void UEFITool::contextMenuEvent(QContextMenuEvent* event)
case Types::VssEntry:
case Types::FsysEntry:
case Types::EvsaEntry:
case Types::FlashMapEntry: ui->menuVariableActions->exec(event->globalPos()); break;
case Types::FlashMapEntry: ui->menuEntryActions->exec(event->globalPos()); break;
case Types::VssStore:
case Types::FdcStore:
case Types::FsysStore:
@ -1057,7 +1057,7 @@ void UEFITool::showFitTable()
// Set up the FIT table
ui->fitTableWidget->clear();
ui->fitTableWidget->setRowCount(fitTable.size());
ui->fitTableWidget->setRowCount((int)fitTable.size());
ui->fitTableWidget->setColumnCount(6);
ui->fitTableWidget->setHorizontalHeaderLabels(QStringList() << tr("Address") << tr("Size") << tr("Version") << tr("Checksum") << tr("Type") << tr("Information"));
ui->fitTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
@ -1070,7 +1070,7 @@ void UEFITool::showFitTable()
for (UINT8 j = 0; j < 6; j++) {
QTableWidgetItem* item = new QTableWidgetItem(fitTable[i].first[j]);
item->setData(Qt::UserRole, fitTable[i].second);
ui->fitTableWidget->setItem(i, j, item);
ui->fitTableWidget->setItem((int)i, j, item);
}
}

View File

@ -8,10 +8,12 @@ DEFINES += "U_ENABLE_NVRAM_PARSING_SUPPORT"
HEADERS += uefitool.h \
searchdialog.h \
hexviewdialog.h \
gotooffsetdialog.h \
guidlineedit.h \
ffsfinder.h \
../common/nvram.h \
../common/nvramparser.h \
../common/meparser.h \
../common/ffsops.h \
../common/basetypes.h \
../common/descriptor.h \
@ -35,8 +37,7 @@ HEADERS += uefitool.h \
../common/ubytearray.h \
../qhexedit2/qhexedit.h \
../qhexedit2/chunks.h \
../qhexedit2/commands.h \
gotooffsetdialog.h
../qhexedit2/commands.h
SOURCES += uefitool_main.cpp \
uefitool.cpp \

View File

@ -272,8 +272,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>851</width>
<height>21</height>
<width>850</width>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@ -428,12 +428,12 @@
<addaction name="separator"/>
<addaction name="actionMessagesClear"/>
</widget>
<widget class="QMenu" name="menuVariableActions">
<widget class="QMenu" name="menuEntryActions">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title">
<string>Variable</string>
<string>Entry</string>
</property>
<addaction name="actionHexView"/>
<addaction name="actionBodyHexView"/>
@ -485,8 +485,9 @@
<addaction name="menuVolumeActions"/>
<addaction name="menuFileActions"/>
<addaction name="menuSectionActions"/>
<addaction name="separator"/>
<addaction name="menuStoreActions"/>
<addaction name="menuVariableActions"/>
<addaction name="menuEntryActions"/>
<addaction name="separator"/>
<addaction name="menuMessageActions"/>
</widget>

View File

@ -14,7 +14,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <map>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <inttypes.h>
#include "descriptor.h"
@ -49,7 +49,7 @@ USTATUS FfsParser::parse(const UByteArray & buffer)
if (lastVtf.isValid())
result = performSecondPass(root);
else
msg(("parse: not a single Volume Top File is found, the image may be corrupted"));
msg(UString("parse: not a single Volume Top File is found, the image may be corrupted"));
return result;
}
@ -298,7 +298,7 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l
// Check for Gigabyte specific descriptor map
if (bios.length == (UINT32)intelImage.size()) {
if (!me.offset) {
msg(("parseIntelImage: can't determine BIOS region start from Gigabyte-specific descriptor"));
msg(UString("parseIntelImage: can't determine BIOS region start from Gigabyte-specific descriptor"));
return U_INVALID_FLASH_DESCRIPTOR;
}
// Use ME region end as BIOS region offset
@ -314,7 +314,7 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l
regions.push_back(bios);
}
else {
msg(("parseIntelImage: descriptor parsing failed, BIOS region not found in descriptor"));
msg(UString("parseIntelImage: descriptor parsing failed, BIOS region not found in descriptor"));
return U_INVALID_FLASH_DESCRIPTOR;
}
@ -432,9 +432,9 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l
for (size_t i = 1; i < regions.size(); i++) {
UINT32 previousRegionEnd = regions[i-1].offset + regions[i-1].length;
// Check that current region is fully present in the image
if (regions[i].offset + regions[i].length > (UINT32)intelImage.size()) {
if ((UINT64)regions[i].offset + (UINT64)regions[i].length > (UINT64)intelImage.size()) {
msg(UString("parseIntelImage: ") + itemSubtypeToUString(Types::Region, regions[i].type)
+ UString(" region is located outside of opened image, if your system uses dual-chip storage, please append another part to the opened image"),
+ UString(" region is located outside of the opened image. If your system uses dual-chip storage, please append another part to the opened image"),
index);
return U_TRUNCATED_IMAGE;
}
@ -453,12 +453,12 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l
region.data = intelImage.mid(region.offset, region.length);
region.type = getPaddingType(region.data);
std::vector<REGION_INFO>::iterator iter = regions.begin();
std::advance(iter, i - 1);
std::advance(iter, i);
regions.insert(iter, region);
}
}
// Check for padding after the last region
if (regions.back().offset + regions.back().length < (UINT32)intelImage.size()) {
if ((UINT64)regions.back().offset + (UINT64)regions.back().length < (UINT64)intelImage.size()) {
region.offset = regions.back().offset + regions.back().length;
region.length = intelImage.size() - region.offset;
region.data = intelImage.mid(region.offset, region.length);
@ -609,7 +609,7 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l
result = U_SUCCESS;
} break;
default:
msg(("parseIntelImage: region of unknown type found"), index);
msg(UString("parseIntelImage: region of unknown type found"), index);
result = U_INVALID_FLASH_DESCRIPTOR;
}
// Store the first failed result as a final result
@ -702,6 +702,9 @@ USTATUS FfsParser::parseMeRegion(const UByteArray & me, const UINT32 localOffset
else if (!versionFound) {
msg(UString("parseMeRegion: ME version is unknown, it can be damaged"), index);
}
else {
meParser.parseMeRegionBody(index);
}
return U_SUCCESS;
}
@ -1020,8 +1023,8 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
UByteArray header = volume.left(headerSize);
UByteArray body = volume.mid(headerSize);
UString name = guidToUString(volumeHeader->FileSystemGuid);
UString info = usprintf("Signature: _FVH\nZeroVector:\n%02X %02X %02X %02X %02X %02X %02X %02X\n"
"%02X %02X %02X %02X %02X %02X %02X %02X\nFileSystem GUID: ",
UString info = usprintf("ZeroVector:\n%02X %02X %02X %02X %02X %02X %02X %02X\n"
"%02X %02X %02X %02X %02X %02X %02X %02X\nSignature: _FVH\nFileSystem GUID: ",
volumeHeader->ZeroVector[0], volumeHeader->ZeroVector[1], volumeHeader->ZeroVector[2], volumeHeader->ZeroVector[3],
volumeHeader->ZeroVector[4], volumeHeader->ZeroVector[5], volumeHeader->ZeroVector[6], volumeHeader->ZeroVector[7],
volumeHeader->ZeroVector[8], volumeHeader->ZeroVector[9], volumeHeader->ZeroVector[10], volumeHeader->ZeroVector[11],
@ -1618,7 +1621,7 @@ USTATUS FfsParser::parsePadFileBody(const UModelIndex & index)
UString info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
// Add tree item
UModelIndex dataIndex = model->addItem(model->offset(index) + nonEmptyByteOffset, Types::Padding, Subtypes::DataPadding, UString("Non-UEFI data"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
UModelIndex dataIndex = model->addItem(model->offset(index) + model->header(index).size() + nonEmptyByteOffset, Types::Padding, Subtypes::DataPadding, UString("Non-UEFI data"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
// Show message
msg(UString("parsePadFileBody: non-UEFI data found in pad-file"), dataIndex);
@ -2387,7 +2390,6 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index)
if (baGuid == EFI_GUIDED_SECTION_TIANO) {
USTATUS result = decompress(model->body(index), EFI_STANDARD_COMPRESSION, algorithm, processed, efiDecompressed);
if (result) {
parseCurrentSection = false;
msg(UString("parseGuidedSectionBody: decompression failed with error ") + errorCodeToUString(result), index);
return U_SUCCESS;
}
@ -2416,7 +2418,6 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index)
else if (baGuid == EFI_GUIDED_SECTION_LZMA || baGuid == EFI_GUIDED_SECTION_LZMAF86) {
USTATUS result = decompress(model->body(index), EFI_CUSTOMIZED_COMPRESSION, algorithm, processed, efiDecompressed);
if (result) {
parseCurrentSection = false;
msg(UString("parseGuidedSectionBody: decompression failed with error ") + errorCodeToUString(result), index);
return U_SUCCESS;
}
@ -2764,7 +2765,7 @@ USTATUS FfsParser::parseTeImageSectionBody(const UModelIndex & index)
// Get section body
UByteArray body = model->body(index);
if ((UINT32)body.size() < sizeof(EFI_IMAGE_TE_HEADER)) {
msg(("parsePeImageSectionBody: section body size is smaller than TE header size"), index);
msg(UString("parsePeImageSectionBody: section body size is smaller than TE header size"), index);
return U_SUCCESS;
}
@ -2878,6 +2879,7 @@ USTATUS FfsParser::parseFit(const UModelIndex & index, const UINT32 diff)
// Calculate FIT entry checksum
UByteArray tempFIT = model->body(fitIndex).mid(fitOffset, fitSize);
FIT_ENTRY* tempFitHeader = (FIT_ENTRY*)tempFIT.data();
tempFitHeader->Type &= 0x7F; // Remove ChecksumValid bit before calculating the checksum
tempFitHeader->Checksum = 0;
UINT8 calculated = calculateChecksum8((const UINT8*)tempFitHeader, fitSize);
if (calculated != fitHeader->Checksum) {
@ -2887,8 +2889,7 @@ USTATUS FfsParser::parseFit(const UModelIndex & index, const UINT32 diff)
// Check fit header type
if ((fitHeader->Type & 0x7F) != FIT_TYPE_HEADER)
msg(("Invalid FIT header type"), fitIndex);
msg(UString("Invalid FIT header type"), fitIndex);
// Add FIT header
std::vector<UString> currentStrings;
@ -2902,11 +2903,10 @@ USTATUS FfsParser::parseFit(const UModelIndex & index, const UINT32 diff)
// Process all other entries
bool msgModifiedImageMayNotWork = false;
UModelIndex itemIndex;
UString info;
for (UINT32 i = 1; i < fitHeader->Size; i++) {
currentStrings.clear();
info.clear();
UString info;
UModelIndex itemIndex;
const FIT_ENTRY* currentEntry = fitHeader + i;
UINT32 currentEntrySize = currentEntry->Size;
@ -2922,7 +2922,7 @@ USTATUS FfsParser::parseFit(const UModelIndex & index, const UINT32 diff)
case FIT_TYPE_MICROCODE: {
//TODO: refactor into function with error reporting
if (currentEntry->Address > diff && currentEntry->Address < 0xFFFFFFFFUL) {
UINT32 offset = currentEntry->Address - diff;
UINT32 offset = (UINT32)currentEntry->Address - diff;
UModelIndex mcIndex = model->findByOffset(offset);
UByteArray mcFile = model->header(mcIndex) + model->body(mcIndex) + model->tail(mcIndex);
@ -2961,6 +2961,11 @@ USTATUS FfsParser::parseFit(const UModelIndex & index, const UINT32 diff)
case FIT_TYPE_AC_KEY_MANIFEST:
case FIT_TYPE_AC_BOOT_POLICY:
default:
if (currentEntry->Address > diff && currentEntry->Address < 0xFFFFFFFFUL) {
UINT32 offset = (UINT32)currentEntry->Address - diff;
itemIndex = model->findByOffset(offset);
}
msgModifiedImageMayNotWork = true;
break;
}

View File

@ -20,18 +20,21 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "ubytearray.h"
#include "treemodel.h"
#include "nvramparser.h"
#include "meparser.h"
class FfsParser
{
public:
// Default constructor and destructor
FfsParser(TreeModel* treeModel) : model(treeModel), nvramParser(treeModel), capsuleOffsetFixup(0) {}
FfsParser(TreeModel* treeModel) : model(treeModel), nvramParser(treeModel), meParser(treeModel), capsuleOffsetFixup(0) {}
~FfsParser() {}
// Returns messages
std::vector<std::pair<UString, UModelIndex> > getMessages() const {
std::vector<std::pair<UString, UModelIndex> > meVector = meParser.getMessages();
std::vector<std::pair<UString, UModelIndex> > nvramVector = nvramParser.getMessages();
std::vector<std::pair<UString, UModelIndex> > resultVector = messagesVector;
resultVector.insert(resultVector.end(), meVector.begin(), meVector.end());
resultVector.insert(resultVector.end(), nvramVector.begin(), nvramVector.end());
return resultVector;
}
@ -53,6 +56,7 @@ private:
};
NvramParser nvramParser;
MeParser meParser;
UModelIndex lastVtf;
UINT32 capsuleOffsetFixup;

43
common/meparser.h Normal file
View File

@ -0,0 +1,43 @@
/* meparser.h
Copyright (c) 2016, Nikolaj Schlej. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#ifndef MEPARSER_H
#define MEPARSER_H
#include <vector>
#include "basetypes.h"
#include "ustring.h"
#include "ubytearray.h"
#include "treemodel.h"
#include "me.h"
// TODO: implement ME region parser
class MeParser
{
public:
// Default constructor and destructor
MeParser(TreeModel* treeModel) { U_UNUSED_PARAMETER(treeModel); }
~MeParser() {}
// Returns messages
std::vector<std::pair<UString, UModelIndex> > getMessages() const { return std::vector<std::pair<UString, UModelIndex> >(); }
// Clears messages
void clearMessages() {}
// ME parsing
USTATUS parseMeRegionBody(const UModelIndex & index) { U_UNUSED_PARAMETER(index); return U_SUCCESS; }
};
#endif // MEPARSER_H

View File

@ -1468,7 +1468,10 @@ USTATUS NvramParser::parseFsysStoreBody(const UModelIndex & index)
UINT32 variableSize = 0;
// Get nameSize and name of the variable
const UINT8 nameSize = *(UINT8*)(data.constData() + offset);
UINT8 nameSize = *(UINT8*)(data.constData() + offset);
bool valid = !(nameSize & 0x80); // Last bit is a validity bit, 0 means valid
nameSize &= 0x7F;
// Check sanity
if (unparsedSize >= nameSize + sizeof(UINT8)) {
variableSize = nameSize + sizeof(UINT8);
@ -1484,11 +1487,10 @@ USTATUS NvramParser::parseFsysStoreBody(const UModelIndex & index)
UString info = usprintf("Full size: %Xh (%u)", header.size(), header.size());
// Add EOF tree item
model->addItem(localOffset + offset, Types::FsysEntry, 0, UString("EOF"), UString(), info, header, UByteArray(), UByteArray(), Fixed, index);
model->addItem(localOffset + offset, Types::FsysEntry, Subtypes::NormalFsysEntry, UString("EOF"), UString(), info, header, UByteArray(), UByteArray(), Fixed, index);
// Add free space
offset += header.size();
unparsedSize = dataSize - offset;
UByteArray body = data.mid(offset);
info = usprintf("Full size: %Xh (%u)", body.size(), body.size());
@ -1529,7 +1531,7 @@ USTATUS NvramParser::parseFsysStoreBody(const UModelIndex & index)
body.size(), body.size());
// Add tree item
model->addItem(localOffset + offset, Types::FsysEntry, 0, UString(name.constData()), UString(), info, header, body, UByteArray(), Movable, index);
model->addItem(localOffset + offset, Types::FsysEntry, valid ? Subtypes::NormalFsysEntry : Subtypes::InvalidFsysEntry, UString(name.constData()), UString(), info, header, body, UByteArray(), Movable, index);
// Move to next variable
offset += variableSize;

View File

@ -10,6 +10,7 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include "ustring.h"
#include "types.h"
#include "ffs.h"
#include "fit.h"
@ -75,7 +76,6 @@ UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype)
case Types::FtwStore:
case Types::FlashMapStore:
case Types::CmdbStore:
case Types::FsysEntry:
case Types::SlicData: return UString();
case Types::Image:
if (subtype == Subtypes::IntelImage) return UString("Intel");
@ -114,6 +114,10 @@ UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype)
if (subtype == Subtypes::AppleVssEntry) return UString("Apple");
if (subtype == Subtypes::AuthVssEntry) return UString("Auth");
break;
case Types::FsysEntry:
if (subtype == Subtypes::InvalidFsysEntry) return UString("Invalid");
if (subtype == Subtypes::NormalFsysEntry) return UString("Normal");
break;
case Types::EvsaEntry:
if (subtype == Subtypes::InvalidEvsaEntry) return UString("Invalid");
if (subtype == Subtypes::UnknownEvsaEntry) return UString("Unknown");

View File

@ -15,7 +15,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define TYPES_H
#include "basetypes.h"
#include "ustring.h"
// Actions
namespace Actions
@ -115,8 +114,13 @@ namespace Subtypes {
AuthVssEntry
};
enum FsysEntrySubtypes {
InvalidFsysEntry = 150,
NormalFsysEntry
};
enum EvsaEntrySubtypes {
InvalidEvsaEntry = 150,
InvalidEvsaEntry = 160,
UnknownEvsaEntry,
GuidEvsaEntry,
NameEvsaEntry,
@ -124,17 +128,17 @@ namespace Subtypes {
};
enum FlashMapEntrySubtypes {
VolumeFlashMapEntry = 160,
VolumeFlashMapEntry = 170,
DataFlashMapEntry
};
enum MicrocodeSubtypes {
IntelMicrocode = 170,
IntelMicrocode = 180,
AmdMicrocode
};
enum SlicDataSubtypes {
PubkeySlicData = 180,
PubkeySlicData = 190,
MarkerSlicData
};
}

View File

@ -19,7 +19,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define UByteArray QByteArray
#else
// Use own implementation
#include <cstdint>
#include <stdint.h>
#include <string>
#include <vector>
#include <algorithm>

View File

@ -11,7 +11,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include "ustring.h"
#include <cstdarg>
#include <stdarg.h>
#if defined(QT_CORE_LIB)
UString usprintf(const char* fmt, ...)

View File

@ -519,7 +519,7 @@ void QHexEdit::keyPressEvent(QKeyEvent *event)
{
/* Hex input */
int key = int(event->text()[0].toLatin1());
if ((key>='0' && key<='9') || (key>='a' && key <= 'f'))
if ((key >= '0' && key <= '9') || (key >= 'a' && key <= 'f') || (key >= 'A' && key <= 'F'))
{
if (getSelectionBegin() != getSelectionEnd())
{
@ -828,10 +828,15 @@ void QHexEdit::paintEvent(QPaintEvent *event)
}
// paint cursor
if (_blink && !_readOnly && hasFocus())
if (_blink && !_readOnly && hasFocus()) {
painter.fillRect(_cursorRect, this->palette().color(QPalette::WindowText));
else
painter.drawText(_pxCursorX, _pxCursorY, _hexDataShown.mid(_cursorPosition - _bPosFirst * 2, 1));
}
else {
QByteArray dataShown = _hexDataShown.mid(_cursorPosition - _bPosFirst * 2, 1);
if (_upperCase)
dataShown = dataShown.toUpper();
painter.drawText(_pxCursorX, _pxCursorY, dataShown);
}
// emit event, if size has changed
if (_lastEventSize != _chunks->size())