574 lines
23 KiB
C++
574 lines
23 KiB
C++
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
|
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
|
// ******************************************************************
|
|
// *
|
|
// * This file is part of the Cxbx project.
|
|
// *
|
|
// * Cxbx and Cxbe are free software; you can redistribute them
|
|
// * and/or modify them under the terms of the GNU General Public
|
|
// * License as published by the Free Software Foundation; either
|
|
// * version 2 of the license, or (at your option) any later version.
|
|
// *
|
|
// * This program is distributed in the hope that it will be useful,
|
|
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// * GNU General Public License for more details.
|
|
// *
|
|
// * You should have recieved a copy of the GNU General Public License
|
|
// * along with this program; see the file COPYING.
|
|
// * If not, write to the Free Software Foundation, Inc.,
|
|
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
|
|
// *
|
|
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
|
|
// *
|
|
// * All rights reserved
|
|
// *
|
|
// ******************************************************************
|
|
|
|
#include "common\xbe\XbePrinter.h"
|
|
#include "CxbxVersion.h" // For CxbxVersionStr
|
|
|
|
#include <locale> // For ctime
|
|
#include <sstream> // For std::stringstream
|
|
#include <iomanip> // For std::setfill, std::uppercase, std::hex
|
|
#include "common/util/strConverter.hpp" // for utf16le_to_ascii
|
|
|
|
// better time
|
|
static char *BetterTime(uint32_t x_timeDate)
|
|
{
|
|
time_t x_time = x_timeDate;
|
|
char *x_ctime = ctime(&x_time);
|
|
|
|
int v=0;
|
|
|
|
for(v=0;x_ctime[v] != '\n';v++);
|
|
|
|
x_ctime[v] = '\0';
|
|
|
|
return x_ctime;
|
|
}
|
|
|
|
std::string DumpInformation(Xbe* Xbe_object)
|
|
{
|
|
if(Xbe_object->HasError()) {
|
|
return "ERROR";
|
|
}
|
|
XbePrinter printer(Xbe_object);
|
|
return printer.GenXbeInfo();
|
|
}
|
|
|
|
#define SSTREAM_SET_HEX(stream_name) stream_name << std::setfill('0') << std::uppercase << std::hex;
|
|
#define SSTREAM_SET_DEC(stream_name) stream_name << std::setfill('0') << std::uppercase << std::dec;
|
|
|
|
std::string FormatTitleId(uint32_t title_id)
|
|
{
|
|
std::stringstream ss;
|
|
|
|
// If the Title ID prefix is a printable character, parse it
|
|
// This shows the correct game serial number for retail titles!
|
|
// EG: MS-001 for 1st tile published by MS, EA-002 for 2nd title by EA, etc
|
|
// Some special Xbes (Dashboard, XDK Samples) use non-alphanumeric serials
|
|
// We fall back to Hex for those
|
|
// ergo720: we cannot use isalnum() here because it will treat chars in the range -1 - 255 as valid ascii chars which can
|
|
// lead to unicode characters being printed in the title (e.g.: dashboard uses 0xFE and 0xFF)
|
|
uint8_t pTitleId1 = (title_id >> 24) & 0xFF;
|
|
uint8_t pTitleId2 = (title_id >> 16) & 0xFF;
|
|
|
|
if ((pTitleId1 < 65 || pTitleId1 > 90) || (pTitleId2 < 65 || pTitleId2 > 90)) {
|
|
// Prefix was non-printable, so we need to print a hex reprentation of the entire title_id
|
|
ss << std::setfill('0') << std::setw(8) << std::hex << std::uppercase << title_id;
|
|
return ss.str();
|
|
}
|
|
|
|
ss << pTitleId1 << pTitleId2;
|
|
ss << "-";
|
|
ss << std::setfill('0') << std::setw(3) << std::dec << (title_id & 0x0000FFFF);
|
|
|
|
return ss.str();
|
|
}
|
|
|
|
XbePrinter::XbePrinter(Xbe* Xbe_object)
|
|
{
|
|
Xbe_to_print = Xbe_object;
|
|
Xbe_header = &(Xbe_object->m_Header);
|
|
Xbe_certificate = &(Xbe_object->m_Certificate);
|
|
}
|
|
|
|
std::string XbePrinter::GenXbeInfo()
|
|
{
|
|
std::string info;
|
|
info.append(GenDumpHeader());
|
|
info.append(GenXbeHeaderInfo());
|
|
info.append(GenXbeCertificateInfo());
|
|
info.append(ValidateXbeSignature());
|
|
info.append(GenSectionInfo());
|
|
info.append(GenLibraryVersions());
|
|
info.append(GenTLS());
|
|
return info;
|
|
}
|
|
|
|
std::string XbePrinter::GenHexRow(
|
|
uint8_t *signature, const uint8_t row, const uint8_t row_size
|
|
)
|
|
{
|
|
const uint16_t offset = row * row_size;
|
|
std::stringstream text;
|
|
SSTREAM_SET_HEX(text);
|
|
for(uint8_t x = 0; x < row_size; x++) {
|
|
text << std::setw(2) << static_cast<unsigned>(signature[offset + x]);
|
|
}
|
|
return text.str();
|
|
}
|
|
|
|
std::string XbePrinter::AllowedMediaToString()
|
|
{
|
|
const uint32_t dwAllowedMedia = Xbe_certificate->dwAllowedMedia;
|
|
std::string text = "Media Types:";
|
|
|
|
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_MEDIA_MASK) {
|
|
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_HARD_DISK)
|
|
text.append(" HARD_DISK");
|
|
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_X2)
|
|
text.append(" DVD_X2");
|
|
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_CD)
|
|
text.append(" DVD_CD");
|
|
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_CD)
|
|
text.append(" CD");
|
|
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_5_RO)
|
|
text.append(" DVD_5_RO");
|
|
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_9_RO)
|
|
text.append(" DVD_9_RO");
|
|
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_5_RW)
|
|
text.append(" DVD_5_RW");
|
|
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DVD_9_RW)
|
|
text.append(" DVD_9_RW");
|
|
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_DONGLE)
|
|
text.append(" DONGLE");
|
|
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_MEDIA_BOARD)
|
|
text.append(" BOARD");
|
|
if((dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_MEDIA_MASK) >= (XBEIMAGE_MEDIA_TYPE_MEDIA_BOARD * 2))
|
|
text.append(" UNKNOWN");
|
|
}
|
|
|
|
if(dwAllowedMedia & ~XBEIMAGE_MEDIA_TYPE_MEDIA_MASK) {
|
|
text.append(" NONSECURE");
|
|
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_NONSECURE_HARD_DISK)
|
|
text.append(" HARD_DISK");
|
|
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_NONSECURE_MODE)
|
|
text.append(" MODE");
|
|
}
|
|
return text;
|
|
}
|
|
|
|
std::string XbePrinter::GameRatingToString()
|
|
{
|
|
std::string text;
|
|
// Info from: https://xboxdevwiki.net/EEPROM
|
|
switch(Xbe_certificate->dwGameRatings) {
|
|
case 0x0:
|
|
text.append("(RP) Rating Pending");
|
|
break;
|
|
case 0x1:
|
|
text.append("(AO) Adults Only");
|
|
break;
|
|
case 0x2:
|
|
text.append("(M) Mature");
|
|
break;
|
|
case 0x3:
|
|
text.append("(T) Teen");
|
|
break;
|
|
case 0x4:
|
|
text.append("(E) Everyone");
|
|
break;
|
|
case 0x5:
|
|
text.append("(K-A) Kids to Adults");
|
|
break;
|
|
case 0x6:
|
|
text.append("(EC) Early Childhood");
|
|
break;
|
|
default:
|
|
text.append("ERROR: no rating");
|
|
break;
|
|
}
|
|
return text;
|
|
}
|
|
|
|
std::string XbePrinter::GenDumpHeader()
|
|
{
|
|
std::string text;
|
|
text.append("XBE information generated by Cxbx-Reloaded (Version ");
|
|
text.append(CxbxVersionStr);
|
|
text.append(")\n\n");
|
|
text.append("Title identified as \"");
|
|
text.append(Xbe_to_print->m_szAsciiTitle);
|
|
text.append("\"\n\n");
|
|
text.append("Dumping XBE file header...\n\n");
|
|
text.append("Magic Number : XBEH\n");
|
|
return text;
|
|
}
|
|
|
|
std::string XbePrinter::GenXbeHeaderInfo()
|
|
{
|
|
std::string text;
|
|
text.append(GenDigitalSignature());
|
|
text.append(GenGeneralHeaderInfo1());
|
|
text.append(GenInitFlags());
|
|
text.append(GenGeneralHeaderInfo2());
|
|
return text;
|
|
}
|
|
|
|
std::string XbePrinter::GenDigitalSignature()
|
|
{
|
|
const uint8_t row_size = 16;
|
|
std::string text;
|
|
text.append("Digital Signature : <Hex Dump>");
|
|
for(int row = 0; row < 16; row++) {
|
|
text.append("\n ");
|
|
text.append(GenHexRow(&(Xbe_header->pbDigitalSignature[0]), row, row_size));
|
|
}
|
|
text.append("\n </Hex Dump>\n");
|
|
return text;
|
|
}
|
|
|
|
std::string XbePrinter::GenGeneralHeaderInfo1()
|
|
{
|
|
std::stringstream text;
|
|
SSTREAM_SET_HEX(text);
|
|
text << "Base Address : 0x" << std::setw(8) << Xbe_header->dwBaseAddr << "\n";
|
|
text << "Size of Headers : 0x" << std::setw(8) << Xbe_header->dwSizeofHeaders << "\n";
|
|
text << "Size of Image : 0x" << std::setw(8) << Xbe_header->dwSizeofImage << "\n";
|
|
text << "Size of Image Header : 0x" << std::setw(8) << Xbe_header->dwSizeofImageHeader << "\n";
|
|
text << "TimeDate Stamp : 0x" << std::setw(8) << Xbe_header->dwTimeDate << " (" << BetterTime(Xbe_header->dwTimeDate) << ")\n";
|
|
text << "Certificate Address : 0x" << std::setw(8) << Xbe_header->dwCertificateAddr << "\n";
|
|
text << "Number of Sections : 0x" << std::setw(8) << Xbe_header->dwSections << "\n";
|
|
text << "Section Headers Address : 0x" << std::setw(8) << Xbe_header->dwSectionHeadersAddr << "\n";
|
|
return text.str();
|
|
}
|
|
|
|
std::string XbePrinter::GenInitFlags()
|
|
{
|
|
std::stringstream text;
|
|
SSTREAM_SET_HEX(text);
|
|
text << "Init Flags : 0x" << std::setw(8) << Xbe_header->dwInitFlags_value << " ";
|
|
|
|
if(Xbe_header->dwInitFlags.bMountUtilityDrive) {
|
|
text << "[Mount Utility Drive] ";
|
|
}
|
|
if(Xbe_header->dwInitFlags.bFormatUtilityDrive) {
|
|
text << "[Format Utility Drive] ";
|
|
}
|
|
if(Xbe_header->dwInitFlags.bLimit64MB) {
|
|
text << "[Limit Devkit Run Time Memory to 64MB] ";
|
|
}
|
|
if(!Xbe_header->dwInitFlags.bDontSetupHarddisk) {
|
|
text << "[Setup Harddisk] ";
|
|
}
|
|
text << "\n";
|
|
return text.str();
|
|
}
|
|
|
|
std::string XbePrinter::GenGeneralHeaderInfo2()
|
|
{
|
|
const uint32_t retail_entry_point = Xbe_header->dwEntryAddr ^ XOR_EP_RETAIL;
|
|
const uint32_t debug_entry_point = Xbe_header->dwEntryAddr ^ XOR_EP_DEBUG;
|
|
const uint32_t retail_thunk_addr = Xbe_header->dwKernelImageThunkAddr ^ XOR_KT_RETAIL;
|
|
const uint32_t debug_thunk_addr = Xbe_header->dwKernelImageThunkAddr ^ XOR_KT_DEBUG;
|
|
const std::string AsciiFilename = utf16le_to_ascii(Xbe_to_print->GetUnicodeFilenameAddr());
|
|
std::stringstream text;
|
|
SSTREAM_SET_HEX(text);
|
|
text << "Entry Point : 0x" << std::setw(8) << Xbe_header->dwEntryAddr << " (Retail: 0x" << std::setw(8) << retail_entry_point << ", Debug: 0x" << std::setw(8) << debug_entry_point << ")\n";
|
|
text << "TLS Address : 0x" << std::setw(8) << Xbe_header->dwTLSAddr << "\n";
|
|
text << "(PE) Stack Commit : 0x" << std::setw(8) << Xbe_header->dwPeStackCommit << "\n";
|
|
text << "(PE) Heap Reserve : 0x" << std::setw(8) << Xbe_header->dwPeHeapReserve << "\n";
|
|
text << "(PE) Heap Commit : 0x" << std::setw(8) << Xbe_header->dwPeHeapCommit << "\n";
|
|
text << "(PE) Base Address : 0x" << std::setw(8) << Xbe_header->dwPeBaseAddr << "\n";
|
|
text << "(PE) Size of Image : 0x" << std::setw(8) << Xbe_header->dwPeSizeofImage << "\n";
|
|
text << "(PE) Checksum : 0x" << std::setw(8) << Xbe_header->dwPeChecksum << "\n";
|
|
text << "(PE) TimeDate Stamp : 0x" << std::setw(8) << Xbe_header->dwPeTimeDate << " (" << BetterTime(Xbe_header->dwPeTimeDate) << ")\n";
|
|
text << "Debug Pathname Address : 0x" << std::setw(8) << Xbe_header->dwDebugPathnameAddr << " (\"" << Xbe_to_print->GetAddr(Xbe_header->dwDebugPathnameAddr) << "\")\n";
|
|
text << "Debug Filename Address : 0x" << std::setw(8) << Xbe_header->dwDebugFilenameAddr << " (\"" << Xbe_to_print->GetAddr(Xbe_header->dwDebugFilenameAddr) << "\")\n";
|
|
text << "Debug Unicode filename Address : 0x" << std::setw(8) << Xbe_header->dwDebugUnicodeFilenameAddr << " (L\"" << AsciiFilename << "\")\n";
|
|
text << "Kernel Image Thunk Address : 0x" << std::setw(8) << Xbe_header->dwKernelImageThunkAddr << " (Retail: 0x" << std::setw(8) << retail_thunk_addr << ", Debug: 0x" << std::setw(8) << debug_thunk_addr << ")\n";
|
|
text << "NonKernel Import Dir Address : 0x" << std::setw(8) << Xbe_header->dwNonKernelImportDirAddr << "\n";
|
|
text << "Library Versions : 0x" << std::setw(8) << Xbe_header->dwLibraryVersions << "\n";
|
|
text << "Library Versions Address : 0x" << std::setw(8) << Xbe_header->dwLibraryVersionsAddr << "\n";
|
|
text << "Kernel Library Version Address : 0x" << std::setw(8) << Xbe_header->dwKernelLibraryVersionAddr << "\n";
|
|
text << "XAPI Library Version Address : 0x" << std::setw(8) << Xbe_header->dwXAPILibraryVersionAddr << "\n";
|
|
text << "Logo Bitmap Address : 0x" << std::setw(8) << Xbe_header->dwLogoBitmapAddr << "\n";
|
|
text << "Logo Bitmap Size : 0x" << std::setw(8) << Xbe_header->dwSizeofLogoBitmap << "\n\n";
|
|
return text.str();
|
|
}
|
|
|
|
std::string XbePrinter::ValidateXbeSignature()
|
|
{
|
|
std::string text("\nInvalid xbe signature. Homebrew, tampered or pirated xbe?\n");
|
|
if (Xbe_to_print->CheckSignature()) {
|
|
text = "\nValid xbe signature. Xbe is legit\n";
|
|
}
|
|
return text;
|
|
}
|
|
|
|
std::string XbePrinter::GenXbeCertificateInfo()
|
|
{
|
|
std::string text;
|
|
text.append(GenCertificateHeader());
|
|
text.append(GenAlternateTitleIDs());
|
|
text.append(GenMediaInfo());
|
|
text.append(GenLANKey());
|
|
text.append(GenSignatureKey());
|
|
text.append(GenAlternateSignatureKeys());
|
|
text.append(GenExtraInfo());
|
|
return text;
|
|
}
|
|
|
|
std::string XbePrinter::GenCertificateHeader()
|
|
{
|
|
std::stringstream text;
|
|
SSTREAM_SET_HEX(text);
|
|
text << "Dumping XBE Certificate...\n\n";
|
|
text << "Size of Certificate : 0x" << std::setw(8) << Xbe_certificate->dwSize << "\n";
|
|
text << "TimeDate Stamp : 0x" << std::setw(8) << Xbe_certificate->dwTimeDate << " (" << BetterTime(Xbe_certificate->dwTimeDate) << ")\n";
|
|
text << "Title ID : " << FormatTitleId(Xbe_certificate->dwTitleId) << "\n";
|
|
text << "Title ID (Hex) : 0x" << std::setw(8) << Xbe_certificate->dwTitleId << "\n";
|
|
text << "Title : L\"" << Xbe_to_print->m_szAsciiTitle << "\"\n";
|
|
return text.str();
|
|
}
|
|
|
|
std::string XbePrinter::GenAlternateTitleIDs()
|
|
{
|
|
std::stringstream text;
|
|
SSTREAM_SET_HEX(text);
|
|
text << "Alternate Titles IDs : ";
|
|
|
|
for(int v = 0; v < 0x10; v++) {
|
|
if(v != 0) {
|
|
text << " ";
|
|
}
|
|
text << "0x" << std::setw(8) << Xbe_certificate->dwAlternateTitleId[v];
|
|
if(v != 0x0F) {
|
|
text << "\n";
|
|
}
|
|
}
|
|
text << "\n";
|
|
return text.str();
|
|
}
|
|
|
|
std::string XbePrinter::GenMediaInfo()
|
|
{
|
|
std::stringstream text;
|
|
SSTREAM_SET_HEX(text);
|
|
text << "Allowed Media : 0x" << std::setw(8) << Xbe_certificate->dwAllowedMedia << " (" << AllowedMediaToString() << ")\n";
|
|
text << "Game Region : 0x" << std::setw(8) << Xbe_certificate->dwGameRegion << " (" << Xbe_to_print->GameRegionToString() << ")\n";
|
|
text << "Game Ratings : 0x" << std::setw(8) << Xbe_certificate->dwGameRatings << " (" << GameRatingToString() << ")\n";
|
|
text << "Disc Number : 0x" << std::setw(8) << Xbe_certificate->dwDiscNumber << "\n";
|
|
text << "Version : 0x" << std::setw(8) << Xbe_certificate->dwVersion << "\n";
|
|
SSTREAM_SET_DEC(text);
|
|
text << "Disc Version : " << std::setw(0) << Xbe_to_print->GetDiscVersion() << "\n";
|
|
text << "Patch Version : " << std::setw(0) << Xbe_to_print->GetPatchVersion() << "\n";
|
|
|
|
return text.str();
|
|
}
|
|
|
|
std::string XbePrinter::GenLANKey()
|
|
{
|
|
const uint8_t row = 0;
|
|
const uint8_t row_size = 16;
|
|
std::string text;
|
|
text.append("LAN Key : ");
|
|
text.append(GenHexRow(&(Xbe_certificate->bzLanKey[0]), row, row_size));
|
|
text.append("\n");
|
|
return text;
|
|
}
|
|
|
|
std::string XbePrinter::GenSignatureKey()
|
|
{
|
|
const uint8_t row = 0;
|
|
const uint8_t row_size = 16;
|
|
std::string text;
|
|
text.append("Signature Key : ");
|
|
text.append(GenHexRow(&(Xbe_certificate->bzSignatureKey[0]), row, row_size));
|
|
text.append("\n");
|
|
return text;
|
|
}
|
|
|
|
std::string XbePrinter::GenAlternateSignatureKeys()
|
|
{
|
|
const uint8_t row = 0;
|
|
const uint8_t row_size = 16;
|
|
std::string text;
|
|
|
|
text.append("Title Alternate Signature Keys : <Hex Dump>");
|
|
for(int row = 0; row < 16; row++)
|
|
{
|
|
text.append("\n ");
|
|
text.append(GenHexRow(&(Xbe_certificate->bzTitleAlternateSignatureKey[0][0]), row, row_size));
|
|
}
|
|
text.append("\n </Hex Dump>\n");
|
|
return text;
|
|
}
|
|
|
|
std::string XbePrinter::GenExtraInfo()
|
|
{
|
|
std::stringstream text;
|
|
|
|
if (Xbe_certificate->dwSize >= 0x1EC)
|
|
{
|
|
SSTREAM_SET_HEX(text);
|
|
text << "Original Certificate Size : 0x" << std::setw(8) << Xbe_certificate->dwOriginalCertificateSize << "\n";
|
|
text << "Online Service ID : 0x" << std::setw(8) << Xbe_certificate->dwOnlineService << "\n";
|
|
text << "Extra Security Flags : 0x" << std::setw(8) << Xbe_certificate->dwSecurityFlags << "\n";
|
|
text << "Code Encryption Key : ";
|
|
text << GenHexRow(&(Xbe_certificate->bzCodeEncKey[0]), 0, 16) << "\n";
|
|
}
|
|
return text.str();
|
|
}
|
|
|
|
std::string XbePrinter::GenSectionInfo()
|
|
{
|
|
std::string text;
|
|
text.append("\nDumping XBE Section Headers...\n\n");
|
|
text.append(GenSectionHeaders());
|
|
return text;
|
|
}
|
|
|
|
std::string XbePrinter::GenSectionHeaders()
|
|
{
|
|
std::stringstream text;
|
|
SSTREAM_SET_HEX(text);
|
|
for(uint32_t v=0; v < Xbe_header->dwSections; v++) {
|
|
text << "Section Name : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwSectionNameAddr << " (\"" << Xbe_to_print->m_szSectionName[v] << "\")\n";
|
|
text << GenSectionFlags(Xbe_to_print->m_SectionHeader[v]);
|
|
text << "Virtual Address : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwVirtualAddr << "\n";
|
|
text << "Virtual Size : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwVirtualSize << "\n";
|
|
text << "Raw Address : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwRawAddr << "\n";
|
|
text << "Size of Raw : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwSizeofRaw << "\n";
|
|
text << "Section Name Address : 0x" << std::setw(8) << Xbe_to_print->m_SectionHeader[v].dwSectionNameAddr << "\n";
|
|
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";
|
|
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();
|
|
}
|
|
|
|
std::string XbePrinter::GenSectionFlags(Xbe::SectionHeader section_header)
|
|
{
|
|
std::stringstream text;
|
|
SSTREAM_SET_HEX(text);
|
|
text << "Flags : 0x" << std::setw(8) << section_header.dwFlags_value << " ";
|
|
|
|
if(section_header.dwFlags.bWritable) {
|
|
text << "(Writable) ";
|
|
}
|
|
if(section_header.dwFlags.bPreload) {
|
|
text << "(Preload) ";
|
|
}
|
|
if(section_header.dwFlags.bExecutable) {
|
|
text << "(Executable) ";
|
|
}
|
|
if(section_header.dwFlags.bInsertedFile) {
|
|
text << "(Inserted File) ";
|
|
}
|
|
if(section_header.dwFlags.bHeadPageRO) {
|
|
text << "(Head Page RO) ";
|
|
}
|
|
if(section_header.dwFlags.bTailPageRO) {
|
|
text << "(Tail Page RO) ";
|
|
}
|
|
text << "\n";
|
|
return text.str();
|
|
}
|
|
|
|
std::string XbePrinter::GenSectionDigest(Xbe::SectionHeader section_header)
|
|
{
|
|
std::string text;
|
|
text.append("Section Digest : ");
|
|
text.append(GenHexRow(§ion_header.bzSectionDigest[0], 0, 20));
|
|
return text;
|
|
}
|
|
|
|
std::string XbePrinter::GenLibraryVersions()
|
|
{
|
|
std::stringstream text;
|
|
text << "Dumping XBE Library Versions...\n\n";
|
|
|
|
if(Xbe_to_print->m_LibraryVersion == 0 || Xbe_header->dwLibraryVersions == 0) {
|
|
text << "(This XBE contains no Library Versions)\n\n";
|
|
}
|
|
else {
|
|
for(uint32_t v = 0; v < Xbe_header->dwLibraryVersions; v++) {
|
|
char libname[9];
|
|
for(uint32_t c=0;c<8;c++) {
|
|
libname[c] = Xbe_to_print->m_LibraryVersion[v].szName[c];
|
|
}
|
|
libname[8] = '\0';
|
|
|
|
text << "Library Name : " << libname << "\n";
|
|
text << "Version : "
|
|
<< Xbe_to_print->m_LibraryVersion[v].wMajorVersion << "."
|
|
<< Xbe_to_print->m_LibraryVersion[v].wMinorVersion << "."
|
|
<< Xbe_to_print->m_LibraryVersion[v].wBuildVersion << "\n";
|
|
text << GenLibraryFlags(Xbe_to_print->m_LibraryVersion[v]);
|
|
text << "\n";
|
|
}
|
|
}
|
|
return text.str();
|
|
}
|
|
|
|
std::string XbePrinter::GenLibraryFlags(Xbe::LibraryVersion libver)
|
|
{
|
|
std::stringstream text;
|
|
SSTREAM_SET_HEX(text);
|
|
text << "Flags : 0x" << std::setw(4) << libver.wFlags_value << " ";
|
|
text << "QFEVersion : 0x" << std::setw(4) << libver.wFlags.QFEVersion << ", ";
|
|
|
|
if(libver.wFlags.bDebugBuild) {
|
|
text << "Debug, ";
|
|
}
|
|
else {
|
|
text << "Retail, ";
|
|
}
|
|
|
|
switch(libver.wFlags.Approved) {
|
|
case 0:
|
|
text << "Unapproved";
|
|
break;
|
|
case 1:
|
|
text << "Possibly Approved";
|
|
break;
|
|
case 2:
|
|
text << "Approved";
|
|
break;
|
|
}
|
|
text << "\n";
|
|
return text.str();
|
|
}
|
|
|
|
std::string XbePrinter::GenTLS()
|
|
{
|
|
std::stringstream text;
|
|
SSTREAM_SET_HEX(text);
|
|
Xbe::TLS *local_TLS = Xbe_to_print->m_TLS;
|
|
|
|
text << "Dumping XBE TLS...\n\n";
|
|
// print thread local storage
|
|
if(local_TLS != 0) {
|
|
text << "Data Start Address : 0x" << std::setw(8) << local_TLS->dwDataStartAddr << "\n";
|
|
text << "Data End Address : 0x" << std::setw(8) << local_TLS->dwDataEndAddr << "\n";
|
|
text << "TLS Index Address : 0x" << std::setw(8) << local_TLS->dwTLSIndexAddr << "\n";
|
|
text << "TLS Callback Address : 0x" << std::setw(8) << local_TLS->dwTLSCallbackAddr << "\n";
|
|
text << "Size of Zero Fill : 0x" << std::setw(8) << local_TLS->dwSizeofZeroFill << "\n";
|
|
text << "Characteristics : 0x" << std::setw(8) << local_TLS->dwCharacteristics << "\n";
|
|
}
|
|
else {
|
|
text << "(This XBE contains no TLS)\n";
|
|
}
|
|
return text.str();
|
|
}
|