mirror of
https://github.com/advancingdragon/Dirtbox.git
synced 2024-05-16 20:00:19 -04:00
Refactored code, added MapRegisters patcher.
This commit is contained in:
parent
fe3f60cf00
commit
b2a489ca16
148
MicroExe.h
148
MicroExe.h
|
@ -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"
|
||||
|
||||
|
|
8
Types.h
8
Types.h
|
@ -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
433
Xbe.cpp
|
@ -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
380
Xbe.h
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue