Last active
February 14, 2022 23:49
-
-
Save GXTX/0ba2d5a69afde3a859e45f2252e78f01 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"encoding/binary" | |
"fmt" | |
"os" | |
"strings" | |
"time" | |
"unsafe" | |
) | |
const MAGIC_OFFSET = 0x600; | |
const NETWORK_SETTINGS_OFFSET = 0x1000; | |
const MACHINE_OFFSET = 0x1200; | |
type MainConfig struct { | |
Magic [4]byte | |
NumberOfBoots uint32 | |
FormatDate [8]byte | |
} | |
type XLiveAccount struct { | |
XUID [0x10]byte | |
UNK1 uint64 | |
Gamertag [0x10]byte | |
Flags uint32 | |
Passcode [0x4]byte | |
Domain [0x14]byte | |
Realm [0x18]byte | |
Confounder [0x14]byte | |
Verification [0x10]byte | |
} | |
type NetworkSettings struct { | |
SectionBeginSignature [0x04]byte // Present at the start of new sections in the config sectors | |
UNK1 [0x04]byte // Always 1? | |
UNK2 [0x04]byte // Always 1? | |
UNK3 [0x40]byte | |
Flags [0x02]byte // Maybe only takes 1 byte? How are setting derived from it? | |
MACAddress [0x06]byte | |
Static IPv4AddressBlock | |
PrimaryDNS IPv4 | |
SecondaryDNS IPv4 | |
HostName [0x28]byte | |
PPPOEUserName [0x40]byte | |
PPPOEPassword [0x40]byte | |
UNK4 [0x28]byte | |
PPPOEServiceName [0x28]byte | |
UNK5 [0x94]byte // Padding? Might contain DHCP IP, server, DNS? | |
NetworkEndSignature [0x04]byte // Always contains "XBCP" | |
UNK6 [0x04]byte | |
SecionEndSignature [0x02]byte // Always 0x55 0xAA | |
} | |
type IPv4 [4]byte | |
type IPv4AddressBlock struct { | |
Address IPv4 | |
Subnet IPv4 | |
Gateway IPv4 | |
PrimaryDNS IPv4 | |
SecondaryDNS IPv4 | |
} | |
type Filetime struct { | |
LowDateTime uint32 | |
HighDateTime uint32 | |
} | |
func main() { | |
file, err := os.OpenFile("/home/dev/Desktop/Files/disk.bin", os.O_RDONLY, 0666) | |
if err != nil { | |
panic(err) | |
} | |
readHeader(file) | |
readAccounts(file) | |
readNetworkSettings(file) | |
} | |
func readHeader(f *os.File) MainConfig { | |
var config MainConfig | |
buf := make([]byte, unsafe.Sizeof(config)) | |
l, err := f.ReadAt(buf, MAGIC_OFFSET) | |
if err != nil || l != len(buf) { | |
panic(err) | |
} | |
r := bytes.NewReader(buf) | |
err = binary.Read(r, binary.LittleEndian, &config) | |
if err != nil { | |
panic(err) | |
} | |
if string(config.Magic[:]) != "BRFR" { | |
panic("Missing magic bytes!") | |
} | |
fmt.Printf("Magic: %v, NumberOfBoots: %v, HDDFormatDate: %v\n", | |
string(config.Magic[:]), | |
config.NumberOfBoots, | |
time.Unix(0, filetimeToNano(config.FormatDate)).UTC()) | |
return config | |
} | |
func readAccounts(f *os.File) []XLiveAccount { | |
var accountsBuffer XLiveAccount | |
var LiveAccounts []XLiveAccount | |
buf := make([]byte, unsafe.Sizeof(accountsBuffer)) | |
offset := MACHINE_OFFSET | |
for i := 0; i <= 8; i++ { | |
if i == 1 { | |
offset += 0x600 | |
} else if i != 0 { | |
offset += 0x200 | |
} | |
_, err := f.ReadAt(buf, int64(offset)) | |
if err != nil { | |
panic(err) | |
} | |
r := bytes.NewReader(buf) | |
err = binary.Read(r, binary.LittleEndian, &accountsBuffer) | |
if err != nil { | |
panic(err) | |
} | |
if strings.Count(string(accountsBuffer.Gamertag[:]), string(0x0)) != 16 { | |
LiveAccounts = append(LiveAccounts, accountsBuffer) | |
fmt.Printf("Account Name: %v, Domain: %v, Realm: %v, XUID: %x\n", | |
string(accountsBuffer.Gamertag[:]), | |
string(accountsBuffer.Domain[:]), | |
string(accountsBuffer.Realm[:]), | |
accountsBuffer.XUID) | |
} | |
} | |
return LiveAccounts | |
} | |
func readNetworkSettings (f *os.File) NetworkSettings { | |
var networksettings NetworkSettings | |
buf := make([]byte, unsafe.Sizeof(networksettings)) | |
l, err := f.ReadAt(buf, NETWORK_SETTINGS_OFFSET) | |
if err != nil || l != len(buf) { | |
panic(err) | |
} | |
r := bytes.NewReader(buf) | |
err = binary.Read(r, binary.LittleEndian, &networksettings) | |
if err != nil { | |
panic(err) | |
} | |
return networksettings | |
} | |
// Helper | |
func filetimeToNano(t [8]byte) int64 { | |
ft := Filetime{ | |
LowDateTime: binary.LittleEndian.Uint32(t[:4]), | |
HighDateTime: binary.LittleEndian.Uint32(t[4:]), | |
} | |
nsec := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) | |
nsec -= 116444736000000000 | |
nsec *= 100 | |
return nsec | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment