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:
parent
b015cc715b
commit
4a3965d644
|
@ -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,281 +550,32 @@ 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]);
|
||||
}
|
||||
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");
|
||||
}
|
||||
XbePrinter printer(this);
|
||||
std::cout << printer.GenXbeInfo();
|
||||
}
|
||||
|
||||
|
||||
// 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(§ion_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();
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1006,32 +1006,21 @@ 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())
|
||||
{
|
||||
MessageBox(m_hwnd, m_Xbe->GetError().c_str(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue