

#include <stdio.h>                     // Need this for fopen(..) fwrite(..) etc
#include <string.h>                    // memcpy(..)

// We use this simple function to write data to our file.
void fileout(char *str)
{
      FILE *fp;
      fp=fopen("output.txt", "a+");   // a+ -> if file doesn't exist create it, else
      fprintf(fp, "%s", str);         //       append to the end of the file
      fclose(fp); 
}// End fileout(..)

long FileSize( char * szFileName )
{
	FILE *file = fopen(szFileName, "rb"); // Open the file
	fseek(file, 0, SEEK_END);             // Seek to the end
	long file_size = ftell(file);         // Get the current position
	fclose(file);
	
	return file_size;                     // We have the file size, so return it
}// End FileSize(..)

// Remember that we use 'pragma pack(1)' so our data in the stucture is packed nice
// and tight using a 1 byte alignment.
#pragma pack(1)
struct stImageHeader
{
	char          sig[4];
	unsigned char auth_sig[0x100];
	unsigned int  base_address;
	unsigned int  size_header;
	unsigned int  size_image;
	unsigned int  size_image_header;
	unsigned int  time_date;
	unsigned int  cert_addr;
	unsigned int  num_sections;
	unsigned int  sect_addr;
	unsigned int  init_flags;
#define MountUtilityDrive    0x00000001
#define FormatUtilityDrive   0x00000002
#define Limit64Megabytes     0x00000004 
#define DontSetupHarddisk    0x00000008
	unsigned int  entry_point;
#define XOR_ENTRY_DEBUG      0x94859D4B
#define XOR_ENTRY_RETAIL     0xA8FC57AB
	unsigned int  tls_addr;
	unsigned int  pls_stack_commit;
	unsigned int  pe_heap_reserv;
	unsigned int  pe_heap_commit;
	unsigned int  pe_base_addr;
	unsigned int  pe_size_image;
	unsigned int  pe_checksum;
	unsigned int  pe_timedata;
	unsigned int  pathname_addr;
	unsigned int  filename_addr;
	unsigned int  unicode_filename_addr;
	unsigned int  kernel_thunk_addr;
#define XOR_KERNEL_DEBUG     0xEFB1F152
#define XOR_KERNEL_RETAIL    0x5B6D40B6
	unsigned int  non_kernel_dir_addr;
	unsigned int  num_lib_versions;
	unsigned int  lib_vers_addr;
	unsigned int  kernel_lib_vers_addr;
	unsigned int  xapi_lib_vers_addr;
	unsigned int  logo_bitmap_addr;
	unsigned int  logo_bitmap_size;
};
#pragma pack()



void ProcessXBE( unsigned char *pXBE, long iSizeXBE )
{

	stImageHeader IH;
	memcpy( &IH, pXBE, sizeof(stImageHeader) );

	// Large temp char buffer
	char buf[500];           

	int iOffset = 0;
	unsigned int * ptr = (unsigned int*)pXBE;

	// Write out the first 3 char's of the xbe to see what they are
	sprintf(buf, "Sig (0x4) (XBEH) = %c%c%c%c\n", 
		    IH.sig[0], IH.sig[1], IH.sig[2], IH.sig[3] );
	fileout(buf);

	sprintf(buf, "Base Address: 0x%08X\n", IH.base_address );
	fileout(buf);

	sprintf(buf, "Number Sections: 0x%08X\n", IH.num_sections );
	fileout(buf);

	sprintf(buf, "Section Address: 0x%08X\n", IH.sect_addr );
	fileout(buf);

	sprintf(buf, "Entry Point: 0x%08X (Decodes to: 0x%08X)\n", 
		                   IH.entry_point,  
						   IH.entry_point^XOR_ENTRY_RETAIL);
	fileout(buf);

	sprintf(buf, "Kernel Thunk Address: 0x%08X (Decodes to: 0x%08X)\n", 
		                  IH.kernel_thunk_addr, 
						  IH.kernel_thunk_addr^XOR_KERNEL_RETAIL );
	fileout(buf);

}// End ProcessXBE(..)

//Program Entry Point
void main(int argc, char* argv[])
{
	char szFileName[] = "default.xbe";    // Our input xbe
	char buf[500];                        // Large temp char buffer

	long iFileSize = FileSize(szFileName);

	sprintf(buf, "File: %s - xbe filesize: %d bytes\n\n", szFileName, iFileSize);
	fileout(buf);

	// Lets allocate enough memory for the whole xbe and read it all in
	unsigned char * pXBE = new unsigned char[iFileSize];

	// Open our xbe file
	FILE* fp = fopen( szFileName, "r" );
	fseek(fp, 0, SEEK_SET);

	// Read all the contents into our allocated memory 
	fread(pXBE, iFileSize, 1, fp);

	// Close our file.
	fclose( fp );

	//------------------------Our XBE Analysis Code-------------------------//

	ProcessXBE( pXBE, iFileSize );
	
	//------------------------End of XBE Analysis---------------------------//

	// Goodbye

	// Remember, before exiting the program, release the memory we allcoated for 
	// the xbe data we read in
	delete[] pXBE;

}// End main(..)






