www.xbdev.net xbdev - software development
Friday December 14, 2018
home | about | contact | Donations

     
 

XBOX Programming

More than just a hobby...

 

Our own XBE

 

This is a fantastic thing you can do, when you can create your own xbe's.... well I think it is *big grin*.  It allows you to really see how your xbox works..  With a bit of creativity and of course assembly you can create some fantastic demo splash's....or even mini games... your only limited by your imagination.

 

Of course most of the stuff you can do here with the nasm assembler, you can do with the OpenXDK or MSXDK... but who needs them now....heheh

 

 

Obtaining NASM?

Well this tutorial, is based on the NASM assembler, which is open source, and can be downloaded from numerous sites.  The reason that I've chosen the nasm assembler instead of the MASM one is the simple fact, that its really really easy to use, and creating binary files for the 0x86 is as easy as one-two-three, which you'll soon see.

 

Why on earth NASM?.... how does it work?... well its a great program to learn with... and really easy to use... let me give you an example... create an empty file... just use notepad and save it as test.asm... then enter this line of code:

 

Assembly: test.asm
db 'XBEH'

resb 0x100

 

Now if you assemble it with nasm like this from the prompt "C:>nasm test.asm -o cool.bin" ..

You should end up with a file called cool.bin in the same folder as your asm file..  Opening this amazing new file in notepad, what do you see?  ... you see the this:

 

Output: cool.bin
XBEH0000000000000000000000000000000000......

 

Cool huh?... Well we can use nasm to create our header...and also mix in some assembly...as nasm is an assembler... it won't be drewling over just how cool this really is... creating code thats 100% yours....just think of the power!... *grin*

 

Sweet piece of code...

 

ARrggg.g..... look at all that assembly...holy cow.... yup...at first it looks like a lot... but its a working set of asm that you can rip to pieces and test over and over again.  Its the bare bones of an xbe - once you get the feel of how it works, you will probably do what I do, and put the header asm in a seperate file, then each time you want to start a new xbe... you can just include it at the top of you asm with %include "header.asm" .. then all that asm header stuff will just be added to the top of your file :)

 

Assembly: DownloadSource

[ORG 0x10000]

[BITS 32]

 

; assemble using 'nasm' assembler

; C:>nasm header.asm -o simple.xbe

 

; XBE HEADER PART ------------------------------------------------------------

 

db    'XBEH'

resb    0x100           ; reserve 100 bytes for the xbe security signature

                        ; This only matters on signed xbe's which are

                        ; ms authorised :)

 

dd    0x10000         ; Base address of image

dd    0x760           ; Size of header

dd    0x7000            ; Size of image

dd      0x178           ; Size of image header

dd    0x3f16d3ce  ; Time Date Stamp

 

dd    cert_header ; Certificate Address (plus offset)

 

 

dd    0x1         ; Number of sections

dd    section_header    ; Sectrion headers Address(plus offset)

 

dd    0x1         ; Initialisation Flags

dd    0x11100 ^ 0xA8FC57AB   

                        ; Entry point (XOR with 0xA8FC57AB)

                        ; ***** Very important - this will be our entry

                        ; point for our code - which is the base address of

                        ; our file added to the actual file offset.

 

dd    0x16000           ; Thread local storage directory address

dd    0x0         ; Size of stack commit

dd    0x0         ; Size of heap reserve

dd    0x0         ; Size of heap commit

 

 

dd    0x0         ; Original base address

dd    0x0         ; Original size of image

dd    0x0         ; Original checksum

dd    0x3f16d3ce  ; Original time date stamp

dd    debugpath   ; Debug path name address

dd    debugpath

dd    szname

 

dd    0x11000 ^ 0x5B6D40B6         

                        ; Kernel image thunk address

                        ; We XOR the original address with 0x5B6D40B6

dd    0x0         ; Non-kernel import directory address

dd    0x0         ; Number of library versions

dd    0x0         ; Library versions area addresses

dd    0x3         ; Kernel library version address

dd    0x0         ; XAPI library version address

dd    0           ; Logo bitmap address

dd    0             ; Logo bitmap size

                        ; Not included a logo bitmap for this simple example

                        ; and will still run without it, but you could encode

                        ; a really cool image logo for you app maybe :)

 

 

; Note: - a lot of assemblers use "[ORG 0x354]" to align data within the assembled

;         file, but for nasm, you have to use: TIMES 0x178-($-$$), which implies

;         that everything from this line is from 0x178 in the file.

 

 

; XBE CERTIFICATION ----------------------------------------------------------

 

TIMES 0x178-($-$$) DB 0 ; I've aligned the certificate to exactly 0x178 in

                        ; the file, but you could exclude this if you want.

 

cert_header:

 

dd    0x1dc       ; Size of Certification

dd    0x3f16d3ce  ; Date Stamp

dd    0x0         ; Title ID

resb    0x50            ; Title name null terminated string

resb  0x40        ; Alt Title

dd    0x0         ; Allowed Media

dd    0x0         ; Game Region

dd    0x0         ; Game Rating

dd    0x0         ; Disk Number

dd    0x0         ; version

resb    0x10            ; Lan

resb  0x10        ; Signature Key

resb  0x100       ; Alt Sig

 

 

; SECTION HEADERS ------------------------------------------------------------

TIMES 0x354-($-$$) DB 0 ; Similar to the xbe cert header, I've aligned the

                        ; single section header to offset 0x354 exactly, but

                        ; you don't have to.

 

section_header:

 

dd    0x07        ; Flags

dd    0x11000           ; Virtual Address (remember offset of 0x10000)

dd    0x6000            ; Virutal Size

dd    0x1000            ; File pointer to raw data

dd    0x6000            ; Size of raw data

dd    section_name      ; Address of the section name (Null terminated)

dd    0x0         ;

dd    rc1         ; head_count_address

dd    rc2         ; tail_count_address

 

 

debugpath:

      db 0x0,0x0,0x0,0x0,0x0,0,0,0,0,0,0,0,0,0,0

szname:

      dw 'x','b','d','e','v',0,0,0

 

rc1:

  dd 0

rc2:

  dd 0

 

section_name:

  db '.','t','e','x','t',0,0

 

 

; 'OUR CODE'

; THE SECTION WE DEFINED -----------------------------------------------------

 

; This is the start of our section.. the start of our simple

; code.

; Its offset in the file is at 0x1000

TIMES 0x1000-($-$$) DB 0

 

 

section_1_start:        ; this should be 0x11000 in memory when loaded

; kernel thunk table

MmAllocateContiguousMemoryEx:

      dd    0x80000000 + 166

MmGetPhysicalAddress:

      dd    0x80000000 + 173

NtAllocateVirtualMemory:

      dd    0x80000000 + 184

 

      dd    0           ; end of table

 

                 

 

; Entry point of our code - offset 0x1100 in the file.

TIMES 0x1100-($-$$) DB 0x90   ; this should be 0x11100 in memory when loaded

 

 

; Fantastic testing assembly function, which can be found on xbox-linux site

; also, its used here to make sure our xbe is loaded into memory okay, and is

; started :)  This would be the point where you code would go... the rest of

; its all over-head

 

flashingleds:

 

            mov dx, 0xc004

            mov al, 0x20

            out dx, al

           

            mov dx, 0xc008

            mov al, 8

            out dx, al

 

 

            mov dx, 0xc006

            ; c = 0x80 + 0x04 + 0x20 +  0x02= 0xA6

            mov al, 0xA6

            out dx, al

 

            mov dx, 0xc000

            in ax, dx

 

            out dx, al

            mov dx, 0xc002

            mov al, 0x1a

            out dx, al

 

            mov eax, 1000000

 

loopx:

            dec eax

            jne loopx

 

 

            mov dx, 0xc004

            mov al, 0x20

            out dx, al

     

           

            mov dx, 0xc008

            mov al, 7

            out dx, al

           

            mov dx, 0xc006

            mov al, 1

            out dx, al

           

            mov dx, 0xc000

            in ax, dx

            out dx, al

           

            mov dx, 0xc002

            mov al, 0x1a

            out dx, al

 

aa:

            jmp aa

 

 

TIMES 0x6000-($-$$) DB 0x90   ; this will make our section finish at 0x6000

                                ; from the start of the file.

 

TIMES 0x7000-($-$$) DB 0x0    ; And of course, this will make our file size

                                ; equal to 0x7000 a nice round number -

                                ; 0x7000 is 28672bytes... so if you assemble the file

                                ; you should find its that size exactly.

 

 

The only part of the code thats really of any interest is the "flashingleds:" section of code... which tests our simple xbe... So you assemble the file and get your "simple.xbe" and run it on your xbox... and what happens... the LED's on the front of your xbox flash!.. Whahoooooo

 

Well some people might not think thats cool...but I do.... its really a big step I think learning the xbe file format :)  Of course its a lot easier because of the great work from xbox-linux :)

 

Part -2- Soon... Eject..

 

 
 Visitor: 9534626  { 209.237.238.175 } Copyright (c) 2002-2017 xbdev.net - All rights reserved.
Designated tutorial and software are the property of their respective owners.