Keep in mind that XQEMU is LLE and we can't always assume that it's running the official MS bios / kernel / licensed games. Anything which makes such assumptions is part of HLE.
HLE in XQEMU and its UI should always be entirely optional and it must be possible to disable such features (or they must handle non-MS code gracefully).
Following is some code which could be used to get information about the running XBE.
For more information, check http://xboxdevwiki.net/Xbe which also has a link to the file format at the bottom.
- Doesn't handle bad XBEs gracefully and does no bounds checking.
- Retrieves the information in multiple steps which might be problematic if the XBE is changed during readback.
- Timestamp conversion could be broken.
- Unicode conversion could be broken.
- Not known wether it runs synchronously or asynchronously.
- Written for Python 3, whereas XQEMU-Manager also supports Python 2.
Function to do HMP commands via QMP:
def read(self, addr, size):
cmd = {
"execute": "human-monitor-command",
"arguments": { "command-line": "x /%dxb %d" % (size,addr) }
}
response = self.run_cmd(cmd)
lines = response['return'].replace('\r', '').split('\n')
data_string = ' '.join(l.partition(': ')[2] for l in lines).strip()
data = bytes(int(b, 16) for b in data_string.split(' '))
return data
Code to read, parse and print XBE fields:
base = 0x00010000
if t.read(base, 4) == b'XBEH':
xbe_timestamp = int.from_bytes(t.read(base + 0x114, 4), 'little')
ts = datetime.datetime.utcfromtimestamp(xbe_timestamp)
print("XBE Timestamp: %s (0x%08X)" % (str(ts), xbe_timestamp))
cert_address = int.from_bytes(t.read(base + 0x118, 4), 'little')
cert_timestamp = int.from_bytes(t.read(cert_address + 0x4, 4), 'little')
ts = datetime.datetime.utcfromtimestamp(cert_timestamp)
print("XBE Certificate Timestamp: %s (0x%08X)" % (str(ts), cert_timestamp))
title_id = int.from_bytes(t.read(cert_address + 0x8, 4), 'little')
a = title_id >> 24
b = (title_id >> 16) & 0xFF
i = title_id & 0xFFFF
print('XBE Title-ID: 0x%X (%c%c-%03d)' % (title_id, a, b, i))
title_name = t.read(cert_address + 0xC, 40 * 2).decode('utf-8')
print("XBE Title-Name: '%s'" % title_name)
else:
print("No XBE found")
Output:
XBE Timestamp: 2001-12-12 19:15:05 (0x3C17ACB9)
XBE Certificate Timestamp: 2002-03-04 15:58:09 (0x3C839991)
XBE Title-ID: 0x4D530007 (MS-007)
XBE Title-Name: 'Azurik - Rise of Perathia'
The primary use of this information would probably be that it could be displayed as part of the UI (possibly move it into the QEMU window title). This would be immediately visible for use in bug reports.
If we allow some kind of telemetry or motivate users to report often, we can also use this information to create a complete set of XBE header dumps / complete gameset, possibly discovering undumped DVDs.
A sneaky way to get telemetry could be rich presence (which I don't want for XQEMU) or pairing players for network games in the future (which I want, regardless of telemetry).
The memory-read gadget can also retrieve kernel information for bug reports.
Otherwise, it's quite limited in use, because the UI can get information directly through our hardware-emulation.
Reminder: Xbox RAM contains copyrighted or otherwise protected material during runtime. So I'd advise against doing full crashdumps.
We should selectively dump the metadata we need, much like the code above does.