Show a popup when xbe sections are corrupted

This commit is contained in:
ergo720 2020-06-23 20:23:37 +02:00
parent ed57ca9788
commit 9e90a2df50
10 changed files with 86 additions and 32 deletions

View File

@ -278,7 +278,7 @@ PopupReturn PopupCustomEx(const void* hwnd, const CXBXR_MODULE cxbxr_module, con
UINT uType = MB_TOPMOST | MB_SETFOREGROUND;
// Make assert whenever the format string is null pointer which isn't allow in here.
assert(!message);
assert(message != nullptr);
switch (icon) {
case PopupIcon::Warning: {

View File

@ -82,7 +82,8 @@ static struct {
const char* RecentXbeFiles = "RecentXbeFiles";
const char* DataStorageToggle = "DataStorageToggle";
const char* DataCustomLocation = "DataCustomLocation";
const char* IgnoreInvalidXbeSig = "IgnoreInvalidXbeSig";
const char* IgnoreInvalidXbeSig = "IgnoreInvalidXbeSig";
const char *IgnoreInvalidXbeSec = "IgnoreInvalidXbeSec";
} sect_gui_keys;
static const char* section_core = "core";
@ -315,7 +316,8 @@ bool Settings::LoadConfig()
index++;
}
m_gui.bIgnoreInvalidXbeSig = m_si.GetBoolValue(section_gui, sect_gui_keys.IgnoreInvalidXbeSig, /*Default=*/false);
m_gui.bIgnoreInvalidXbeSig = m_si.GetBoolValue(section_gui, sect_gui_keys.IgnoreInvalidXbeSig, /*Default=*/false);
m_gui.bIgnoreInvalidXbeSec = m_si.GetBoolValue(section_gui, sect_gui_keys.IgnoreInvalidXbeSec, /*Default=*/false);
// ==== GUI End =============
@ -517,7 +519,8 @@ bool Settings::Save(std::string file_path)
m_si.SetValue(section_gui, sect_gui_keys.RecentXbeFiles, m_gui.szRecentXbeFiles[i].c_str(), nullptr, false);
}
m_si.SetBoolValue(section_gui, sect_gui_keys.IgnoreInvalidXbeSig, m_gui.bIgnoreInvalidXbeSig, nullptr, true);
m_si.SetBoolValue(section_gui, sect_gui_keys.IgnoreInvalidXbeSig, m_gui.bIgnoreInvalidXbeSig, nullptr, true);
m_si.SetBoolValue(section_gui, sect_gui_keys.IgnoreInvalidXbeSec, m_gui.bIgnoreInvalidXbeSec, nullptr, true);
// ==== GUI End =============

View File

@ -88,7 +88,8 @@ public:
std::string szRecentXbeFiles[10];
unsigned int DataStorageToggle;
std::string szCustomLocation = "";
bool bIgnoreInvalidXbeSig;
bool bIgnoreInvalidXbeSig;
bool bIgnoreInvalidXbeSec;
} m_gui;
// Core settings

View File

@ -779,7 +779,7 @@ const wchar_t *Xbe::GetUnicodeFilenameAddr()
return (const wchar_t *)GetAddr(m_Header.dwDebugUnicodeFilenameAddr);
}
bool Xbe::CheckXbeSignature()
bool Xbe::CheckSignature()
{
init_tom_lib();
@ -810,6 +810,24 @@ bool Xbe::CheckXbeSignature()
return false; // signature check failed
}
bool Xbe::CheckSectionIntegrity(uint32_t sectionIndex)
{
uint32_t RawSize = m_SectionHeader[sectionIndex].dwSizeofRaw;
if (RawSize == 0) {
return true;
}
unsigned char SHADigest[A_SHA_DIGEST_LEN];
CalcSHA1Hash(SHADigest, m_bzSection[sectionIndex], RawSize);
if (std::memcmp(SHADigest, m_SectionHeader[sectionIndex].bzSectionDigest, A_SHA_DIGEST_LEN) != 0) {
return false;
}
else {
return true;
}
}
// ported from Dxbx's XbeExplorer
XbeType Xbe::GetXbeType()
{

View File

@ -63,8 +63,11 @@ class Xbe : public Error
// export to Xbe file
void Export(const char *x_szXbeFilename);
// verify the integrity of the loaded xbe
bool CheckXbeSignature();
// verify the integrity of the xbe header
bool CheckSignature();
// verify the integrity of an xbe section
bool CheckSectionIntegrity(uint32_t sectionIndex);
// import logo bitmap from raw monochrome data
void ImportLogoBitmap(const uint8_t x_Gray[100*17]);

View File

@ -276,7 +276,7 @@ std::string XbePrinter::GenGeneralHeaderInfo2()
std::string XbePrinter::ValidateXbeSignature()
{
std::string text("\nInvalid xbe signature. Homebrew, tampered or pirated xbe?\n");
if (Xbe_to_print->CheckXbeSignature()) {
if (Xbe_to_print->CheckSignature()) {
text = "\nValid xbe signature. Xbe is legit\n";
}
return text;
@ -416,7 +416,13 @@ std::string XbePrinter::GenSectionHeaders()
text << "Section Reference Count : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwSectionRefCount << "\n";
text << "Head Shared Reference Count Addr : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwHeadSharedRefCountAddr << "\n";
text << "Tail Shared Reference Count Addr : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwTailSharedRefCountAddr << "\n";
text << GenSectionDigest(Xbe_to_print->m_SectionHeader[v]) << "\n";
text << GenSectionDigest(Xbe_to_print->m_SectionHeader[v]) << "\n";
if (Xbe_to_print->CheckSectionIntegrity(v)) {
text << "SHA hash check of section " << Xbe_to_print->m_szSectionName[v] << " successful" << "\n\n";
}
else {
text << "SHA hash of section " << Xbe_to_print->m_szSectionName[v] << " doesn't match, section is corrupted" << "\n\n";
}
}
return text.str();
}
@ -454,7 +460,6 @@ std::string XbePrinter::GenSectionDigest(Xbe::SectionHeader section_header)
std::string text;
text.append("Section Digest : ");
text.append(GenHexRow(&section_header.bzSectionDigest[0], 0, 20));
text.append("\n");
return text;
}

View File

@ -993,7 +993,7 @@ void CxbxKrnlEmulate(unsigned int reserved_systems, blocks_reserved_t blocks_res
}
// Check the signature of the xbe
if (CxbxKrnl_Xbe->CheckXbeSignature()) {
if (CxbxKrnl_Xbe->CheckSignature()) {
EmuLogInit(LOG_LEVEL::INFO, "Valid xbe signature. Xbe is legit");
}
else {
@ -1002,18 +1002,11 @@ void CxbxKrnlEmulate(unsigned int reserved_systems, blocks_reserved_t blocks_res
// Check the integrity of the xbe sections
for (uint32_t sectionIndex = 0; sectionIndex < CxbxKrnl_Xbe->m_Header.dwSections; sectionIndex++) {
uint32_t RawSize = CxbxKrnl_Xbe->m_SectionHeader[sectionIndex].dwSizeofRaw;
if (RawSize == 0) {
continue;
}
unsigned char SHADigest[A_SHA_DIGEST_LEN];
CalcSHA1Hash(SHADigest, CxbxKrnl_Xbe->m_bzSection[sectionIndex], RawSize);
if (memcmp(SHADigest, (CxbxKrnl_Xbe->m_SectionHeader)[sectionIndex].bzSectionDigest, A_SHA_DIGEST_LEN) != 0) {
EmuLogInit(LOG_LEVEL::WARNING, "SHA hash of section %s doesn't match, possible section corruption", CxbxKrnl_Xbe->m_szSectionName[sectionIndex]);
if (CxbxKrnl_Xbe->CheckSectionIntegrity(sectionIndex)) {
EmuLogInit(LOG_LEVEL::INFO, "SHA hash check of section %s successful", CxbxKrnl_Xbe->m_szSectionName[sectionIndex]);
}
else {
EmuLogInit(LOG_LEVEL::INFO, "SHA hash check of section %s successful", CxbxKrnl_Xbe->m_szSectionName[sectionIndex]);
EmuLogInit(LOG_LEVEL::WARNING, "SHA hash of section %s doesn't match, section is corrupted", CxbxKrnl_Xbe->m_szSectionName[sectionIndex]);
}
}

View File

@ -1291,6 +1291,11 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
RefreshMenus();
break;
case ID_SETTINGS_IGNOREINVALIDXBESEC:
g_Settings->m_gui.bIgnoreInvalidXbeSec = !g_Settings->m_gui.bIgnoreInvalidXbeSec;
RefreshMenus();
break;
case ID_SETTINGS_ALLOWADMINPRIVILEGE:
g_Settings->m_core.allowAdminPrivilege = !g_Settings->m_core.allowAdminPrivilege;
RefreshMenus();
@ -1762,6 +1767,9 @@ void WndMain::RefreshMenus()
chk_flag = (g_Settings->m_gui.bIgnoreInvalidXbeSig) ? MF_CHECKED : MF_UNCHECKED;
CheckMenuItem(settings_menu, ID_SETTINGS_IGNOREINVALIDXBESIG, chk_flag);
chk_flag = (g_Settings->m_gui.bIgnoreInvalidXbeSec) ? MF_CHECKED : MF_UNCHECKED;
CheckMenuItem(settings_menu, ID_SETTINGS_IGNOREINVALIDXBESEC, chk_flag);
chk_flag = (g_Settings->m_core.allowAdminPrivilege) ? MF_CHECKED : MF_UNCHECKED;
CheckMenuItem(settings_menu, ID_SETTINGS_ALLOWADMINPRIVILEGE, chk_flag);
}
@ -2001,25 +2009,46 @@ void WndMain::OpenXbe(const char *x_filename)
return;
}
bool invalidXbe = false;
std::string errorMsg = "";
if (!g_Settings->m_gui.bIgnoreInvalidXbeSig && !m_Xbe->CheckXbeSignature())
{
PopupReturn ret = PopupWarningEx(m_hwnd, PopupButtons::YesNo, PopupReturn::No,
"XBE signature check failed!\n"
"\nThis is dangerous, as maliciously modified Xbox titles could take control of your system.\n"
if (!g_Settings->m_gui.bIgnoreInvalidXbeSig && !m_Xbe->CheckSignature()) {
invalidXbe = true;
errorMsg += "- XBE signature check failed!\n";
}
if (!g_Settings->m_gui.bIgnoreInvalidXbeSec) {
for (uint32_t sectionIndex = 0; sectionIndex < m_Xbe->m_Header.dwSections; sectionIndex++) {
if (!m_Xbe->CheckSectionIntegrity(sectionIndex)) {
invalidXbe = true;
errorMsg += "- One or more XBE section(s) are corrupted!\n";
// if we find a corrupted section, we won't bother checking the remaining sections since we know
// already at this point that the xbe is invalid
break;
}
}
}
if (invalidXbe) {
errorMsg += ("\nThis is dangerous, as maliciously modified Xbox applications could take control of your system."
"\nPlease do not report issues for this application.\n"
"\nAre you sure you want to continue?");
PopupReturn ret = PopupWarningEx(m_hwnd, PopupButtons::YesNo, PopupReturn::No, errorMsg.c_str());
if (ret != PopupReturn::Yes)
{
delete m_Xbe; m_Xbe = nullptr;
RedrawWindow(m_hwnd, nullptr, NULL, RDW_INVALIDATE);
UpdateCaption();
return;
}
}
// save this xbe to the list of recent xbe files
if(m_XbeFilename[0] != '\0') {
bool found = false;

View File

@ -679,6 +679,7 @@ BEGIN
END
MENUITEM "Use Loader Executable", ID_USELOADEREXEC,MFT_STRING,MFS_ENABLED
MENUITEM "Ignore Invalid Xbe Signature", ID_SETTINGS_IGNOREINVALIDXBESIG,MFT_STRING,MFS_ENABLED
MENUITEM "Ignore Invalid Xbe Sections", ID_SETTINGS_IGNOREINVALIDXBESEC, MFT_STRING, MFS_ENABLED
MENUITEM "Allow Admin Privilege", ID_SETTINGS_ALLOWADMINPRIVILEGE,MFT_STRING,MFS_ENABLED
MENUITEM "", -1, MFT_SEPARATOR
MENUITEM "Reset To Defaults", ID_SETTINGS_INITIALIZE,MFT_STRING,MFS_ENABLED

View File

@ -365,6 +365,7 @@
#define ID_SETTINGS_EXPERIMENTAL 40113
#define ID_USELOADEREXEC 40114
#define ID_SETTINGS_IGNOREINVALIDXBESIG 40115
#define ID_SETTINGS_IGNOREINVALIDXBESEC 40116
#define IDC_STATIC -1
// Next default values for new objects
@ -372,7 +373,7 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 136
#define _APS_NEXT_COMMAND_VALUE 40116
#define _APS_NEXT_COMMAND_VALUE 40117
#define _APS_NEXT_CONTROL_VALUE 1305
#define _APS_NEXT_SYMED_VALUE 109
#endif