Move Xbe dumping into its own class. Add game ratings string printout for issue #686. Cleanup GUI code so that the Xbe Printer is responsible for outputting Xbe info

This commit is contained in:
Fisherman166 2018-01-20 14:36:59 -08:00
parent b015cc715b
commit 4a3965d644
3 changed files with 515 additions and 310 deletions

View File

@ -37,11 +37,13 @@
#include "CxbxVersion.h"
#include "CxbxUtil.h"
#include <memory.h>
#include <clocale>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <locale>
#include <codecvt>
#include <fstream>
#include <iostream>
#include <sstream>
#include <iomanip>
#define PAGE_SIZE 0x1000
@ -548,280 +550,31 @@ static char *BetterTime(uint32 x_timeDate)
return x_ctime;
}
// dump Xbe information to text file
void Xbe::DumpInformation(FILE *x_file)
bool Xbe::DumpInformationToFile(std::string out_filename)
{
if(HasError()) {
return false;
}
bool success = false;
XbePrinter printer(this);
std::ofstream out_file(out_filename);
if(out_file.is_open()) {
out_file << printer.GenXbeInfo();
out_file.close();
success = true;
}
return success;
}
void Xbe::DumpInformationToConsole()
{
if(HasError())
return;
fprintf(x_file, "XBE information generated by Cxbx-Reloaded (Version " _CXBX_VERSION ")\n");
fprintf(x_file, "\n");
fprintf(x_file, "Title identified as \"%s\"\n", m_szAsciiTitle);
fprintf(x_file, "\n");
fprintf(x_file, "Dumping XBE file header...\n");
fprintf(x_file, "\n");
fprintf(x_file, "Magic Number : XBEH\n");
// print digital signature
{
fprintf(x_file, "Digitial Signature : <Hex Dump>");
for(int y=0;y<16;y++)
{
fprintf(x_file, "\n ");
for(int x=0;x<16;x++)
fprintf(x_file, "%.02X", m_Header.pbDigitalSignature[y*16+x]);
XbePrinter printer(this);
std::cout << printer.GenXbeInfo();
}
fprintf(x_file, "\n </Hex Dump>\n");
}
fprintf(x_file, "Base Address : 0x%.08X\n", m_Header.dwBaseAddr);
fprintf(x_file, "Size of Headers : 0x%.08X\n", m_Header.dwSizeofHeaders);
fprintf(x_file, "Size of Image : 0x%.08X\n", m_Header.dwSizeofImage);
fprintf(x_file, "Size of Image Header : 0x%.08X\n", m_Header.dwSizeofImageHeader);
fprintf(x_file, "TimeDate Stamp : 0x%.08X (%s)\n", m_Header.dwTimeDate, BetterTime(m_Header.dwTimeDate));
fprintf(x_file, "Certificate Address : 0x%.08X\n", m_Header.dwCertificateAddr);
fprintf(x_file, "Number of Sections : 0x%.08X\n", m_Header.dwSections);
fprintf(x_file, "Section Headers Address : 0x%.08X\n", m_Header.dwSectionHeadersAddr);
// print init flags
{
fprintf(x_file, "Init Flags : 0x%.08X ", m_Header.dwInitFlags_value);
if(m_Header.dwInitFlags.bMountUtilityDrive)
fprintf(x_file, "[Mount Utility Drive] ");
if(m_Header.dwInitFlags.bFormatUtilityDrive)
fprintf(x_file, "[Format Utility Drive] ");
if(m_Header.dwInitFlags.bLimit64MB)
fprintf(x_file, "[Limit Devkit Run Time Memory to 64MB] ");
if(!m_Header.dwInitFlags.bDontSetupHarddisk)
fprintf(x_file, "[Setup Harddisk] ");
fprintf(x_file, "\n");
}
char AsciiFilename[40];
setlocale( LC_ALL, "English" );
const wchar_t *wszFilename = (const wchar_t *)GetAddr(m_Header.dwDebugUnicodeFilenameAddr);
if(wszFilename != NULL)
wcstombs(AsciiFilename, wszFilename, 40);
else
AsciiFilename[0] = '\0';
fprintf(x_file, "Entry Point : 0x%.08X (Retail: 0x%.08X, Debug: 0x%.08X)\n", m_Header.dwEntryAddr, m_Header.dwEntryAddr ^ XOR_EP_RETAIL, m_Header.dwEntryAddr ^ XOR_EP_DEBUG);
fprintf(x_file, "TLS Address : 0x%.08X\n", m_Header.dwTLSAddr);
fprintf(x_file, "(PE) Stack Commit : 0x%.08X\n", m_Header.dwPeStackCommit);
fprintf(x_file, "(PE) Heap Reserve : 0x%.08X\n", m_Header.dwPeHeapReserve);
fprintf(x_file, "(PE) Heap Commit : 0x%.08X\n", m_Header.dwPeHeapCommit);
fprintf(x_file, "(PE) Base Address : 0x%.08X\n", m_Header.dwPeBaseAddr);
fprintf(x_file, "(PE) Size of Image : 0x%.08X\n", m_Header.dwPeSizeofImage);
fprintf(x_file, "(PE) Checksum : 0x%.08X\n", m_Header.dwPeChecksum);
fprintf(x_file, "(PE) TimeDate Stamp : 0x%.08X (%s)\n", m_Header.dwPeTimeDate, BetterTime(m_Header.dwPeTimeDate));
fprintf(x_file, "Debug Pathname Address : 0x%.08X (\"%s\")\n", m_Header.dwDebugPathnameAddr, GetAddr(m_Header.dwDebugPathnameAddr));
fprintf(x_file, "Debug Filename Address : 0x%.08X (\"%s\")\n", m_Header.dwDebugFilenameAddr, GetAddr(m_Header.dwDebugFilenameAddr));
fprintf(x_file, "Debug Unicode filename Address : 0x%.08X (L\"%s\")\n", m_Header.dwDebugUnicodeFilenameAddr, AsciiFilename);
fprintf(x_file, "Kernel Image Thunk Address : 0x%.08X (Retail: 0x%.08X, Debug: 0x%.08X)\n", m_Header.dwKernelImageThunkAddr, m_Header.dwKernelImageThunkAddr ^ XOR_KT_RETAIL, m_Header.dwKernelImageThunkAddr ^ XOR_KT_DEBUG);
fprintf(x_file, "NonKernel Import Dir Address : 0x%.08X\n", m_Header.dwNonKernelImportDirAddr);
fprintf(x_file, "Library Versions : 0x%.08X\n", m_Header.dwLibraryVersions);
fprintf(x_file, "Library Versions Address : 0x%.08X\n", m_Header.dwLibraryVersionsAddr);
fprintf(x_file, "Kernel Library Version Address : 0x%.08X\n", m_Header.dwKernelLibraryVersionAddr);
fprintf(x_file, "XAPI Library Version Address : 0x%.08X\n", m_Header.dwXAPILibraryVersionAddr);
fprintf(x_file, "Logo Bitmap Address : 0x%.08X\n", m_Header.dwLogoBitmapAddr);
fprintf(x_file, "Logo Bitmap Size : 0x%.08X\n", m_Header.dwSizeofLogoBitmap);
fprintf(x_file, "\n");
fprintf(x_file, "Dumping XBE Certificate...\n");
fprintf(x_file, "\n");
fprintf(x_file, "Size of Certificate : 0x%.08X\n", m_Certificate.dwSize);
fprintf(x_file, "TimeDate Stamp : 0x%.08X (%s)\n", m_Certificate.dwTimeDate, BetterTime(m_Certificate.dwTimeDate));
fprintf(x_file, "Title ID : 0x%.08X\n", m_Certificate.dwTitleId);
fprintf(x_file, "Title : L\"%s\"\n", m_szAsciiTitle);
// print alternate title IDs
{
fprintf(x_file, "Alternate Titles IDs : ");
for(int v=0;v<0x10;v++)
{
if(v != 0)
fprintf(x_file, " ");
fprintf(x_file, "0x%.08X", m_Certificate.dwAlternateTitleId[v]);
if(v != 0x0F)
fprintf(x_file, "\n");
}
fprintf(x_file, "\n");
}
fprintf(x_file, "Allowed Media : 0x%.08X (%s)\n", m_Certificate.dwAllowedMedia, AllowedMediaToString().c_str());
fprintf(x_file, "Game Region : 0x%.08X (%s)\n", m_Certificate.dwGameRegion, GameRegionToString());
fprintf(x_file, "Game Ratings : 0x%.08X\n", m_Certificate.dwGameRatings);
fprintf(x_file, "Disk Number : 0x%.08X\n", m_Certificate.dwDiskNumber);
fprintf(x_file, "Version : 0x%.08X\n", m_Certificate.dwVersion);
// print LAN key
{
fprintf(x_file, "LAN Key : ");
for(int x=0;x<16;x++)
fprintf(x_file, "%.02X", m_Certificate.bzLanKey[x]);
fprintf(x_file, "\n");
}
// print signature key
{
fprintf(x_file, "Signature Key : ");
for(int x=0;x<16;x++)
fprintf(x_file, "%.02X", m_Certificate.bzSignatureKey[x]);
fprintf(x_file, "\n");
}
// print alternate signature keys
{
fprintf(x_file, "Title Alternate Signature Keys : <Hex Dump>");
for(int y=0;y<16;y++)
{
fprintf(x_file, "\n ");
for(int x=0;x<16;x++)
fprintf(x_file, "%.02X", m_Certificate.bzTitleAlternateSignatureKey[y][x]);
}
fprintf(x_file, "\n </Hex Dump>\n");
}
fprintf(x_file, "\n");
fprintf(x_file, "Dumping XBE Section Headers...\n");
fprintf(x_file, "\n");
// print section headers
{
for(uint32 v=0;v<m_Header.dwSections;v++)
{
fprintf(x_file, "Section Name : 0x%.08X (\"%s\")\n", m_SectionHeader[v].dwSectionNameAddr, m_szSectionName[v]);
// print flags
{
fprintf(x_file, "Flags : 0x%.08X ", m_SectionHeader[v].dwFlags_value);
if(m_SectionHeader[v].dwFlags.bWritable)
fprintf(x_file, "(Writable) ");
if(m_SectionHeader[v].dwFlags.bPreload)
fprintf(x_file, "(Preload) ");
if(m_SectionHeader[v].dwFlags.bExecutable)
fprintf(x_file, "(Executable) ");
if(m_SectionHeader[v].dwFlags.bInsertedFile)
fprintf(x_file, "(Inserted File) ");
if(m_SectionHeader[v].dwFlags.bHeadPageRO)
fprintf(x_file, "(Head Page RO) ");
if(m_SectionHeader[v].dwFlags.bTailPageRO)
fprintf(x_file, "(Tail Page RO) ");
fprintf(x_file, "\n");
}
fprintf(x_file, "Virtual Address : 0x%.08X\n", m_SectionHeader[v].dwVirtualAddr);
fprintf(x_file, "Virtual Size : 0x%.08X\n", m_SectionHeader[v].dwVirtualSize);
fprintf(x_file, "Raw Address : 0x%.08X\n", m_SectionHeader[v].dwRawAddr);
fprintf(x_file, "Size of Raw : 0x%.08X\n", m_SectionHeader[v].dwSizeofRaw);
fprintf(x_file, "Section Name Address : 0x%.08X\n", m_SectionHeader[v].dwSectionNameAddr);
fprintf(x_file, "Section Reference Count : 0x%.08X\n", m_SectionHeader[v].dwSectionRefCount);
fprintf(x_file, "Head Shared Reference Count Addr : 0x%.08X\n", m_SectionHeader[v].dwHeadSharedRefCountAddr);
fprintf(x_file, "Tail Shared Reference Count Addr : 0x%.08X\n", m_SectionHeader[v].dwTailSharedRefCountAddr);
// print section digest
{
fprintf(x_file, "Section Digest : ");
for(int s=0;s<20;s++)
fprintf(x_file, "%.02X", m_SectionHeader[v].bzSectionDigest[s]);
fprintf(x_file, "\n");
}
fprintf(x_file, "\n");
}
}
fprintf(x_file, "Dumping XBE Library Versions...\n");
fprintf(x_file, "\n");
// print library versions
{
if(m_LibraryVersion == 0 || m_Header.dwLibraryVersions == 0)
{
fprintf(x_file, "(This XBE contains no Library Versions)\n");
fprintf(x_file, "\n");
}
else
{
for(uint32 v=0;v<m_Header.dwLibraryVersions;v++)
{
char tmp[9];
for(uint32 c=0;c<8;c++)
tmp[c] = m_LibraryVersion[v].szName[c];
tmp[8] = '\0';
fprintf(x_file, "Library Name : %s\n", tmp);
fprintf(x_file, "Version : %d.%d.%d\n", m_LibraryVersion[v].wMajorVersion, m_LibraryVersion[v].wMinorVersion, m_LibraryVersion[v].wBuildVersion);
// print flags
{
fprintf(x_file, "Flags : 0x%.04X ", m_LibraryVersion[v].wFlags_value);
fprintf(x_file, "QFEVersion : 0x%.04X, ", m_LibraryVersion[v].wFlags.QFEVersion);
if(m_LibraryVersion[v].wFlags.bDebugBuild)
fprintf(x_file, "Debug, ");
else
fprintf(x_file, "Retail, ");
switch(m_LibraryVersion[v].wFlags.Approved)
{
case 0:
fprintf(x_file, "Unapproved");
break;
case 1:
fprintf(x_file, "Possibly Approved");
break;
case 2:
fprintf(x_file, "Approved");
break;
}
fprintf(x_file, "\n");
}
fprintf(x_file, "\n");
}
}
}
fprintf(x_file, "Dumping XBE TLS...\n");
fprintf(x_file, "\n");
// print thread local storage
if(m_TLS != 0)
{
fprintf(x_file, "Data Start Address : 0x%.08X\n", m_TLS->dwDataStartAddr);
fprintf(x_file, "Data End Address : 0x%.08X\n", m_TLS->dwDataEndAddr);
fprintf(x_file, "TLS Index Address : 0x%.08X\n", m_TLS->dwTLSIndexAddr);
fprintf(x_file, "TLS Callback Address : 0x%.08X\n", m_TLS->dwTLSCallbackAddr);
fprintf(x_file, "Size of Zero Fill : 0x%.08X\n", m_TLS->dwSizeofZeroFill);
fprintf(x_file, "Characteristics : 0x%.08X\n", m_TLS->dwCharacteristics);
}
else
{
fprintf(x_file, "(This XBE contains no TLS)\n");
}
}
// import logo bitmap from raw monochrome data
void Xbe::ImportLogoBitmap(const uint08 x_Gray[100*17])
@ -1037,9 +790,56 @@ const char *Xbe::GameRegionToString()
return Region_text[index];
}
std::string Xbe::AllowedMediaToString()
const wchar_t *Xbe::GetUnicodeFilenameAddr()
{
const uint32 dwAllowedMedia = m_Certificate.dwAllowedMedia;
return (const wchar_t *)GetAddr(m_Header.dwDebugUnicodeFilenameAddr);
}
#define SSTREAM_SET_HEX(stream_name) stream_name << std::setfill('0') << std::uppercase << std::hex;
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(GenSectionInfo());
info.append(GenLibraryVersions());
info.append(GenTLS());
return info;
}
std::string XbePrinter::GenHexRow(
uint08 *signature, const uint08 row, const uint08 row_size
)
{
const uint16 offset = row * row_size;
std::stringstream text;
SSTREAM_SET_HEX(text);
for(uint08 x = 0; x < row_size; x++) {
text << std::setw(2) << static_cast<unsigned>(signature[offset + x]);
}
return text.str();
}
// https://stackoverflow.com/questions/4786292/converting-unicode-strings-and-vice-versa
std::string XbePrinter::utf8_to_ascii(const wchar_t* utf8_string)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_to_ascii;
const std::wstring utf8_filename(utf8_string);
return utf8_to_ascii.to_bytes(utf8_filename);
}
std::string XbePrinter::AllowedMediaToString()
{
const uint32 dwAllowedMedia = Xbe_certificate->dwAllowedMedia;
std::string text = "Media Types:";
if(dwAllowedMedia & XBEIMAGE_MEDIA_TYPE_MEDIA_MASK) {
@ -1076,3 +876,377 @@ std::string Xbe::AllowedMediaToString()
}
return text;
}
std::string XbePrinter::GameRatingToString()
{
std::string text;
// Info from: http://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 " _CXBX_VERSION ")\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 uint08 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 retail_entry_point = Xbe_header->dwEntryAddr ^ XOR_EP_RETAIL;
const uint32 debug_entry_point = Xbe_header->dwEntryAddr ^ XOR_EP_DEBUG;
const uint32 retail_thunk_addr = Xbe_header->dwKernelImageThunkAddr ^ XOR_KT_RETAIL;
const uint32 debug_thunk_addr = Xbe_header->dwKernelImageThunkAddr ^ XOR_KT_DEBUG;
const std::string AsciiFilename = utf8_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::GenXbeCertificateInfo()
{
std::string text;
text.append(GenCertificateHeader());
text.append(GenAlternateTitleIDs());
text.append(GenMediaInfo());
text.append(GenLANKey());
text.append(GenSignatureKey());
text.append(GenAlternateSignatureKeys());
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 : 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 << "Disk Number : 0x" << std::setw(8) << Xbe_certificate->dwDiskNumber << "\n";
text << "Version : 0x" << std::setw(8) << Xbe_certificate->dwVersion << "\n";
return text.str();
}
std::string XbePrinter::GenLANKey()
{
const uint08 row = 0;
const uint08 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 uint08 row = 0;
const uint08 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 uint08 row = 0;
const uint08 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::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 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";
}
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(&section_header.bzSectionDigest[0], 0, 20));
text.append("\n");
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 v = 0; v < Xbe_header->dwLibraryVersions; v++) {
char libname[9];
for(uint32 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();
}

View File

@ -62,8 +62,8 @@ class Xbe : public Error
// export to Xbe file
void Export(const char *x_szXbeFilename);
// dump Xbe information to text file
void DumpInformation(FILE *x_file);
bool DumpInformationToFile(std::string);
void DumpInformationToConsole();
// import logo bitmap from raw monochrome data
void ImportLogoBitmap(const uint08 x_Gray[100*17]);
@ -255,17 +255,17 @@ class Xbe : public Error
// retrieve thread local storage index address
uint32 *GetTLSIndex() { if(m_TLS == 0) return 0; else return (uint32*)GetAddr(m_TLS->dwTLSIndexAddr); }
// return a modifiable pointer inside this structure that corresponds to a virtual address
uint08 *GetAddr(uint32 x_dwVirtualAddress);
const wchar_t *GetUnicodeFilenameAddr();
private:
// constructor initialization
void ConstructorInit();
// return a modifiable pointer inside this structure that corresponds to a virtual address
uint08 *GetAddr(uint32 x_dwVirtualAddress);
// return a modifiable pointer to logo bitmap data
uint08 *GetLogoBitmap(uint32 x_dwSize);
std::string AllowedMediaToString();
// used to encode/decode logo bitmap data
union LogoRLE
@ -346,6 +346,49 @@ class Xbe : public Error
*m_xprImage;
};
class XbePrinter
{
public:
XbePrinter(Xbe*);
std::string GenXbeInfo();
private:
Xbe *Xbe_to_print;
Xbe::Header *Xbe_header;
Xbe::Certificate *Xbe_certificate;
std::string GenHexRow(uint08*, const uint08, const uint08);
std::string utf8_to_ascii(const wchar_t*);
std::string AllowedMediaToString();
std::string GameRatingToString();
std::string GenDumpHeader();
std::string GenXbeHeaderInfo();
std::string GenDigitalSignature();
std::string GenGeneralHeaderInfo1();
std::string GenInitFlags();
std::string GenGeneralHeaderInfo2();
std::string GenXbeCertificateInfo();
std::string GenCertificateHeader();
std::string GenAlternateTitleIDs();
std::string GenMediaInfo();
std::string GenLANKey();
std::string GenSignatureKey();
std::string GenAlternateSignatureKeys();
std::string GenSectionInfo();
std::string GenSectionHeaders();
std::string GenSectionFlags(Xbe::SectionHeader);
std::string GenSectionDigest(Xbe::SectionHeader);
std::string GenLibraryVersions();
std::string GenLibraryFlags(Xbe::LibraryVersion);
std::string GenTLS();
};
// debug/retail XOR keys
const uint32 XOR_EP_DEBUG = 0x94859D4B; // Entry Point (Debug)
const uint32 XOR_EP_RETAIL = 0xA8FC57AB; // Entry Point (Retail)

View File

@ -1006,31 +1006,20 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
// dump xbe information to file
{
FILE *TxtFile = fopen(ofn.lpstrFile, "wt");
// verify file was opened
if (TxtFile == 0)
MessageBox(m_hwnd, "Could not open text file.", "Cxbx-Reloaded", MB_ICONSTOP | MB_OK);
else
{
m_Xbe->DumpInformation(TxtFile);
fclose(TxtFile);
if (m_Xbe->HasError())
{
bool success = m_Xbe->DumpInformationToFile(ofn.lpstrFile);
if (m_Xbe->HasError()) {
MessageBox(m_hwnd, m_Xbe->GetError().c_str(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK);
}
else
{
else {
if(success) {
char buffer[255];
sprintf(buffer, "%s's .xbe info was successfully dumped.", m_Xbe->m_szAsciiTitle);
printf("WndMain: %s\n", buffer);
MessageBox(m_hwnd, buffer, "Cxbx-Reloaded", MB_ICONINFORMATION | MB_OK);
}
else {
MessageBox(m_hwnd, "Could not open Xbe text file.", "Cxbx-Reloaded", MB_ICONSTOP | MB_OK);
}
}
}
}
@ -1039,8 +1028,7 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
case ID_EDIT_DUMPXBEINFOTO_DEBUGCONSOLE:
{
// dump xbe information to debug console
m_Xbe->DumpInformation(stdout);
m_Xbe->DumpInformationToConsole();
if (m_Xbe->HasError())
{
@ -1050,7 +1038,7 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
{
char buffer[255];
sprintf(buffer, "%s's .xbe info was successfully dumped.", m_Xbe->m_szAsciiTitle);
sprintf(buffer, "%s's .xbe info was successfully dumped to console.", m_Xbe->m_szAsciiTitle);
printf("WndMain: %s\n", buffer);
}