xbox-scene.com - your xbox news information source
Quick Links: Main Forums | Xbox360 Forums | Xbox1 Forums | PS3 Forums
Xbox-Scene Forum Help  Search Xbox-Scene Forums   Xbox-Scene Forum Members   Xbox-Scene Calendar

Giganews Usenet Offers: +1150 days binary retention, 99%+ Completion, and Unlimited Speed/Access!

360 ODD Emulators: X360 Key $99 | Wasabi360 FAT $99 | Wasabi360 Slim $99
C4E's iXtreme Burner MAX Drive: LiteOn iHAS124 DROPPED TO JUST $17


Welcome Guest ( Log In | Register )

 Forum Rules Rules
> Specs., Technical notes
^Blazed^
post Dec 10 2003, 11:03 AM
Post #1


Avalaunch Team
**

Group: Members
Posts: 268
Joined: 16-April 03
Member No.: 32558
Xbox Version: unk
360 version: unknown



How to find images in the xbe file

To be able to do this you must know how to walk
executables (in this case an xbe file).

The XBE header is documented quite well at caustik's
web site at the following address: 'http://www.caustik.com/xbox/download/xbe.htm'.

Kudos to caustik for his fantastic work.

The following definition of the header that is found in the xbe,
is almost an exact copy of what you can find at caustik's site:

CODE

// Note: This source is compatible with MSVC 6.0 or higher, and is public domain.

// ******************************************************************
// * standard typedefs
// ******************************************************************
typedef signed int     sint;
typedef unsigned int   uint;

typedef char           int08;
typedef short          int16;
typedef long           int32;

typedef unsigned char  uint08;
typedef unsigned short uint16;
typedef unsigned long  uint32;

typedef signed char    sint08;
typedef signed short   sint16;
typedef signed long    sint32;

typedef struct _xbe_info_
{
#pragma pack( push, before_header )
#pragma pack(1)
 struct header
 {
   uint32 magic;                         // magic number [should be "XBEH"]
   uint08 digsig[256];                   // digital signature
   uint32 base;                          // base address
   uint32 sizeof_headers;                // size of headers
   uint32 sizeof_image;                  // size of image
   uint32 sizeof_image_header;           // size of image header
   uint32 timedate;                      // timedate stamp
   uint32 certificate_addr;              // certificate address
   uint32 sections;                      // number of sections
   uint32 section_headers_addr;          // section headers address

   struct init_flags
   {
     uint mount_utility_drive    : 1;  // mount utility drive flag
     uint format_utility_drive   : 1;  // format utility drive flag
     uint limit_64mb             : 1;  // limit development kit run time memory to 64mb flag
     uint dont_setup_harddisk    : 1;  // don't setup hard disk flag
     uint unused                 : 4;  // unused (or unknown)
     uint unused_b1              : 8;  // unused (or unknown)
     uint unused_b2              : 8;  // unused (or unknown)
     uint unused_b3              : 8;  // unused (or unknown)
   } init_flags;

   uint32 entry;                         // entry point address
   uint32 tls_addr;                      // thread local storage directory address
   uint32 pe_stack_commit;               // size of stack commit
   uint32 pe_heap_reserve;               // size of heap reserve
   uint32 pe_heap_commit;                // size of heap commit
   uint32 pe_base_addr;                  // original base address
   uint32 pe_sizeof_image;               // size of original image
   uint32 pe_checksum;                   // original checksum
   uint32 pe_timedate;                   // original timedate stamp
   uint32 debug_pathname_addr;           // debug pathname address
   uint32 debug_filename_addr;           // debug filename address
   uint32 debug_unicode_filename_addr;   // debug unicode filename address
   uint32 kernel_image_thunk_addr;       // kernel image thunk address
   uint32 nonkernel_import_dir_addr;     // non kernel import directory address
   uint32 library_versions;              // number of library versions
   uint32 library_versions_addr;         // library versions address
   uint32 kernel_library_version_addr;   // kernel library version address
   uint32 xapi_library_version_addr;     // xapi library version address
   uint32 logo_bitmap_addr;              // logo bitmap address
   uint32 logo_bitmap_size;              // logo bitmap size
 } Header;

 struct certificate
 {
   uint32 size;                          // size of certificate
   uint32 timedate;                      // timedate stamp
   uint32 titleid;                       // title id
   uint16 title_name[40];                // title name (unicode)
   uint32 alt_title_id[0x10];            // alternate title ids
   uint32 allowed_media;                 // allowed media types
   uint32 game_region;                   // game region
   uint32 game_ratings;                  // game ratings
   uint32 disk_number;                   // disk number
   uint32 version;                       // version
   uint08 lan_key[16];                   // lan key
   uint08 sig_key[16];                   // signature key
   uint08 title_alt_sig_key[16][16];     // alternate signature keys
 } Certificate;

 struct section_header
 {
   struct flags                            // flags
   {
     uint writable             : 1;    // writable flag
     uint preload              : 1;    // preload flag
     uint executable           : 1;    // executable flag
     uint inserted_file        : 1;    // inserted file flag
     uint head_page_ro         : 1;    // head page read only flag
     uint tail_page_ro         : 1;    // tail page read only flag
     uint unused_a1            : 1;    // unused (or unknown)
     uint unused_a2            : 1;    // unused (or unknown)
     uint unused_b1            : 8;    // unused (or unknown)
     uint unused_b2            : 8;    // unused (or unknown)
     uint unused_b3            : 8;    // unused (or unknown)
   } Flags;

   uint32  virtual_addr;                  // virtual address
   uint32  virtual_size;                  // virtual size
   uint32  raw_addr;                      // file offset to raw data
   uint32  sizeof_raw;                    // size of raw data
   uint32  section_name_addr;             // section name addr
   uint32  section_reference_count;       // section reference count
   uint16 *head_shared_ref_count_addr;    // head shared page reference count address
   uint16 *tail_shared_ref_count_addr;    // tail shared page reference count address
   uint08  section_digest[20];            // section digest
 } * pSection_Header;

 struct library_version
 {
   char   name[8];                       // library name
   uint16 major_version;                 // major version
   uint16 minor_version;                 // minor version
   uint16 build_version;                 // build version

   struct flags                            // flags
   {
     uint16 qfe_version        : 13;   // QFE Version
     uint16 approved           : 2;    // Approved? (0:no, 1:possibly, 2:yes)
     uint16 debug_build        : 1;    // Is this a debug build?
   } Flags;
 } * Library_Version, * Kernel_Version, * XAPI_Version;

 struct tls                                  // thread local storage
 {
   uint32 data_start_addr;               // raw start address
   uint32 data_end_addr;                 // raw end address
   uint32 tls_index_addr;                // tls index  address
   uint32 tls_callback_addr;             // tls callback address
   uint32 sizeof_zero_fill;              // size of zero fill
   uint32 characteristics;               // characteristics
 } * TLS;
#pragma pack( pop, before_header )
} XBE_INFO, * PXBE_INFO, ** PPXBE_INFO;


You need to read this header from the beginning of the xbe file to so that you
know where to start looking for stuff since this header contains all the necessary
information for where to start looking for stuff.

The following example shows how to e.g. get information about the certificate of the xbe:

CODE

  XBE_INFO   m_XBEInfo;

  int        m_iHeaderSize;
  char     * m_pHeader;

  .
  .
  .

  // Assume 256K is enough for header information
  m_iHeaderSize = ( 256 * 1024 );
  m_pHeader = ( char * )NULL;

  .
  .
  .

  // Do we have a header memory area?
  if ( m_pHeader == ( char * )NULL )
     {
     // No header area. Allocate memory for header
     if ( ( m_pHeader = ( char * )malloc( m_iHeaderSize ) ) == ( char * )NULL )
        {
        // Unable to allocate memory. Return not OK
        return ( int )RET_ERR;
        }
     }

  .
  .
  .

  HANDLE hFile;

  // Open the local file
  hFile = CreateFile( szFileName,
                      GENERIC_READ,
                      0,
                      NULL,
                      OPEN_EXISTING,
                      FILE_ATTRIBUTE_NORMAL,
                      NULL );


  // Did we manage to open the file?
  if ( hFile == ( HANDLE )INVALID_HANDLE_VALUE )
     {
     // Unable to open file. Return not OK
     return ( int )RET_ERR;
     }

  // Read the header
  if ( ::ReadFile( hFile,
                   m_pHeader,
                   min( m_iHeaderSize,
                        ( int )GetFileSize( hFile, ( LPDWORD )NULL ) ),
                        &dwRead,
                        NULL ) == ( BOOL )TRUE )
     {
     // Header read. Copy information about header
     memcpy( &m_XBEInfo.Header, m_pHeader, sizeof( m_XBEInfo.Header ) );
     }


  // Header read. Copy information about certificate
  memcpy( &m_XBEInfo.Certificate, ( m_pHeader + m_XBEInfo.Header.sizeof_image_header ), sizeof( m_XBEInfo.Certificate ) );

  // Title id. (remember to convert it to a hex value before using it as a part of any file names)
  // m_XBEInfo.Certificate.titleid;

  // Media flag
  // m_XBEInfo.Certificate.allowed_media;

  // Game region code
  // m_XBEInfo.Certificate.game_region;


The next section shows how to identify certain sections of the xbe file,
since the images that we're looking are placed in sections with certain names.

CODE

  // XPR stuff
  #ifndef XBR_HEADER
  typedef struct _XPR_File_Header_
  {
     union _ImageType_
        {
        DWORD     dwXPRMagic;
        WORD      wBitmapMagic;
        } Type;

     DWORD       dwTotalSize;
     DWORD       dwHeaderSize;

     DWORD       dwTextureCommon;
     DWORD       dwTextureData;
     DWORD       dwTextureLock;
     BYTE        btTextureMisc1;
     BYTE        btTextureFormat;
     BYTE        btTextureLevel  : 4;
     BYTE        btTextureWidth  : 4;
     BYTE        btTextureHeight : 4;
     BYTE        btTextureMisc2  : 4;
     DWORD       dwTextureSize;

     DWORD       dwEndOfHeader; // 0xFFFFFFFF
  } XPR_FILE_HEADER, * PXPR_FILE_HEADER, ** PPXPR_FILE_HEADER;
  #endif

  int    m_iImageSize;
  char * m_pImage;

  int    iNumSections;
  char * pszSectionName;

  // Assume 256K is enough for image information
  m_iImageSize = ( 256 * 1024 );
  m_pImage = ( char * )NULL;

  .
  .
  .

  // Initialize
  iNumSections = m_XBEInfo.Header.sections;

  // Position at the first section
  m_XBEInfo.pSection_Header = ( _xbe_info_::section_header * )( m_pHeader + ( m_XBEInfo.Header.section_headers_addr -
                                                                              m_XBEInfo.Header.base ) );

  // Sections read. Parse all the section headers
  while ( iNumSections-- > ( int )0 )
     {
     // Is this section an inserted file?
     if ( ( int )m_XBEInfo.pSection_Header->Flags.inserted_file == ( int )1 )
        {
        // Inserted file. Position at the name of the section
        pszSectionName = ( m_pHeader + ( m_XBEInfo.pSection_Header->section_name_addr -
                                         m_XBEInfo.Header.base ) );

        // Title image?
        if ( strcmp( pszSectionName, "$$XTIMAGE" ) == ( int )0 )
           {
           // Do we have an image memory area?
           if ( m_pImage == ( char * )NULL )
              {
              // No image area. Allocate memory for image
              if ( ( m_pImage = ( char * )malloc( m_iImageSize ) ) == ( char * )NULL )
                 {
                 // Unable to allocate memory. Break out of loop
                 break;
                 }
              }

              // Position at 'title image' in the XBE itself
              if ( SetFilePointer( hFile,
                                   m_XBEInfo.pSection_Header->raw_addr,
                                   NULL,
                                   FILE_BEGIN ) == ( DWORD )0xFFFFFFFF )
                 {
                 // Unable to set file position. Break out of loop
                 break;
                 }

              // Read the image
              if ( ::ReadFile( hFile,
                               m_pImage,
                               min( m_iImageSize,
                                    ( int )m_XBEInfo.pSection_Header->sizeof_raw ),
                                    &dwRead,
                                    NULL ) == ( BOOL )FALSE )
                 {
                 // Image not read. Break out of loop
                 break;
                 }

              // The m_pImage variable now contains the image data itself
              // Most of the times this is an image described as an XPR0 image
              // TODO - Insert NinjaImageCodeHere( )

              // Break out of loop
              break;
              }
           }

        // Position at the next section
        m_XBEInfo.pSection_Header++;
        }
     }


As you can see the section to look for when you want to find the
icon that is being used as the application icon, you'll have to look for a section
named $$XTIMAGE. If you want to look for the save game image (not always present),
then you need to look for the section named $$XSIMAGE.

The above example shows you how to find the section containing the title image, the
actual image extraction is left out so that you can do this exercise for your self.
Tip: the image is an XPR0 described image - but not always though.

Happy hunting

beerchug.gif
User is offlineProfile CardPM
Go to the top of the page
+Quote Post

Posts in this topic






Closed TopicStart new topic

 

Lo-Fi Version Time is now: 19th May 2013 - 06:17 PM