initial commit
This commit is contained in:
commit
840fb76d79
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
*
|
||||||
|
!*.c
|
||||||
|
!*.py
|
||||||
|
!Makefile
|
||||||
|
!README.md
|
||||||
|
!LICENSE
|
||||||
|
!.gitignore
|
7
Makefile
Normal file
7
Makefile
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
GCCOPT=-O0 -Wall -pedantic
|
||||||
|
GCC=gcc
|
||||||
|
|
||||||
|
all: hwid_dec
|
||||||
|
|
||||||
|
hwid_dec: hwid_dec.c
|
||||||
|
$(GCC) $(GCCOPT) $< -o $@
|
35
README.md
Normal file
35
README.md
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# HWID Stuff
|
||||||
|
|
||||||
|
Here are some basic example utilities for GenuineAuthorization tickets and HWID block blobs.
|
||||||
|
|
||||||
|
If you'd like to learn more about the things those scripts work with, go to [massgravel/activation](https://github.com/massgravel/activation).
|
||||||
|
|
||||||
|
# Info
|
||||||
|
|
||||||
|
## `hwid_extract.py`
|
||||||
|
|
||||||
|
This scripts extracts the HWID block blob from a GenuineAuthorization ticket into a file:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Writes to file
|
||||||
|
python hwid_extract.py GenuineTicket.xml hwid.bin
|
||||||
|
|
||||||
|
# Writes to stdout
|
||||||
|
python hwid_extract.py GenuineTicket.xml
|
||||||
|
```
|
||||||
|
|
||||||
|
## `hwid_dec.c`
|
||||||
|
|
||||||
|
This is a program that prints out all the individual fields in the HWID block blob. Build with `make`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
hwid_dec hwid.bin
|
||||||
|
```
|
||||||
|
|
||||||
|
## `ticket_decode.py`
|
||||||
|
|
||||||
|
This is a script that prints out meaningful individual fields in a ticket.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
python ticket_decode.py GenuineTicket.xml
|
||||||
|
```
|
108
hwid_dec.c
Normal file
108
hwid_dec.c
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
struct __attribute__((packed)) HWID {
|
||||||
|
uint16_t size;
|
||||||
|
uint16_t version;
|
||||||
|
uint16_t instances[9];
|
||||||
|
uint16_t dock_or_PCMCIA;
|
||||||
|
uint16_t hashRAM;
|
||||||
|
uint16_t hashBIOS;
|
||||||
|
uint16_t instanceHashes[];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __attribute__((packed)) TIMEWEIGHT {
|
||||||
|
uint8_t num_weights;
|
||||||
|
struct __attribute__((packed)) Weight {
|
||||||
|
uint8_t type;
|
||||||
|
uint16_t weight;
|
||||||
|
} weight[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *CLASS_NAMES[] = {
|
||||||
|
"CDROM",
|
||||||
|
"Hard Disk Controllers",
|
||||||
|
"Hard Disk Drives",
|
||||||
|
"Displays",
|
||||||
|
"SCSI Adapters",
|
||||||
|
"PCMCIA",
|
||||||
|
"Audio Adapters",
|
||||||
|
"Dock",
|
||||||
|
"Network Interface Cards",
|
||||||
|
"CPUs",
|
||||||
|
"Memory",
|
||||||
|
"UNUSED",
|
||||||
|
"BIOS",
|
||||||
|
"UNUSED",
|
||||||
|
"Mobile Broadband",
|
||||||
|
"Bluetooth Interfaces"
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *HWID_NAMES[] = {
|
||||||
|
"CDROM / Mobile Broadband",
|
||||||
|
"Hard Disk Controllers",
|
||||||
|
"Hard Disk Drives",
|
||||||
|
"Displays",
|
||||||
|
"SCSI Adapters / Bluetooth Controllers",
|
||||||
|
"Audio Adapters",
|
||||||
|
"Unused",
|
||||||
|
"Network Interface Cards",
|
||||||
|
"CPUs"
|
||||||
|
};
|
||||||
|
|
||||||
|
void print_block(uint8_t *hw_block) {
|
||||||
|
uint32_t size = *(uint32_t *)hw_block;
|
||||||
|
uint16_t unknown = *(uint16_t *)(hw_block + 4);
|
||||||
|
unsigned instance_count = 0;
|
||||||
|
|
||||||
|
puts("Block Information:");
|
||||||
|
printf("Size : [%08x]\n", size);
|
||||||
|
printf("Unknown : [%08x]\n", unknown);
|
||||||
|
puts("");
|
||||||
|
|
||||||
|
struct HWID *hwid = (struct HWID *)(hw_block + 6);
|
||||||
|
puts("HWID Information:");
|
||||||
|
printf("Size : [%04x]\n", hwid->size);
|
||||||
|
printf("Version : [%04x]\n", hwid->version);
|
||||||
|
for(size_t i = 0; i < 9; i++) {
|
||||||
|
instance_count += hwid->instances[i];
|
||||||
|
printf("Inst. (%02zx) : [%04x] -> %s\n", i, hwid->instances[i], HWID_NAMES[i]);
|
||||||
|
}
|
||||||
|
printf("Dock/PCMCIA : [%04x]\n", hwid->dock_or_PCMCIA);
|
||||||
|
printf("RAM hash : [%02x]\n", hwid->hashRAM);
|
||||||
|
printf("SMBIOS hash : [%04x]\n", hwid->hashBIOS);
|
||||||
|
for(size_t i = 0; i < instance_count; i++) {
|
||||||
|
printf("Hash (%02zx) : [%04x] %s\n", i, hwid->instanceHashes[i], (hwid->instanceHashes[i] & 1) == 1 ? "[[Non-Removable]]" : "");
|
||||||
|
}
|
||||||
|
puts("");
|
||||||
|
|
||||||
|
struct TIMEWEIGHT *tw = (struct TIMEWEIGHT *) ((hw_block + 6) + hwid->size);
|
||||||
|
puts("Timeweight Information:");
|
||||||
|
printf("Weights : [%02x]\n", tw->num_weights);
|
||||||
|
|
||||||
|
for(size_t i = 0; i < tw->num_weights; i++) {
|
||||||
|
printf("Weight (%02x) : [%04x] -> %s\n", tw->weight[i].type, tw->weight[i].weight, CLASS_NAMES[tw->weight[i].type]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
if(argc != 2) {
|
||||||
|
puts("Invalid parameters.\nUsages:\n\thwid file");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fd = fopen(argv[1], "r");
|
||||||
|
fseek(fd, 0, SEEK_END);
|
||||||
|
long fsize = ftell(fd);
|
||||||
|
rewind(fd);
|
||||||
|
|
||||||
|
uint8_t *hw_block = malloc(fsize);
|
||||||
|
fread(hw_block, 1, fsize, fd);
|
||||||
|
|
||||||
|
print_block(hw_block);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
50
hwid_extract.py
Executable file
50
hwid_extract.py
Executable file
@ -0,0 +1,50 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
from functools import reduce
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
from base64 import b64decode
|
||||||
|
|
||||||
|
class Ticket:
|
||||||
|
@staticmethod
|
||||||
|
def get_properties(genAuth: ET.Element) -> str:
|
||||||
|
properties = genAuth.find('./{*}genuineProperties/{*}properties')
|
||||||
|
return properties.text
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def split_keyval(x: str) -> dict:
|
||||||
|
parameters = {}
|
||||||
|
|
||||||
|
for params in x.split(';'):
|
||||||
|
if not params or params == '\x00':
|
||||||
|
break
|
||||||
|
key_val = params.split('=')
|
||||||
|
parameters[key_val[0]] = key_val[1]
|
||||||
|
return parameters
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_hwid(genAuth: ET.Element) -> str:
|
||||||
|
props = Ticket.split_keyval(Ticket.get_properties(genAuth))
|
||||||
|
params = Ticket.split_keyval(b64decode(props['SessionId'] + '===').decode('utf-16'))
|
||||||
|
|
||||||
|
return params['Hwid']
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
main_parser = argparse.ArgumentParser(
|
||||||
|
'hwid_extract',
|
||||||
|
description='Extract the binary hardware id from ticket'
|
||||||
|
)
|
||||||
|
main_parser.add_argument('input', type=argparse.FileType('rb'))
|
||||||
|
main_parser.add_argument('output', type=argparse.FileType('wb'), nargs='?')
|
||||||
|
args = main_parser.parse_args()
|
||||||
|
|
||||||
|
ticket = ET.parse(args.input).getroot()
|
||||||
|
hwid = Ticket.get_hwid(ticket)
|
||||||
|
|
||||||
|
hwid_block = b64decode(hwid + '===')
|
||||||
|
if args.output is None:
|
||||||
|
print(hwid_block)
|
||||||
|
else:
|
||||||
|
args.output.write(hwid_block)
|
57
ticket_decode.py
Executable file
57
ticket_decode.py
Executable file
@ -0,0 +1,57 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
from functools import reduce
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
from base64 import b64decode
|
||||||
|
|
||||||
|
# Microsoft really hates padding base64
|
||||||
|
# appending "===" is just so that b64decode
|
||||||
|
# doesn't complain about it.
|
||||||
|
# It's neither valid padding nor magic.
|
||||||
|
|
||||||
|
class Ticket:
|
||||||
|
@staticmethod
|
||||||
|
def get_properties(genAuth: ET.Element) -> str:
|
||||||
|
properties = genAuth.find('./{*}genuineProperties/{*}properties')
|
||||||
|
return properties.text
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def split_keyval(x: str) -> dict:
|
||||||
|
parameters = {}
|
||||||
|
|
||||||
|
for params in x.split(';'):
|
||||||
|
if not params or params == '\x00':
|
||||||
|
break
|
||||||
|
key_val = params.split('=')
|
||||||
|
parameters[key_val[0]] = key_val[1]
|
||||||
|
return parameters
|
||||||
|
|
||||||
|
def __init__(self, genuine_authorization: ET.Element):
|
||||||
|
self.gen_auth = genuine_authorization
|
||||||
|
self.gen_props = genuine_authorization.find('./{*}genuineProperties')
|
||||||
|
|
||||||
|
props = self.gen_props.find('./{*}properties').text
|
||||||
|
self.props = self.split_keyval(props)
|
||||||
|
self.props['SessionId'] = self.split_keyval(b64decode(self.props['SessionId'] + '===').decode('utf-16'))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
main_parser = argparse.ArgumentParser(
|
||||||
|
'ticket_decode',
|
||||||
|
description='Print out contents of a GenuineAuthorization ticket'
|
||||||
|
)
|
||||||
|
main_parser.add_argument('input', type=argparse.FileType('r'))
|
||||||
|
args = main_parser.parse_args()
|
||||||
|
|
||||||
|
ticket = Ticket(ET.parse(args.input).getroot())
|
||||||
|
|
||||||
|
# Print out stuff
|
||||||
|
|
||||||
|
for prop in ticket.props:
|
||||||
|
if prop == 'SessionId':
|
||||||
|
for sess_prop in ticket.props['SessionId']:
|
||||||
|
print(sess_prop, ticket.props['SessionId'][sess_prop], sep=': ')
|
||||||
|
continue
|
||||||
|
print(prop, ticket.props[prop], sep=': ')
|
Loading…
Reference in New Issue
Block a user