Show a popup when xbe sections are corrupted
This commit is contained in:
parent
ed57ca9788
commit
9e90a2df50
|
@ -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: {
|
||||
|
|
|
@ -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 =============
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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(§ion_header.bzSectionDigest[0], 0, 20));
|
||||
text.append("\n");
|
||||
return text;
|
||||
}
|
||||
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue