XRPC & ucode finder/extractor

Started by Hoernchen, 03. Nov 2008, 18:17

previous topic - next topic
Go Down

Hoernchen

03. Nov 2008, 18:17 Last Edit: 14. May 2009, 22:57 by mce2222
xrpc finder:
Code: [Select]

// xrpcfinder.cpp : Defines the entry point for the console application.
//

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
//#include <tchar.h>
#include <string.h>
#include <malloc.h>

#define XRPC_HIDESIZE (256*1024)
#define XRPC_MAXSIZE (10*1024*1024)

#define XRPC_CALLERID_IGNORED 0
#define XRPC_CALLERID_SIGMA_SER 0xffffffff

#define XRPC_ID_GETSERIAL      0 // return chip serial number to param0..3
//whats 1 ? -> dvi.bin
#define XRPC_ID_GETRANDOM      2 // return 32bit of true random to param0
#define XRPC_ID_BONDINGCOMMENT 3 // return the bonding comment to param0..1
#define XRPC_ID_SHA1XOS        4 // outputs SHA-1 of burnt signablearea-xosMxy.bin to param0..4
#define XRPC_ID_XLOAD          5
#define XRPC_ID_XOSSELFUPDATE  9
#define XRPC_ID_IH_LOAD       13 //interrupthandler
#define XRPC_ID_DRAM          15 /* --- deprecated in xosMa0 */
#define XRPC_ID_XUNLOAD       17
#define XRPC_ID_CACHEDUMP     18 // not implemented in release build
#define XRPC_ID_REBOOT        19
#define XRPC_ID_XBIND         20 // bind/unbind certificate to xload.
#define XRPC_ID_XSTART        21 // start xtask
#define XRPC_ID_XKILL         22 // signal or stop xtask
#define XRPC_ID_GETPROTECTION 23 // Get protection registers
#define XRPC_ID_GETBINDING    24 // Get binding hash
#define XRPC_ID_GETOWNER      25 // Get sector ownership hash
#define XRPC_ID_SETENHANCEDMODE 26 // enhanced mode
#define XRPC_ID_VERSION       27 // Get XOS build version string (!= sha1)

#define XLOAD_CERTTYPE_CPU 0x1
#define XLOAD_CERTTYPE_XTASK1 0x2
#define XLOAD_CERTTYPE_UCODE_VIDEO 0x3
#define XLOAD_CERTTYPE_UCODE_AUDIO 0x4
#define XLOAD_CERTTYPE_UCODE_DEMUX 0x5
#define XLOAD_CERTTYPE_IH 0x6
#define XLOAD_CERTTYPE_XTASK2 0x7
#define XLOAD_CERTTYPE_XTASK3 0x8
#define XLOAD_CERTTYPE_XTASK4 0x9
#define XLOAD_CERTTYPE_XOSU 0xff


struct xrpc_block_header {
unsigned int callerid; // deprecated field, put XRPC_CALLERID_IGNORED
unsigned int xrpcid;
// parameters (input and output)
unsigned int param0;
unsigned int param1;
unsigned int param2;
unsigned int param3;
unsigned int param4;
unsigned int headerandblocksize;
//stuff
unsigned short certid;
unsigned char certtype;
unsigned char securityID;
unsigned char PayloadSignCert[0x100];
unsigned char SignedCertSig[0x100];
unsigned char PayloadSig[0x100];
//unsigned char RecordData[(headerandblocksize-32)-0x304];
};


int main(int argc, char* argv[])
{

//search for XRPC_CALLERID_IGNORED+XRPC_ID_XLOAD
const char header[] = "\x00\x00\x00\x00\x05\x00\x00\x00";//better : int32 anything, int32 0< XRPC_ID < 28 - > 0, fuck off, getserial..
unsigned int len=9;
unsigned long ulFileSize=0;


if(!argv[1])
return 0;
FILE* datei = fopen(argv[1], "rb");

if (!datei)return 0;

fseek(datei,0,SEEK_END);
ulFileSize=ftell(datei);
fseek(datei,0,SEEK_SET);

if (!ulFileSize)return 0;;
if (len>ulFileSize)return 0;;

char* lpBuffer=(char*)malloc(ulFileSize);
fread(lpBuffer,1,ulFileSize,datei);

if (!lpBuffer) return 0;;

//printf("file: %s\n", argv[1]);
unsigned long ulCurrentPosition=0;
char string[100];
unsigned int file_number = 0, strpos = 0, fnamepos =0;
while(*(argv[1]+strpos) != 0x0) {
if( *(argv[1]+strpos) == '\\')
fnamepos = strpos;
strpos++;
}
while (ulCurrentPosition<ulFileSize-(len-1))
{

if (!memcmp(lpBuffer+ulCurrentPosition,header,len-1))
//if ((*(unsigned int*)(lpBuffer+ulCurrentPosition) == 0L) && (*(unsigned int*)(lpBuffer+ulCurrentPosition+4) > 0) && (*(unsigned int*)(lpBuffer+ulCurrentPosition+4) < 28))
{
xrpc_block_header* hdr = (xrpc_block_header*)(lpBuffer+ulCurrentPosition);
//not too big, small, or at 0x104 (PE Header, )
if( ((ulCurrentPosition+hdr->headerandblocksize) > ulFileSize) //too big for file
|| (hdr->headerandblocksize == 0) // cant be size 0
|| (hdr->headerandblocksize > XRPC_MAXSIZE) //too big for xrpc
|| ((hdr->certtype > 0x9) && (hdr->certtype !=0xff)) // certid wrong (unknown?)
|| (hdr->certtype == 0x0)
|| (ulCurrentPosition<=0x104)) {// PE header
ulCurrentPosition++;
continue;
}
printf("file: %s pos: %#0.8x (%0.10u), size: %#0.8x (%0.10u), hdr: 0x%.8x certtype 0x%.2x\n",
argv[1], ulCurrentPosition, ulCurrentPosition,
hdr->headerandblocksize, hdr->headerandblocksize, hdr->xrpcid, hdr->certtype );
ulCurrentPosition += hdr->headerandblocksize-1;


sprintf( string, "%s_xrpc_%x_%d.bin", (argv[1]+fnamepos+1), hdr->certtype, file_number );
FILE* outfile = fopen( string, "wb" );
if(outfile)
fwrite(hdr, 1, hdr->headerandblocksize, outfile);
fclose(outfile);
file_number++;
//break;
}
ulCurrentPosition++;

}

fclose(datei);
free(lpBuffer);
return 0;
}


usage:
xrpcfinder.exe booter.dll to extract both irqhandler xrpcxloads
xrpcfinder.exe checkxos.dll to extract both xos update xrpcxloads
ucodefinder.exe iptplatform.dll to extract the audio, video and demux ucodes - this is not a generic scanner, it works only for iptvplatform.dll !


exe & source for both programs included.
bringer of linux, conqueror of hdmi, jack of all trades.

Herman

oooooh :D
Am i correct in thinking that these ucodes extracted from the windows setup are the same format to be used for linux booting ?
If so that only leaves dvbt tuner drivers required !

Hoernchen

Err, no. They are not in a loadable xrpc format. The ucodes are not the problem, the embedded mrua ucodes should work, too, but the irqhandler has to match the irqhandler api used by the software, so just loading the wince irqhandler under linux results in a mrua that has no idea how to talk to the chip :-\
bringer of linux, conqueror of hdmi, jack of all trades.

pcgeil

is there a possibility to reengineer the irqhandler api?
The irq_handler is encrypted, or?

Hoernchen

Yes it is, so to rerverse engineer it you would have to look at wince, guess what it does, and fix it in libprivate.a. Obvioulsy the "guessing" part is a problem.
But i have to admit that even after a year of looking at wince and mrua there is still a lot of unknown stuff out there, so there might be a simpler solution. Afaik the irqhandler gets loaded at a certain RAM address....
bringer of linux, conqueror of hdmi, jack of all trades.

Go Up