Refactored code, added MapRegisters patcher.

This commit is contained in:
Long Nguyen 2011-08-11 00:14:07 -07:00
parent fe3f60cf00
commit b2a489ca16
4 changed files with 527 additions and 442 deletions

View file

@ -4,97 +4,99 @@
#include "Types.h"
#include "AlignPrefix1.h"
struct MicroExeHeaders
struct MICRO_EXE_HEADERS
{
// DOS Header
struct DOSHeader
struct DOS_HEADER
{
uint16 wMagic; // DOS .EXE magic number
uint16 Magic; // DOS .EXE magic number
uint16 Unused;
} m_DOSHeader;
} DosHeader;
// PE Header
struct Header
struct HEADER
{
uint32 dwMagic; // magic number [should be "PE\0\0"]
uint16 wMachine; // machine type
uint16 wNumberOfSections; // number of sections
uint32 dwTimeDateStamp; // timedate stamp
uint32 dwPointerToSymbolTable; // symbol table address
uint32 dwNumberOfSymbols; // number of symbols
uint16 wSizeOfOptionalHeader; // size of optional header
uint16 wCharacteristics; // characteristics
} m_Header;
uint32 Magic; // magic number [should be "PE\0\0"]
uint16 Machine; // machine type
uint16 NumberOfSections; // number of sections
uint32 TimeDateStamp; // timedate stamp
uint32 PointerToSymbolTable; // symbol table address
uint32 NumberOfSymbols; // number of symbols
uint16 SizeOfOptionalHeader; // size of optional header
uint16 Characteristics; // characteristics
} Header;
// Optional Header
struct OptionalHeader
struct OPTIONAL_HEADER
{
uint16 wMagic; // magic number [should be 0x010B]
uint08 bMajorLinkerVersion; // linker version [major]
uint08 bMinorLinkerVersion; // linker version [minor]
uint32 dwSizeOfCode; // size of code
uint32 dwSizeOfInitializedData; // size of initialized data
uint32 dwSizeOfUninitializedData; // size of uninitialized data
uint32 dwAddressOfEntryPoint; // address of entry point
uint32 dwBaseOfCode; // address of code base
uint32 dwBaseOfData; // address of data base
uint16 Magic; // magic number [should be 0x010B]
uint08 MajorLinkerVersion; // linker version [major]
uint08 MinorLinkerVersion; // linker version [minor]
uint32 SizeOfCode; // size of code
uint32 SizeOfInitializedData; // size of initialized data
uint32 SizeOfUninitializedData; // size of uninitialized data
uint32 AddressOfEntryPoint; // address of entry point
uint32 BaseOfCode; // address of code base
uint32 BaseOfData; // address of data base
// NT Additional Fields
uint32 dwImageBase; // address of image base
uint32 dwLfanew_SectionAlignment; // section alignment
// (DOS Header) file address of new .EXE header
uint32 dwFileAlignment; // file alignment
uint16 wMajorOperatingSystemVersion; // operating system version [major]
uint16 wMinorOperatingSystemVersion; // operating system version [minor]
uint16 wMajorImageVersion; // image version [major]
uint16 wMinorImageVersion; // image version [minor]
uint16 wMajorSubsystemVersion; // subsystem version [major]
uint16 wMinorSubsystemVersion; // subsystem version [minor]
uint32 dwWin32VersionValue; // win32 version
uint32 dwSizeOfImage; // size of image
uint32 dwSizeOfHeaders; // size of headers
uint32 dwCheckSum; // checksum
uint16 wSubsystem; // subsystem
uint16 wDllCharacteristics; // dll characteristics
uint32 dwSizeOfStackReserve; // size of stack reserve
uint32 dwSizeOfStackCommit; // size of stack commit
uint32 dwSizeOfHeapReserve; // size of heap reserve
uint32 dwSizeOfHeapCommit; // size of heap commit
uint32 dwLoaderFlags; // loader flags
uint32 dwNumberOfRvaAndSizes; // data directories
struct ImageDataDirectory
uint32 ImageBase; // address of image base
uint32 Lfanew_SectionAlignment; // section alignment
// (DOS Header) file address of new .EXE header
uint32 FileAlignment; // file alignment
uint16 MajorOperatingSystemVersion; // operating system version [major]
uint16 MinorOperatingSystemVersion; // operating system version [minor]
// image version not normally used, thus the imported
// Dirtbox DLL name is placed here to save a few bytes.
int08 DirtboxDllName[4];
// uint16 MajorImageVersion; // image version [major]
// uint16 MinorImageVersion; // image version [minor]
uint16 MajorSubsystemVersion; // subsystem version [major]
uint16 MinorSubsystemVersion; // subsystem version [minor]
uint32 Win32VersionValue; // win32 version
uint32 SizeOfImage; // size of image
uint32 SizeOfHeaders; // size of headers
uint32 CheckSum; // checksum
uint16 Subsystem; // subsystem
uint16 DllCharacteristics; // dll characteristics
uint32 SizeOfStackReserve; // size of stack reserve
uint32 SizeOfStackCommit; // size of stack commit
uint32 SizeOfHeapReserve; // size of heap reserve
uint32 SizeOfHeapCommit; // size of heap commit
uint32 LoaderFlags; // loader flags
uint32 NumberOfRvaAndSizes; // data directories
struct IMAGE_DATA_DIRECTORY
{
uint32 dwVirtualAddress;
uint32 dwSize;
} astDataDirectory[4];
} m_OptionalHeader;
uint32 VirtualAddress;
uint32 Size;
} DataDirectory[4];
} OptionalHeader;
struct SectionHeader
struct SECTION_HEADER
{
uint08 szName[8];
uint32 dwVirtualSize;
uint32 dwVirtualAddress;
uint32 dwSizeOfRawData;
uint32 dwPointerToRawData;
uint32 dwPointerToRelocations;
uint32 dwPointerToLinenumbers;
uint16 wNumberOfRelocations;
uint16 wNumberOfLinenumbers;
uint32 dwCharacteristics;
} m_SectionHeader;
int08 Name[8];
uint32 VirtualSize;
uint32 VirtualAddress;
uint32 SizeOfRawData;
uint32 PointerToRawData;
uint32 PointerToRelocations;
uint32 PointerToLinenumbers;
uint16 NumberOfRelocations;
uint16 NumberOfLinenumbers;
uint32 Characteristics;
} SectionHeader;
struct ImageImportDescriptor
struct IMAGE_IMPORT_DESCRIPTOR
{
uint32 dwOriginalFirstThunk; // address of import lookup table
uint32 dwTimeDateStamp; // time date stamp
uint32 dwForwarderChain; // forwarder chain, -1 if no forwarders
uint32 dwName; // address of DLL name string
uint32 dwFirstThunk; // address of import address table
} m_ImageImportDescriptor[2];
uint32 OriginalFirstThunk; // address of import lookup table
uint32 TimeDateStamp; // time date stamp
uint32 ForwarderChain; // forwarder chain, -1 if no forwarders
uint32 Name; // address of DLL name string
uint32 FirstThunk; // address of import address table
} ImageImportDescriptor[2];
uint32 m_ImportAddressTable[2];
char m_ImportName[10];
uint08 m_Trampoline[6];
uint32 ImportAddressTable[2];
uint08 Trampoline[16];
};
#include "AlignPosfix1.h"

View file

@ -18,12 +18,12 @@ typedef signed char sint08;
typedef signed short sint16;
typedef signed long sint32;
inline static uint32 RoundUp(uint32 dwValue, uint32 dwMult)
inline static uint32 RoundUp(uint32 Value, uint32 Mult)
{
if(dwMult == 0)
return dwValue;
if(Mult == 0)
return Value;
return dwValue - (dwValue-1)%dwMult + (dwMult - 1);
return Value - (Value - 1)%Mult + (Mult - 1);
}
#endif

433
Xbe.cpp
View file

@ -50,6 +50,12 @@
exit(1); \
} while(0)
#define XBE_PATCH_ERROR(str, ...) do \
{ \
printf("\nError in Xbe::PatchExe: " str "\n", __VA_ARGS__); \
return 1; \
} while(0)
#define XBE_WRITE_ERROR(str, ...) do \
{ \
printf("\nError in Xbe::WriteExe: " str "\n", __VA_ARGS__); \
@ -58,24 +64,61 @@
return 1; \
} while(0)
// ******************************************************************
// * Signature for MapRegisters patch and the replacing code
// ******************************************************************
#define PATCH_LENGTH 11
static uint08 PatchSignature[] =
"\xC7\x01\x00\x00\x00\xFD"
"\xA1\x04\x18\x00\xFD";
static void __declspec(naked) PatchCode()
{
__asm
{
mov dword ptr [ecx], 0x84000000
xor eax, eax
inc eax
ret
int 3
}
}
// ******************************************************************
// * Trampoline that will be located at entry point
// ******************************************************************
#define TRAMPOLINE_LENGTH 10
static void __declspec(naked) TrampolineCode()
{
__asm
{
mov edx, 0x000100EC
call dword ptr [edx]
ret 0x10
}
}
// ******************************************************************
// * constructor
// ******************************************************************
Xbe::Xbe(const char *x_szFilename)
Xbe::Xbe(const char *Filename)
{
m_HeaderEx = 0;
m_HeaderExSize = 0;
m_SectionHeader = 0;
m_szSectionName = 0;
m_LibraryVersion = 0;
m_KernelLibraryVersion = 0;
m_XAPILibraryVersion = 0;
m_TLS = 0;
m_bzSection = 0;
HeaderEx = 0;
HeaderExSize = 0;
SectionHeader = 0;
SectionName = 0;
LibraryVersion = 0;
KernelLibraryVersion = 0;
XapiLibraryVersion = 0;
Tls = 0;
Section = 0;
printf("Xbe::Xbe: Opening Xbe file...");
FILE *XbeFile = fopen(x_szFilename, "rb");
FILE *XbeFile = fopen(Filename, "rb");
if(XbeFile == 0)
XBE_ERROR("Could not open Xbe file.");
@ -87,15 +130,15 @@ Xbe::Xbe(const char *x_szFilename)
{
printf("Xbe::Xbe Storing Xbe Path...");
strcpy(m_szPath, x_szFilename);
int v=0, c=0;
while(m_szPath[v] != '\0')
strcpy(Path, Filename);
int v = 0, c = 0;
while(Path[v] != '\0')
{
if(m_szPath[v] == '\\')
c = v+1;
if(Path[v] == '\\')
c = v + 1;
v++;
}
m_szPath[c] = '\0';
Path[c] = '\0';
}
printf("OK\n");
@ -106,9 +149,9 @@ Xbe::Xbe(const char *x_szFilename)
{
printf("Xbe::Xbe: Reading Image Header...");
if(fread(&m_Header, sizeof(m_Header), 1, XbeFile) != 1)
if(fread(&Header, sizeof(Xbe::HEADER), 1, XbeFile) != 1)
XBE_ERROR("Unexpected end of file while reading Xbe Image Header");
if(m_Header.dwMagic != *(uint32 *)"XBEH")
if(Header.Magic != *(uint32 *)"XBEH")
XBE_ERROR("Invalid magic number in Xbe file");
printf("OK\n");
@ -117,15 +160,15 @@ Xbe::Xbe(const char *x_szFilename)
// ******************************************************************
// * read xbe image header extra bytes
// ******************************************************************
if(m_Header.dwSizeOfHeaders > sizeof(m_Header))
if(Header.SizeOfHeaders > sizeof(Xbe::HEADER))
{
printf("Xbe::Xbe: Reading Image Header Extra Bytes...");
uint32 m_HeaderExSize = RoundUp(m_Header.dwSizeOfHeaders, PAGE_SIZE) - sizeof(m_Header);
uint32 HeaderExSize = RoundUp(Header.SizeOfHeaders, PAGE_SIZE) - sizeof(Header);
m_HeaderEx = new char[m_HeaderExSize];
HeaderEx = new char[HeaderExSize];
if(fread(m_HeaderEx, m_HeaderExSize, 1, XbeFile) != 1)
if(fread(HeaderEx, HeaderExSize, 1, XbeFile) != 1)
XBE_ERROR("Unexpected end of file while reading Xbe Image Header (Ex)");
printf("OK\n");
@ -137,16 +180,16 @@ Xbe::Xbe(const char *x_szFilename)
{
printf("Xbe::Xbe: Reading Certificate...");
fseek(XbeFile, m_Header.dwCertificateAddr - m_Header.dwBaseAddr, SEEK_SET);
if(fread(&m_Certificate, sizeof(m_Certificate), 1, XbeFile) != 1)
fseek(XbeFile, Header.CertificateAddr - Header.BaseAddr, SEEK_SET);
if(fread(&Certificate, sizeof(Xbe::CERTIFICATE), 1, XbeFile) != 1)
XBE_ERROR("Unexpected end of file while reading Xbe Certificate");
setlocale(LC_ALL, "English");
wcstombs(m_szAsciiTitle, m_Certificate.wszTitleName, 40);
wcstombs(AsciiTitle, Certificate.TitleName, 40);
printf("OK\n");
printf("Xbe::Xbe: Title identified as %s\n", m_szAsciiTitle);
printf("Xbe::Xbe: Title identified as %s\n", AsciiTitle);
}
// ******************************************************************
@ -155,14 +198,14 @@ Xbe::Xbe(const char *x_szFilename)
{
printf("Xbe::Xbe: Reading Section Headers...\n");
fseek(XbeFile, m_Header.dwSectionHeadersAddr - m_Header.dwBaseAddr, SEEK_SET);
fseek(XbeFile, Header.SectionHeadersAddr - Header.BaseAddr, SEEK_SET);
m_SectionHeader = new SectionHeader[m_Header.dwSections];
for(uint32 v=0; v<m_Header.dwSections; v++)
SectionHeader = new Xbe::SECTION_HEADER[Header.Sections];
for(uint32 v = 0; v < Header.Sections; v++)
{
printf("Xbe::Xbe: Reading Section Header 0x%.04X...", v);
if(fread(&m_SectionHeader[v], sizeof(*m_SectionHeader), 1, XbeFile) != 1)
if(fread(&SectionHeader[v], sizeof(Xbe::SECTION_HEADER), 1, XbeFile) != 1)
XBE_ERROR("Unexpected end of file while reading Xbe Section Header %d (%Xh)", v, v);
printf("OK\n");
@ -175,44 +218,44 @@ Xbe::Xbe(const char *x_szFilename)
{
printf("Xbe::Xbe: Reading Section Names...\n");
m_szSectionName = new char[m_Header.dwSections][9];
for(uint32 v=0; v<m_Header.dwSections; v++)
SectionName = new char[Header.Sections][9];
for(uint32 v = 0; v < Header.Sections; v++)
{
printf("Xbe::Xbe: Reading Section Name 0x%.04X...", v);
uint08 *sn = GetAddr(m_SectionHeader[v].dwSectionNameAddr);
uint08 *sn = GetAddr(SectionHeader[v].SectionNameAddr);
memset(m_szSectionName[v], 0, 9);
memset(SectionName[v], 0, 9);
if(sn != 0)
{
for(int b=0; b<8; b++)
for(int b = 0; b < 8; b++)
{
m_szSectionName[v][b] = sn[b];
if(m_szSectionName[v][b] == '\0')
SectionName[v][b] = sn[b];
if(SectionName[v][b] == '\0')
break;
}
}
printf("OK (%s)\n", m_szSectionName[v]);
printf("OK (%s)\n", SectionName[v]);
}
}
// ******************************************************************
// * read xbe library versions
// ******************************************************************
if(m_Header.dwLibraryVersionsAddr != 0)
if(Header.LibraryVersionsAddr != 0)
{
printf("Xbe::Xbe: Reading Library Versions...\n");
fseek(XbeFile, m_Header.dwLibraryVersionsAddr - m_Header.dwBaseAddr, SEEK_SET);
fseek(XbeFile, Header.LibraryVersionsAddr - Header.BaseAddr, SEEK_SET);
m_LibraryVersion = new LibraryVersion[m_Header.dwLibraryVersions];
for(uint32 v=0; v<m_Header.dwLibraryVersions; v++)
LibraryVersion = new Xbe::LIBRARY_VERSION[Header.LibraryVersions];
for(uint32 v = 0; v < Header.LibraryVersions; v++)
{
printf("Xbe::Xbe: Reading Library Version 0x%.04X...", v);
if(fread(&m_LibraryVersion[v], sizeof(*m_LibraryVersion), 1, XbeFile) != 1)
if(fread(&LibraryVersion[v], sizeof(Xbe::LIBRARY_VERSION), 1, XbeFile) != 1)
XBE_ERROR("Unexpected end of file while reading Xbe Library Version %d (%Xh)", v, v);
printf("OK\n");
@ -224,13 +267,13 @@ Xbe::Xbe(const char *x_szFilename)
{
printf("Xbe::Xbe: Reading Kernel Library Version...");
if(m_Header.dwKernelLibraryVersionAddr == 0)
if(Header.KernelLibraryVersionAddr == 0)
XBE_ERROR("Could not locate kernel library version");
fseek(XbeFile, m_Header.dwKernelLibraryVersionAddr - m_Header.dwBaseAddr, SEEK_SET);
fseek(XbeFile, Header.KernelLibraryVersionAddr - Header.BaseAddr, SEEK_SET);
m_KernelLibraryVersion = new LibraryVersion;
if(fread(m_KernelLibraryVersion, sizeof(*m_LibraryVersion), 1, XbeFile) != 1)
KernelLibraryVersion = new Xbe::LIBRARY_VERSION;
if(fread(KernelLibraryVersion, sizeof(Xbe::LIBRARY_VERSION), 1, XbeFile) != 1)
XBE_ERROR("Unexpected end of file while reading Xbe Kernel Version");
printf("OK\n");
@ -242,13 +285,13 @@ Xbe::Xbe(const char *x_szFilename)
{
printf("Xbe::Xbe: Reading Xapi Library Version...");
if(m_Header.dwXAPILibraryVersionAddr == 0)
if(Header.XapiLibraryVersionAddr == 0)
XBE_ERROR("Could not locate Xapi Library Version", true);
fseek(XbeFile, m_Header.dwXAPILibraryVersionAddr - m_Header.dwBaseAddr, SEEK_SET);
fseek(XbeFile, Header.XapiLibraryVersionAddr - Header.BaseAddr, SEEK_SET);
m_XAPILibraryVersion = new LibraryVersion;
if(fread(m_XAPILibraryVersion, sizeof(*m_LibraryVersion), 1, XbeFile) != 1)
XapiLibraryVersion = new Xbe::LIBRARY_VERSION;
if(fread(XapiLibraryVersion, sizeof(Xbe::LIBRARY_VERSION), 1, XbeFile) != 1)
XBE_ERROR("Unexpected end of file while reading Xbe Xapi Version", true);
printf("OK\n");
@ -261,18 +304,18 @@ Xbe::Xbe(const char *x_szFilename)
{
printf("Xbe::Xbe: Reading Sections...\n");
m_bzSection = new uint08*[m_Header.dwSections];
Section = new uint08*[Header.Sections];
memset(m_bzSection, 0, m_Header.dwSections);
memset(Section, 0, Header.Sections);
for(uint32 v=0; v<m_Header.dwSections; v++)
for(uint32 v = 0; v < Header.Sections; v++)
{
printf("Xbe::Xbe: Reading Section 0x%.04X...", v);
uint32 RawSize = m_SectionHeader[v].dwSizeOfRaw;
uint32 RawAddr = m_SectionHeader[v].dwRawAddr;
uint32 RawSize = SectionHeader[v].SizeOfRaw;
uint32 RawAddr = SectionHeader[v].RawAddr;
m_bzSection[v] = new uint08[RawSize];
Section[v] = new uint08[RawSize];
fseek(XbeFile, RawAddr, SEEK_SET);
@ -282,8 +325,8 @@ Xbe::Xbe(const char *x_szFilename)
continue;
}
if(fread(m_bzSection[v], RawSize, 1, XbeFile) != 1)
XBE_ERROR("Unexpected end of file while reading Xbe Section %d (%Xh) (%s)", v, v, m_szSectionName[v]);
if(fread(Section[v], RawSize, 1, XbeFile) != 1)
XBE_ERROR("Unexpected end of file while reading Xbe Section %d (%Xh) (%s)", v, v, SectionName[v]);
printf("OK\n");
}
@ -292,16 +335,16 @@ Xbe::Xbe(const char *x_szFilename)
// ******************************************************************
// * read xbe thread local storage
// ******************************************************************
if(m_Header.dwTLSAddr != 0)
if(Header.TlsAddr != 0)
{
printf("Xbe::Xbe: Reading Thread Local Storage...");
void *Addr = GetAddr(m_Header.dwTLSAddr);
void *Addr = GetAddr(Header.TlsAddr);
if(Addr == 0)
XBE_ERROR("Could not locate Thread Local Storage");
m_TLS = new TLS;
memcpy(m_TLS, Addr, sizeof(*m_TLS));
Tls = new Xbe::TLS;
memcpy(Tls, Addr, sizeof(Xbe::TLS));
printf("OK\n");
}
@ -315,186 +358,222 @@ Xbe::Xbe(const char *x_szFilename)
// ******************************************************************
Xbe::~Xbe()
{
if(m_bzSection != 0)
if(Section != 0)
{
for(uint32 v=0; v<m_Header.dwSections; v++)
delete[] m_bzSection[v];
for(uint32 v = 0; v < Header.Sections; v++)
delete[] Section[v];
delete[] m_bzSection;
delete[] Section;
}
delete m_XAPILibraryVersion;
delete m_KernelLibraryVersion;
delete[] m_LibraryVersion;
delete m_TLS;
delete[] m_szSectionName;
delete[] m_SectionHeader;
delete[] m_HeaderEx;
delete XapiLibraryVersion;
delete KernelLibraryVersion;
delete[] LibraryVersion;
delete Tls;
delete[] SectionName;
delete[] SectionHeader;
delete[] HeaderEx;
}
// ******************************************************************
// * Patcher
// ******************************************************************
int32 Xbe::PatchXbe()
{
printf("Xbe::PatchExe Patching MapRegisters in Xbe...");
// ******************************************************************
// * find section with Direct3D code
// ******************************************************************
uint32 v;
for (v = 0; v < Header.Sections; v++)
if (strncmp(SectionName[v], "D3D", 9) == 0)
break;
if (v == Header.Sections)
XBE_PATCH_ERROR("Could not find D3D section");
// ******************************************************************
// * find patching location in D3D section
// ******************************************************************
uint32 i;
for (i = 0; i < SectionHeader[v].SizeOfRaw - PATCH_LENGTH; i++)
if (memcmp(&Section[v][i], PatchSignature, PATCH_LENGTH) == 0)
break;
if (i == SectionHeader[v].SizeOfRaw - PATCH_LENGTH)
XBE_PATCH_ERROR("Could not find signature in D3D section");
// ******************************************************************
// * patch MapRegisters
// ******************************************************************
memcpy(&Section[v][i], &PatchCode, PATCH_LENGTH);
printf("OK\n");
return 0;
}
// ******************************************************************
// * Writer
// ******************************************************************
int32 Xbe::WriteExe(const char *x_szFilename)
int32 Xbe::WriteExe(const char *Filename)
{
printf("Xbe::WriteExe Converting Xbe to Exe...");
if (PatchXbe() != 0)
return 1;
// ******************************************************************
// * create buffer for "as-loaded" XBE/EXE hybrid
// ******************************************************************
uint08 *ExeBuffer = new uint08[m_Header.dwSizeOfImage];
uint08 *ExeBuffer = new uint08[Header.SizeOfImage];
if (ExeBuffer == 0)
XBE_WRITE_ERROR("Cannot allocate buffer for Exe");
memset(ExeBuffer, 0, m_Header.dwSizeOfImage);
memset(ExeBuffer, 0, Header.SizeOfImage);
// ******************************************************************
// * write xbe section headers
// ******************************************************************
memcpy(ExeBuffer + 0, &m_Header, sizeof(Xbe::Header));
memcpy(ExeBuffer + m_Header.dwSizeOfImageHeader, m_HeaderEx, m_HeaderExSize);
memcpy(ExeBuffer + 0, &Header, sizeof(Xbe::HEADER));
memcpy(ExeBuffer + Header.SizeOfImageHeader, HeaderEx, HeaderExSize);
// ******************************************************************
// * write xbe sections
// ******************************************************************
for (uint32 v=0; v<m_Header.dwSections; v++)
for (uint32 v = 0; v < Header.Sections; v++)
{
uint32 offs = m_SectionHeader[v].dwVirtualAddr - m_Header.dwBaseAddr;
memcpy(ExeBuffer + offs, m_bzSection[v], m_SectionHeader[v].dwSizeOfRaw);
uint32 offs = SectionHeader[v].VirtualAddr - Header.BaseAddr;
memcpy(ExeBuffer + offs, Section[v], SectionHeader[v].SizeOfRaw);
}
// ******************************************************************
// * patch digital signature with PE stub
// ******************************************************************
MicroExeHeaders ExeHeaders;
MICRO_EXE_HEADERS ExeHeaders;
ExeHeaders.m_DOSHeader.wMagic = *(uint16 *)"MZ";
ExeHeaders.m_DOSHeader.Unused = 0;
ExeHeaders.DosHeader.Magic = *(uint16 *)"MZ";
ExeHeaders.DosHeader.Unused = 0;
ExeHeaders.m_Header.dwMagic = *(uint32 *)"PE\0\0";
ExeHeaders.m_Header.wMachine = IMAGE_FILE_MACHINE_I386;
ExeHeaders.m_Header.wNumberOfSections = 1;
ExeHeaders.m_Header.dwTimeDateStamp = m_Header.dwTimeDate;
ExeHeaders.m_Header.dwPointerToSymbolTable = 0;
ExeHeaders.m_Header.dwNumberOfSymbols = 0;
ExeHeaders.m_Header.wSizeOfOptionalHeader = sizeof(MicroExeHeaders::OptionalHeader);
ExeHeaders.m_Header.wCharacteristics = 0x0103;
ExeHeaders.Header.Magic = *(uint32 *)"PE\0\0";
ExeHeaders.Header.Machine = IMAGE_FILE_MACHINE_I386;
ExeHeaders.Header.NumberOfSections = 1;
ExeHeaders.Header.TimeDateStamp = Header.TimeDate;
ExeHeaders.Header.PointerToSymbolTable = 0;
ExeHeaders.Header.NumberOfSymbols = 0;
ExeHeaders.Header.SizeOfOptionalHeader = sizeof(MICRO_EXE_HEADERS::OPTIONAL_HEADER);
ExeHeaders.Header.Characteristics = 0x0103;
ExeHeaders.m_OptionalHeader.wMagic = 0x010B;
ExeHeaders.m_OptionalHeader.bMajorLinkerVersion = 0x06;
ExeHeaders.m_OptionalHeader.bMinorLinkerVersion = 0x00;
ExeHeaders.m_OptionalHeader.dwSizeOfCode = 0;
ExeHeaders.m_OptionalHeader.dwSizeOfInitializedData = 0;
ExeHeaders.m_OptionalHeader.dwSizeOfUninitializedData = 0;
ExeHeaders.m_OptionalHeader.dwAddressOfEntryPoint = (uint32)&ExeHeaders.m_Trampoline - (uint32)&ExeHeaders;
ExeHeaders.m_OptionalHeader.dwBaseOfCode = 0;
ExeHeaders.m_OptionalHeader.dwBaseOfData = 0;
ExeHeaders.OptionalHeader.Magic = 0x010B;
ExeHeaders.OptionalHeader.MajorLinkerVersion = 0x06;
ExeHeaders.OptionalHeader.MinorLinkerVersion = 0x00;
ExeHeaders.OptionalHeader.SizeOfCode = 0;
ExeHeaders.OptionalHeader.SizeOfInitializedData = 0;
ExeHeaders.OptionalHeader.SizeOfUninitializedData = 0;
ExeHeaders.OptionalHeader.AddressOfEntryPoint = (uint32)&ExeHeaders.Trampoline - (uint32)&ExeHeaders;
ExeHeaders.OptionalHeader.BaseOfCode = 0;
ExeHeaders.OptionalHeader.BaseOfData = 0;
ExeHeaders.m_OptionalHeader.dwImageBase = m_Header.dwBaseAddr;
ExeHeaders.m_OptionalHeader.dwLfanew_SectionAlignment = EXE_ALIGNMENT;
ExeHeaders.m_OptionalHeader.dwFileAlignment = EXE_ALIGNMENT;
ExeHeaders.m_OptionalHeader.wMajorOperatingSystemVersion = 4;
ExeHeaders.m_OptionalHeader.wMinorOperatingSystemVersion = 0;
ExeHeaders.m_OptionalHeader.wMajorImageVersion = 0;
ExeHeaders.m_OptionalHeader.wMinorImageVersion = 0;
ExeHeaders.m_OptionalHeader.wMajorSubsystemVersion = 4;
ExeHeaders.m_OptionalHeader.wMinorSubsystemVersion = 0;
ExeHeaders.m_OptionalHeader.dwWin32VersionValue = 0;
ExeHeaders.m_OptionalHeader.dwSizeOfImage = m_Header.dwSizeOfImage; // already aligned at 0x20
ExeHeaders.m_OptionalHeader.dwSizeOfHeaders = RoundUp(sizeof(MicroExeHeaders), EXE_ALIGNMENT);
ExeHeaders.m_OptionalHeader.dwCheckSum = 0;
ExeHeaders.m_OptionalHeader.wSubsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
ExeHeaders.m_OptionalHeader.wDllCharacteristics = 0x400;
ExeHeaders.m_OptionalHeader.dwSizeOfStackReserve = 0x100000;
ExeHeaders.m_OptionalHeader.dwSizeOfStackCommit = 0x1000;
ExeHeaders.m_OptionalHeader.dwSizeOfHeapReserve = 0x100000;
ExeHeaders.m_OptionalHeader.dwSizeOfHeapCommit = 0x1000;
ExeHeaders.m_OptionalHeader.dwLoaderFlags = 0;
ExeHeaders.m_OptionalHeader.dwNumberOfRvaAndSizes = 4;
ExeHeaders.OptionalHeader.ImageBase = Header.BaseAddr;
ExeHeaders.OptionalHeader.Lfanew_SectionAlignment = EXE_ALIGNMENT;
ExeHeaders.OptionalHeader.FileAlignment = EXE_ALIGNMENT;
ExeHeaders.OptionalHeader.MajorOperatingSystemVersion = 4;
ExeHeaders.OptionalHeader.MinorOperatingSystemVersion = 0;
// This is where the imported DLL name "DbE\0" will be located
strncpy(ExeHeaders.OptionalHeader.DirtboxDllName, "DbE", 4);
ExeHeaders.OptionalHeader.MajorSubsystemVersion = 4;
ExeHeaders.OptionalHeader.MinorSubsystemVersion = 0;
ExeHeaders.OptionalHeader.Win32VersionValue = 0;
ExeHeaders.OptionalHeader.SizeOfImage = Header.SizeOfImage; // already aligned at 0x20
ExeHeaders.OptionalHeader.SizeOfHeaders = RoundUp(sizeof(MICRO_EXE_HEADERS), EXE_ALIGNMENT);
ExeHeaders.OptionalHeader.CheckSum = 0;
ExeHeaders.OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
ExeHeaders.OptionalHeader.DllCharacteristics = 0x400;
ExeHeaders.OptionalHeader.SizeOfStackReserve = 0x100000;
ExeHeaders.OptionalHeader.SizeOfStackCommit = 0x1000;
ExeHeaders.OptionalHeader.SizeOfHeapReserve = 0x100000;
ExeHeaders.OptionalHeader.SizeOfHeapCommit = 0x1000;
ExeHeaders.OptionalHeader.LoaderFlags = 0;
ExeHeaders.OptionalHeader.NumberOfRvaAndSizes = 4;
// ******************************************************************
// * the other directories
// ******************************************************************
for (uint32 v=0; v<4; v++)
for (uint32 v = 0; v < 4; v++)
{
ExeHeaders.m_OptionalHeader.astDataDirectory[v].dwVirtualAddress = 0;
ExeHeaders.m_OptionalHeader.astDataDirectory[v].dwSize = 0;
ExeHeaders.OptionalHeader.DataDirectory[v].VirtualAddress = 0;
ExeHeaders.OptionalHeader.DataDirectory[v].Size = 0;
}
// ******************************************************************
// * import directory
// ******************************************************************
uint32 offs = (uint32)&ExeHeaders.m_ImageImportDescriptor - (uint32)&ExeHeaders;
uint32 offs = (uint32)&ExeHeaders.ImageImportDescriptor - (uint32)&ExeHeaders;
ExeHeaders.m_OptionalHeader.astDataDirectory[1].dwVirtualAddress = offs;
ExeHeaders.m_OptionalHeader.astDataDirectory[1].dwSize = 2*sizeof(MicroExeHeaders::ImageImportDescriptor);
ExeHeaders.OptionalHeader.DataDirectory[1].VirtualAddress = offs;
ExeHeaders.OptionalHeader.DataDirectory[1].Size =
2*sizeof(MICRO_EXE_HEADERS::IMAGE_IMPORT_DESCRIPTOR);
// ******************************************************************
// * the one and only section header
// ******************************************************************
uint32 XbeSectionAddress = 0; // the whole image
uint32 XbeSectionSize = m_Header.dwSizeOfImage - XbeSectionAddress; // already aligned at 0x20
uint32 XbeSectionSize = Header.SizeOfImage - XbeSectionAddress; // already aligned at 0x20
strncpy((char *)ExeHeaders.m_SectionHeader.szName, "loldongs", 8);
ExeHeaders.m_SectionHeader.dwVirtualSize = XbeSectionSize;
ExeHeaders.m_SectionHeader.dwVirtualAddress = XbeSectionAddress;
ExeHeaders.m_SectionHeader.dwSizeOfRawData = XbeSectionSize;
ExeHeaders.m_SectionHeader.dwPointerToRawData = XbeSectionAddress;
ExeHeaders.m_SectionHeader.dwPointerToRelocations = 0;
ExeHeaders.m_SectionHeader.dwPointerToLinenumbers = 0;
ExeHeaders.m_SectionHeader.wNumberOfRelocations = 0;
ExeHeaders.m_SectionHeader.wNumberOfLinenumbers = 0;
ExeHeaders.m_SectionHeader.dwCharacteristics = 0x60000020;
strncpy(ExeHeaders.SectionHeader.Name, "loldong", 8);
ExeHeaders.SectionHeader.VirtualSize = XbeSectionSize;
ExeHeaders.SectionHeader.VirtualAddress = XbeSectionAddress;
ExeHeaders.SectionHeader.SizeOfRawData = XbeSectionSize;
ExeHeaders.SectionHeader.PointerToRawData = XbeSectionAddress;
ExeHeaders.SectionHeader.PointerToRelocations = 0;
ExeHeaders.SectionHeader.PointerToLinenumbers = 0;
ExeHeaders.SectionHeader.NumberOfRelocations = 0;
ExeHeaders.SectionHeader.NumberOfLinenumbers = 0;
ExeHeaders.SectionHeader.Characteristics = 0x60000020;
// ******************************************************************
// * image import descriptor, only one DLL
// ******************************************************************
uint32 offsIat = (uint32)&ExeHeaders.m_ImportAddressTable - (uint32)&ExeHeaders;
uint32 offsName = (uint32)&ExeHeaders.m_ImportName - (uint32)&ExeHeaders;
uint32 offsIat = (uint32)&ExeHeaders.ImportAddressTable - (uint32)&ExeHeaders;
uint32 offsName = (uint32)ExeHeaders.OptionalHeader.DirtboxDllName - (uint32)&ExeHeaders;
ExeHeaders.m_ImageImportDescriptor[0].dwOriginalFirstThunk = offsIat;
ExeHeaders.m_ImageImportDescriptor[0].dwTimeDateStamp = 0;
ExeHeaders.m_ImageImportDescriptor[0].dwForwarderChain = 0;
ExeHeaders.m_ImageImportDescriptor[0].dwName = offsName;
ExeHeaders.m_ImageImportDescriptor[0].dwFirstThunk = offsIat;
ExeHeaders.ImageImportDescriptor[0].OriginalFirstThunk = offsIat;
ExeHeaders.ImageImportDescriptor[0].TimeDateStamp = 0;
ExeHeaders.ImageImportDescriptor[0].ForwarderChain = 0;
ExeHeaders.ImageImportDescriptor[0].Name = offsName;
ExeHeaders.ImageImportDescriptor[0].FirstThunk = offsIat;
ExeHeaders.m_ImageImportDescriptor[1].dwOriginalFirstThunk = 0;
ExeHeaders.m_ImageImportDescriptor[1].dwTimeDateStamp = 0;
ExeHeaders.m_ImageImportDescriptor[1].dwForwarderChain = 0;
ExeHeaders.m_ImageImportDescriptor[1].dwName = 0;
ExeHeaders.m_ImageImportDescriptor[1].dwFirstThunk = 0;
ExeHeaders.ImageImportDescriptor[1].OriginalFirstThunk = 0;
ExeHeaders.ImageImportDescriptor[1].TimeDateStamp = 0;
ExeHeaders.ImageImportDescriptor[1].ForwarderChain = 0;
ExeHeaders.ImageImportDescriptor[1].Name = 0;
ExeHeaders.ImageImportDescriptor[1].FirstThunk = 0;
// ******************************************************************
// * import address table, import by ordinal
// ******************************************************************
ExeHeaders.m_ImportAddressTable[0] = 0x80000001;
ExeHeaders.m_ImportAddressTable[1] = 0;
// ******************************************************************
// * imported DLL name
// ******************************************************************
strncpy(ExeHeaders.m_ImportName, "DirtboxKe", 10);
ExeHeaders.ImportAddressTable[0] = 0x80000001;
ExeHeaders.ImportAddressTable[1] = 0;
// ******************************************************************
// * trampoline that calls the Dirtbox loader in the DLL
// ******************************************************************
ExeHeaders.m_Trampoline[0] = 0xFF; // JMP near absolute indirect
ExeHeaders.m_Trampoline[1] = 0x25; // memory
*(uint32 *)&ExeHeaders.m_Trampoline[2] = 0x000100EC;
memcpy(ExeHeaders.Trampoline, &TrampolineCode, TRAMPOLINE_LENGTH);
// ******************************************************************
// * replaces the magic and digital signature with PE headers
// ******************************************************************
memcpy(ExeBuffer + 0, &ExeHeaders, sizeof(MicroExeHeaders));
memcpy(ExeBuffer + 0, &ExeHeaders, sizeof(MICRO_EXE_HEADERS));
// ******************************************************************
// * write the created buffer into EXE file
// ******************************************************************
FILE *ExeFile = fopen(x_szFilename, "wb");
FILE *ExeFile = fopen(Filename, "wb");
if (ExeFile == 0)
XBE_WRITE_ERROR("Could not open Exe file");
fwrite(ExeBuffer, m_Header.dwSizeOfImage, 1, ExeFile);
fwrite(ExeBuffer, Header.SizeOfImage, 1, ExeFile);
fclose(ExeFile);
// ******************************************************************
@ -510,33 +589,33 @@ int32 Xbe::WriteExe(const char *x_szFilename)
// ******************************************************************
// * GetAddr
// ******************************************************************
uint08 *Xbe::GetAddr(uint32 x_dwVirtualAddress)
uint08 *Xbe::GetAddr(uint32 VirtualAddress)
{
uint32 offs = x_dwVirtualAddress - m_Header.dwBaseAddr;
uint32 offs = VirtualAddress - Header.BaseAddr;
// ******************************************************************
// * offset in image header
// ******************************************************************
if(offs < sizeof(m_Header))
return &((uint08*)&m_Header)[offs];
if(offs < sizeof(Header))
return &((uint08*)&Header)[offs];
// ******************************************************************
// * offset in image header extra bytes
// ******************************************************************
if(offs < m_Header.dwSizeOfHeaders)
return (uint08*)&m_HeaderEx[offs - sizeof(m_Header)];
if(offs < Header.SizeOfHeaders)
return (uint08*)&HeaderEx[offs - sizeof(Header)];
// ******************************************************************
// * offset in some random section
// ******************************************************************
{
for(uint32 v=0; v<m_Header.dwSections; v++)
for(uint32 v = 0; v < Header.Sections; v++)
{
uint32 VirtAddr = m_SectionHeader[v].dwVirtualAddr;
uint32 VirtSize = m_SectionHeader[v].dwVirtualSize;
uint32 VirtAddr = SectionHeader[v].VirtualAddr;
uint32 VirtSize = SectionHeader[v].VirtualSize;
if( (x_dwVirtualAddress >= VirtAddr) && (x_dwVirtualAddress < (VirtAddr + VirtSize)) )
return &m_bzSection[v][x_dwVirtualAddress - VirtAddr];
if( (VirtualAddress >= VirtAddr) && (VirtualAddress < (VirtAddr + VirtSize)) )
return &Section[v][VirtualAddress - VirtAddr];
}
}

380
Xbe.h
View file

@ -41,214 +41,218 @@
// ******************************************************************
class Xbe
{
public:
// ******************************************************************
// * Construct via Xbe file
// ******************************************************************
Xbe(const char *x_szFilename);
public:
// ******************************************************************
// * Construct via Xbe file
// ******************************************************************
Xbe(const char *x_szFilename);
// ******************************************************************
// * Deconstructor
// ******************************************************************
~Xbe();
// ******************************************************************
// * Deconstructor
// ******************************************************************
~Xbe();
// ******************************************************************
// * Writer
// ******************************************************************
int32 WriteExe(const char *x_szFilename);
// ******************************************************************
// * Patcher
// ******************************************************************
int32 PatchXbe();
// ******************************************************************
// * XBE header
// ******************************************************************
#include "AlignPrefix1.h"
struct Header
// ******************************************************************
// * Writer
// ******************************************************************
int32 WriteExe(const char *x_szFilename);
// ******************************************************************
// * XBE header
// ******************************************************************
#include "AlignPrefix1.h"
struct HEADER
{
uint32 Magic; // 0x0000 - magic number [should be "XBEH"]
uint08 DigitalSignature[256]; // 0x0004 - digital signature
uint32 BaseAddr; // 0x0104 - base address
uint32 SizeOfHeaders; // 0x0108 - size of headers
uint32 SizeOfImage; // 0x010C - size of image
uint32 SizeOfImageHeader; // 0x0110 - size of image header
uint32 TimeDate; // 0x0114 - timedate stamp
uint32 CertificateAddr; // 0x0118 - certificate address
uint32 Sections; // 0x011C - number of sections
uint32 SectionHeadersAddr; // 0x0120 - section headers address
struct INIT_FLAGS // 0x0124 - initialization flags
{
uint32 dwMagic; // 0x0000 - magic number [should be "XBEH"]
uint08 pbDigitalSignature[256]; // 0x0004 - digital signature
uint32 dwBaseAddr; // 0x0104 - base address
uint32 dwSizeOfHeaders; // 0x0108 - size of headers
uint32 dwSizeOfImage; // 0x010C - size of image
uint32 dwSizeOfImageHeader; // 0x0110 - size of image header
uint32 dwTimeDate; // 0x0114 - timedate stamp
uint32 dwCertificateAddr; // 0x0118 - certificate address
uint32 dwSections; // 0x011C - number of sections
uint32 dwSectionHeadersAddr; // 0x0120 - section headers address
uint32 MountUtilityDrive : 1; // mount utility drive flag
uint32 FormatUtilityDrive : 1; // format utility drive flag
uint32 Limit64MB : 1; // limit development kit run time memory to 64mb flag
uint32 DontSetupHarddisk : 1; // don't setup hard disk flag
uint32 Unused : 4; // unused (or unknown)
uint32 Unused_b1 : 8; // unused (or unknown)
uint32 Unused_b2 : 8; // unused (or unknown)
uint32 Unused_b3 : 8; // unused (or unknown)
} InitFlags;
struct InitFlags // 0x0124 - initialization flags
{
uint32 bMountUtilityDrive : 1; // mount utility drive flag
uint32 bFormatUtilityDrive : 1; // format utility drive flag
uint32 bLimit64MB : 1; // limit development kit run time memory to 64mb flag
uint32 bDontSetupHarddisk : 1; // don't setup hard disk flag
uint32 Unused : 4; // unused (or unknown)
uint32 Unused_b1 : 8; // unused (or unknown)
uint32 Unused_b2 : 8; // unused (or unknown)
uint32 Unused_b3 : 8; // unused (or unknown)
}
dwInitFlags;
uint32 EntryAddr; // 0x0128 - entry point address
uint32 TlsAddr; // 0x012C - thread local storage directory address
uint32 PeStackCommit; // 0x0130 - size of stack commit
uint32 PeHeapReserve; // 0x0134 - size of heap reserve
uint32 PeHeapCommit; // 0x0138 - size of heap commit
uint32 PeBaseAddr; // 0x013C - original base address
uint32 PeSizeOfImage; // 0x0140 - size of original image
uint32 PeChecksum; // 0x0144 - original checksum
uint32 PeTimeDate; // 0x0148 - original timedate stamp
uint32 DebugPathnameAddr; // 0x014C - debug pathname address
uint32 DebugFilenameAddr; // 0x0150 - debug filename address
uint32 DebugUnicodeFilenameAddr; // 0x0154 - debug unicode filename address
uint32 KernelImageThunkAddr; // 0x0158 - kernel image thunk address
uint32 NonKernelImportDirAddr; // 0x015C - non kernel import directory address
uint32 LibraryVersions; // 0x0160 - number of library versions
uint32 LibraryVersionsAddr; // 0x0164 - library versions address
uint32 KernelLibraryVersionAddr; // 0x0168 - kernel library version address
uint32 XapiLibraryVersionAddr; // 0x016C - xapi library version address
uint32 LogoBitmapAddr; // 0x0170 - logo bitmap address
uint32 SizeOfLogoBitmap; // 0x0174 - logo bitmap size
}
#include "AlignPosfix1.h"
Header;
uint32 dwEntryAddr; // 0x0128 - entry point address
uint32 dwTLSAddr; // 0x012C - thread local storage directory address
uint32 dwPeStackCommit; // 0x0130 - size of stack commit
uint32 dwPeHeapReserve; // 0x0134 - size of heap reserve
uint32 dwPeHeapCommit; // 0x0138 - size of heap commit
uint32 dwPeBaseAddr; // 0x013C - original base address
uint32 dwPeSizeOfImage; // 0x0140 - size of original image
uint32 dwPeChecksum; // 0x0144 - original checksum
uint32 dwPeTimeDate; // 0x0148 - original timedate stamp
uint32 dwDebugPathnameAddr; // 0x014C - debug pathname address
uint32 dwDebugFilenameAddr; // 0x0150 - debug filename address
uint32 dwDebugUnicodeFilenameAddr; // 0x0154 - debug unicode filename address
uint32 dwKernelImageThunkAddr; // 0x0158 - kernel image thunk address
uint32 dwNonKernelImportDirAddr; // 0x015C - non kernel import directory address
uint32 dwLibraryVersions; // 0x0160 - number of library versions
uint32 dwLibraryVersionsAddr; // 0x0164 - library versions address
uint32 dwKernelLibraryVersionAddr; // 0x0168 - kernel library version address
uint32 dwXAPILibraryVersionAddr; // 0x016C - xapi library version address
uint32 dwLogoBitmapAddr; // 0x0170 - logo bitmap address
uint32 dwSizeOfLogoBitmap; // 0x0174 - logo bitmap size
}
#include "AlignPosfix1.h"
m_Header;
// ******************************************************************
// * XBE header extra bytes (used to preserve unknown data)
// ******************************************************************
char *HeaderEx;
uint32 HeaderExSize;
// ******************************************************************
// * XBE header extra bytes (used to preserve unknown data)
// ******************************************************************
char *m_HeaderEx;
uint32 m_HeaderExSize;
// ******************************************************************
// * XBE certificate
// ******************************************************************
#include "AlignPrefix1.h"
struct CERTIFICATE
{
uint32 Size; // 0x0000 - size of certificate
uint32 TimeDate; // 0x0004 - timedate stamp
uint32 TitleId; // 0x0008 - title id
wchar_t TitleName[40]; // 0x000C - title name (unicode)
uint32 AlternateTitleId[0x10]; // 0x005C - alternate title ids
uint32 AllowedMedia; // 0x009C - allowed media types
uint32 GameRegion; // 0x00A0 - game region
uint32 GameRatings; // 0x00A4 - game ratings
uint32 DiskNumber; // 0x00A8 - disk number
uint32 Version; // 0x00AC - version
uint08 LanKey[16]; // 0x00B0 - lan key
uint08 SignatureKey[16]; // 0x00C0 - signature key
uint08 TitleAlternateSignatureKey[16][16]; // 0x00D0 - alternate signature keys
}
#include "AlignPosfix1.h"
Certificate;
// ******************************************************************
// * XBE certificate
// ******************************************************************
#include "AlignPrefix1.h"
struct Certificate
// ******************************************************************
// * XBE section header
// ******************************************************************
#include "AlignPrefix1.h"
struct SECTION_HEADER
{
struct _FLAGS
{
uint32 dwSize; // 0x0000 - size of certificate
uint32 dwTimeDate; // 0x0004 - timedate stamp
uint32 dwTitleId; // 0x0008 - title id
wchar_t wszTitleName[40]; // 0x000C - title name (unicode)
uint32 dwAlternateTitleId[0x10]; // 0x005C - alternate title ids
uint32 dwAllowedMedia; // 0x009C - allowed media types
uint32 dwGameRegion; // 0x00A0 - game region
uint32 dwGameRatings; // 0x00A4 - game ratings
uint32 dwDiskNumber; // 0x00A8 - disk number
uint32 dwVersion; // 0x00AC - version
uint08 bzLanKey[16]; // 0x00B0 - lan key
uint08 bzSignatureKey[16]; // 0x00C0 - signature key
uint08 bzTitleAlternateSignatureKey[16][16]; // 0x00D0 - alternate signature keys
uint32 Writable : 1; // writable flag
uint32 Preload : 1; // preload flag
uint32 Executable : 1; // executable flag
uint32 InsertedFile : 1; // inserted file flag
uint32 HeadPageRO : 1; // head page read only flag
uint32 TailPageRO : 1; // tail page read only flag
uint32 Unused_a1 : 1; // unused (or unknown)
uint32 Unused_a2 : 1; // unused (or unknown)
uint32 Unused_b1 : 8; // unused (or unknown)
uint32 Unused_b2 : 8; // unused (or unknown)
uint32 Unused_b3 : 8; // unused (or unknown)
}
#include "AlignPosfix1.h"
m_Certificate;
Flags;
// ******************************************************************
// * XBE section header
// ******************************************************************
#include "AlignPrefix1.h"
struct SectionHeader
uint32 VirtualAddr; // virtual address
uint32 VirtualSize; // virtual size
uint32 RawAddr; // file offset to raw data
uint32 SizeOfRaw; // size of raw data
uint32 SectionNameAddr; // section name addr
uint32 SectionRefCount; // section reference count
uint32 HeadSharedRefCountAddr; // head shared page reference count address
uint32 TailSharedRefCountAddr; // tail shared page reference count address
uint08 SectionDigest[20]; // section digest
}
#include "AlignPosfix1.h"
*SectionHeader;
// ******************************************************************
// * XBE library versions
// ******************************************************************
#include "AlignPrefix1.h"
struct LIBRARY_VERSION
{
char Name[8]; // library name
uint16 MajorVersion; // major version
uint16 MinorVersion; // minor version
uint16 BuildVersion; // build version
struct FLAGS
{
struct _Flags
{
uint32 bWritable : 1; // writable flag
uint32 bPreload : 1; // preload flag
uint32 bExecutable : 1; // executable flag
uint32 bInsertedFile : 1; // inserted file flag
uint32 bHeadPageRO : 1; // head page read only flag
uint32 bTailPageRO : 1; // tail page read only flag
uint32 Unused_a1 : 1; // unused (or unknown)
uint32 Unused_a2 : 1; // unused (or unknown)
uint32 Unused_b1 : 8; // unused (or unknown)
uint32 Unused_b2 : 8; // unused (or unknown)
uint32 Unused_b3 : 8; // unused (or unknown)
}
dwFlags;
uint32 dwVirtualAddr; // virtual address
uint32 dwVirtualSize; // virtual size
uint32 dwRawAddr; // file offset to raw data
uint32 dwSizeOfRaw; // size of raw data
uint32 dwSectionNameAddr; // section name addr
uint32 dwSectionRefCount; // section reference count
uint32 dwHeadSharedRefCountAddr; // head shared page reference count address
uint32 dwTailSharedRefCountAddr; // tail shared page reference count address
uint08 bzSectionDigest[20]; // section digest
uint16 QFEVersion : 13; // QFE Version
uint16 Approved : 2; // Approved? (0:no, 1:possibly, 2:yes)
uint16 DebugBuild : 1; // Is this a debug build?
}
#include "AlignPosfix1.h"
*m_SectionHeader;
Flags;
}
#include "AlignPosfix1.h"
*LibraryVersion, *KernelLibraryVersion, *XapiLibraryVersion;
// ******************************************************************
// * XBE library versions
// ******************************************************************
#include "AlignPrefix1.h"
struct LibraryVersion
{
char szName[8]; // library name
uint16 wMajorVersion; // major version
uint16 wMinorVersion; // minor version
uint16 wBuildVersion; // build version
// ******************************************************************
// * XBE Thread Local Storage
// ******************************************************************
#include "AlignPrefix1.h"
struct TLS
{
uint32 DataStartAddr; // raw start address
uint32 DataEndAddr; // raw end address
uint32 TlsIndexAddr; // tls index address
uint32 TlsCallbackAddr; // tls callback address
uint32 SizeOfZeroFill; // size of zero fill
uint32 Characteristics; // characteristics
}
#include "AlignPosfix1.h"
*Tls;
struct Flags
{
uint16 QFEVersion : 13; // QFE Version
uint16 Approved : 2; // Approved? (0:no, 1:possibly, 2:yes)
uint16 bDebugBuild : 1; // Is this a debug build?
}
dwFlags;
}
#include "AlignPosfix1.h"
*m_LibraryVersion, *m_KernelLibraryVersion, *m_XAPILibraryVersion;
// ******************************************************************
// * XBE section names, each 8 bytes max and null terminated
// ******************************************************************
char (*SectionName)[9];
// ******************************************************************
// * XBE Thread Local Storage
// ******************************************************************
#include "AlignPrefix1.h"
struct TLS
{
uint32 dwDataStartAddr; // raw start address
uint32 dwDataEndAddr; // raw end address
uint32 dwTLSIndexAddr; // tls index address
uint32 dwTLSCallbackAddr; // tls callback address
uint32 dwSizeOfZeroFill; // size of zero fill
uint32 dwCharacteristics; // characteristics
}
#include "AlignPosfix1.h"
*m_TLS;
// ******************************************************************
// * XBE sections
// ******************************************************************
uint08 **Section;
// ******************************************************************
// * XBE section names, each 8 bytes max and null terminated
// ******************************************************************
char (*m_szSectionName)[9];
// ******************************************************************
// * XBE original path
// ******************************************************************
char Path[260];
// ******************************************************************
// * XBE sections
// ******************************************************************
uint08 **m_bzSection;
// ******************************************************************
// * XBE ascii title, translated from certificate title
// ******************************************************************
char AsciiTitle[40];
// ******************************************************************
// * XBE original path
// ******************************************************************
char m_szPath[260];
// ******************************************************************
// * GetTlsData
// ******************************************************************
uint08 *GetTlsData() { if(Tls == 0) return 0; else return GetAddr(Tls->DataStartAddr); }
// ******************************************************************
// * XBE ascii title, translated from certificate title
// ******************************************************************
char m_szAsciiTitle[40];
// ******************************************************************
// * GetTlsIndex
// ******************************************************************
uint32 *GetTlsIndex() { if(Tls == 0) return 0; else return (uint32*)GetAddr(Tls->TlsIndexAddr); }
// ******************************************************************
// * GetTLSData
// ******************************************************************
uint08 *GetTLSData() { if(m_TLS == 0) return 0; else return GetAddr(m_TLS->dwDataStartAddr); }
// ******************************************************************
// * GetTLSIndex
// ******************************************************************
uint32 *GetTLSIndex() { if(m_TLS == 0) return 0; else return (uint32*)GetAddr(m_TLS->dwTLSIndexAddr); }
private:
// ******************************************************************
// * return a modifiable pointer inside this structure that
// * corresponds to a virtual address
// ******************************************************************
uint08 *GetAddr(uint32 x_dwVirtualAddress);
private:
// ******************************************************************
// * return a modifiable pointer inside this structure that
// * corresponds to a virtual address
// ******************************************************************
uint08 *GetAddr(uint32 VirtualAddress);
};
// ******************************************************************
@ -293,6 +297,6 @@ const uint32 XBEIMAGE_MEDIA_TYPE_MEDIA_MASK = 0x00FFFFFF;
// * OpenXDK logo bitmap (used by cxbe by default)
// ******************************************************************
extern uint08 OpenXDK[];
extern uint32 dwSizeOfOpenXDK;
extern uint32 SizeOfOpenXDK;
#endif