?? xrpcinfo.c
字號:
/* by petter wahlman, badeip@binary-art.net
* This code must be compiled with the MIRACL bignum library.
*/
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <getopt.h>
#include <libgen.h>
#include <sys/stat.h>
#include <miracl.h>
#ifndef SHA_DIGEST_LENGTH
#define SHA_DIGEST_LENGTH 20
#endif
#define PAYLOAD_SUFFIX "pld"
typedef unsigned char u8;
typedef char s8;
typedef unsigned short u16;
typedef short s16;
typedef unsigned int u32;
typedef int s32;
static u32 opt_extract = 0;
const s8 *_xrpcid[] = {
"XRPC_ID_GETSERIAL", // 0 return chip serial number to param0..3
NULL, // 1
"XRPC_ID_GETRANDOM", // 2 return 32bit of true random to param0
"XRPC_ID_BONDINGCOMMENT", // 3 return the bonding comment to param0..1
"XRPC_ID_SHA1XOS", // 4 outputs SHA-1 of burnt signablearea-xosMxy.bin to param0..4
"XRPC_ID_XLOAD", // 5
NULL, // 6
NULL, // 7
NULL, // 8
NULL, // 9
NULL, // 10
NULL, // 11
NULL, // 12
NULL, // 13
NULL, // 14
"XRPC_ID_XLOAD", // 15 deprecated in xosMa0
NULL, // 16
"XRPC_ID_XUNLOAD", // 17 not implemented in release build
"XRPC_ID_CACHEDUMP", // 18 bind/unbind certificate to xload.
"XRPC_ID_REBOOT", // 19 !!
"XRPC_ID_XBIND", // 20 signal or stop xtask
"XRPC_ID_XSTART", // 21 start xtask
"XRPC_ID_XKILL", // 22 stop an xtask
"XRPC_ID_GETPROTECTION", // 23 get protection registers
"XRPC_ID_GETBINDING", // 24 get binding hash
"XRPC_ID_GETOWNER", // 25 get sector ownership hash
"XRPC_ID_SETENHANCEDMODE", // 26 enhanced mode
"XRPC_ID_VERSION" // 27 get XOS build version string (!= sha1)
};
const s8 *_cert_type[] = {
"XLOAD_CERTTYPE_NULL", // 0
"XLOAD_CERTTYPE_CPU", // 1
"XLOAD_CERTTYPE_XTASK1", // 2
"XLOAD_CERTTYPE_UCODE_VIDEO", // 3
"XLOAD_CERTTYPE_UCODE_AUDIO", // 4
"XLOAD_CERTTYPE_UCODE_DEMUX", // 4
"XLOAD_CERTTYPE_IH", // 7
"XLOAD_CERTTYPE_XTASK2", // 7
"XLOAD_CERTTYPE_XTASK3", // 8
"XLOAD_CERTTYPE_XTASK4", // 9
"XLOAD_CERTTYPE_XOSU" // 0xff
};
struct xrpc_block_header {
u32 callerid;
u32 xrpcid;
u32 payload_size; // padded payload size
u32 param0;
u32 param1;
u32 param2;
u32 param3;
u32 xload_size; // xload payload + header (should be equal to file size?)
struct {
u16 id;
u8 type;
u8 sekid;
};
u8 payload_cert[256]; //
u8 sigma_sign_cert[256]; //
u8 signed_payload[256]; //
u8 payload[0];
} __attribute__((packed));
static void sha1(u8 *ptr, u8 *h, u32 len)
{
u32 i;
sha sh;
shs_init(&sh);
for (i = 0; i < len; i++)
shs_process(&sh, ptr[i]);
shs_hash(&sh, (s8 *)h);
}
static void print_hex(void *data, u32 len)
{
u8 *ptr = (u8 *)data;
u32 i;
printf(" ");
for (i = 0; i < len; i++) {
if (i && (!(i % 32)))
printf("\n ");
printf("%02x ", ptr[i]);
}
}
static void rev_array(u8 *s, u32 l)
{
u32 i;
u8 c;
for (i = 0; i < l/2; i++) {
c = s[l-1-i];
s[l-1-i] = s[i];
s[i] = c;
}
}
static u32 extract_payload(s8 *source, s8 *buf, u32 len)
{
s8 *dest;
s32 fd, nw;
u32 rc = 1;
dest = malloc(strlen(source)+20);
sprintf(dest, "%s.%s", source, PAYLOAD_SUFFIX);
fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, 0644);
if (-1 != fd) {
nw = write(fd, buf, len);
if (nw == len)
rc = 0;
close(fd);
}
free(dest);
if (rc) {
if (-1 == nw)
printf("\n\nerror, extract_payload: %s\n", strerror(errno));
else
printf("\n\nerror, extract_payload: %d of %d bytes written\n", nw, len);
unlink(dest);
}
return rc;
}
int print_usage(void)
{
printf("by petter wahlman. badeip@binary-art.net\n"
"usage: xrpcinfo file [options]\n"
" -e extract payload\n"
"\n"
);
exit(1);
}
int main(int argc, char **argv)
{
s32 fd, i;
s8 *source;
s8 arr[256];
u8 shabuf[20];
struct stat st;
struct xrpc_block_header *xbh;
big m,c,d,e,n,t,hash;
u32 rc = 1;
if (argc < 2) {
fprintf(stderr, "usage: xrpcinfo <filename>\n");
return rc;
}
while (1) {
u32 c;
s32 option_index = 0;
static struct option long_options[] = {
{ "extract", 1, 0, 'e' },
{ NULL, 0, 0, 0 }
};
c = getopt_long(argc, argv, "e", long_options, &option_index);
if (-1 == c)
break;
switch (c) {
case 'e':
opt_extract = 1;
break;
case 'h':
default:
print_usage();
}
}
miracl *mip=mirsys(200, 0);
for (i = 1; i < argc; i++) {
source = argv[i];
memset(arr, 0, sizeof(arr));
memset(shabuf, 0, sizeof(shabuf));
fd = open(source, O_RDONLY);
if (-1 == fd) {
perror(source);
return rc;
}
fstat(fd, &st);
if (st.st_size < sizeof(*xbh)) {
fprintf(stderr, "\"%s\" is too small to contain the xbh header.\n", source);
close(fd);
return rc;
}
xbh = malloc(st.st_size);
read(fd, xbh, st.st_size);
printf("\nfile: \"%s\"\n", basename(source));
printf("0x000 xrpcid: 0x%08x (%s)\n", xbh->callerid, !xbh->callerid ? "XRPC_CALLERID_IGNORED" : "deprecated");
printf("0x004 xrpcid: 0x%08x (%s)\n", xbh->xrpcid, xbh->xrpcid < sizeof(_xrpcid)/sizeof(_xrpcid[0]) ? _xrpcid[xbh->xrpcid] : "NULL");
printf("0x008 payload_size: 0x%08x\n", xbh->payload_size);
printf("0x00c param0: 0x%08x (load address)\n", xbh->param0);
printf("0x010 param1: 0x%08x\n", xbh->param1);
printf("0x014 param2: 0x%08x\n", xbh->param2);
printf("0x018 param3: 0x%08x\n", xbh->param3);
printf("0x01c xload_size: 0x%08x\n", xbh->xload_size);
printf("\ncertificate info:\n");
printf(" ID: 0x%04x\n", xbh->id);
printf(" type: 0x%02x (%s)\n", xbh->type, xbh->type < 0xa ? _cert_type[xbh->type] : _cert_type[0xa]);
printf(" encryption: 0x%02x (%s)\n", xbh->sekid, xbh->sekid == 0xff ? "none" : "unknown");
printf("\n0x024 payload certificate:\n");
rev_array(xbh->payload_cert, sizeof(xbh->payload_cert));
print_hex(xbh->payload_cert, sizeof(xbh->payload_cert));
printf("\n\n0x124 sigma sign. of certificate:\n");
rev_array(xbh->sigma_sign_cert, sizeof(xbh->sigma_sign_cert));
print_hex(xbh->sigma_sign_cert, sizeof(xbh->sigma_sign_cert));
printf("\n\n0x224 signed payload:\n");
rev_array(xbh->signed_payload, sizeof(xbh->signed_payload));
print_hex(xbh->signed_payload, sizeof(xbh->signed_payload));
m = mirvar(0);
c = mirvar(0);
d = mirvar(0);
e = mirvar(0);
n = mirvar(0);
t = mirvar(0);
hash = mirvar(0);
mip->IOBASE=16;
cinstr(e, "10001");
bytes_to_big(sizeof(xbh->payload_cert), (s8 *)xbh->payload_cert, n);
bytes_to_big(sizeof(xbh->signed_payload), (s8 *)xbh->signed_payload, c);
powmod(c,e,n,m);
big_to_bytes(sizeof(arr), m, arr, 1);
printf("\n\ndecrypted RSA signature:\n");
print_hex(arr, sizeof(arr));
putchar('\n');
printf("\n%-23s", "padding: ");
if ((*(u16 *)arr == 0x0100) && (*(u16 *)&arr[sizeof(arr)-SHA_DIGEST_LENGTH-17] == 0x00ff)) {
printf("PKCS-1\n");
printf("%-20s", "ASN.1:");
print_hex(&arr[sizeof(arr)-SHA_DIGEST_LENGTH-15], 15);
} else if ((*(u16 *) &arr[sizeof(arr)-2] == 0xcc33) && (*(u16 *)arr == 0xbb6b))
printf("X9.31 (todo: adjust H(M) accordingly!)");
else
printf("unknown");
printf("\n%-20s", "decrypted SHA1:");
print_hex(&arr[sizeof(arr)-SHA_DIGEST_LENGTH], SHA_DIGEST_LENGTH);
sha1(xbh->payload, shabuf, st.st_size - sizeof(*xbh));
printf("\n%-20s", "calculated SHA1:");
print_hex(shabuf, SHA_DIGEST_LENGTH);
if (opt_extract) {
rc = extract_payload(source, (s8 *)xbh->payload, st.st_size - sizeof(*xbh));
if (!rc) {
printf("\n%-20s", "extracted payload:");
printf(" \"%s.%s\"\n\n", source, PAYLOAD_SUFFIX);
}
}
if (st.st_size != xbh->xload_size)
printf("\n\nerror, \"%s\" does not look like a valid xrpc file (0x%08lx != 0x%08x)\n", source, st.st_size, xbh->xload_size);
free(xbh);
close(fd);
}
putchar('\n');
return rc;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -