mirror of
https://github.com/rvtr/TwlIPL.git
synced 2025-10-31 06:01:12 -04:00
Delete tools/bin directory
This commit is contained in:
parent
09c7b12b4e
commit
371c997eec
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,260 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
######################################################################
|
||||
# genFontTable.pl
|
||||
#
|
||||
# generate Secure Shared Font Data Table
|
||||
#
|
||||
# [[ HEADER FORMAT ]]
|
||||
# security code (128 bytes) : RSA signature of Header
|
||||
#
|
||||
# Header ( 32 bytes)
|
||||
# TimeStamp ( 4 bytes) : date %y%m%d%H
|
||||
# number ( 2 bytes) : number of font files
|
||||
# region_code ( 1 bytes) : font region code
|
||||
# padding ( 6 bytes) :
|
||||
# padding ( 20 bytes) : SHA1 digest of Font info table
|
||||
#
|
||||
# Font info table ( 64 bytes * number)
|
||||
# fileName ( 32 bytes) : font file name
|
||||
# comp_length ( 4 bytes) : length of the compression file
|
||||
# file offset ( 4 bytes) : file offset of Font data
|
||||
# length ( 4 bytes) : length of file (bytes)
|
||||
# digest ( 20 bytes) : SHA1 digest of Font data
|
||||
#
|
||||
# note: each section image is aligned to 32 bytes.
|
||||
#
|
||||
######################################################################
|
||||
|
||||
use POSIX 'strftime';
|
||||
use File::Basename;
|
||||
|
||||
if ($#ARGV < 3) {
|
||||
printf STDOUT ("Usage: %s [genFontTable] timestamp region_code [Target font files...]\n", $0);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
my $outFile = "TWLFontTable.dat";
|
||||
my $infoFile = "info.bin";
|
||||
my $headerFile = "header.bin";
|
||||
my $digestFile = "sha1.bin";
|
||||
my $signFile = "sign.bin";
|
||||
my $tempFile = "temp.bin";
|
||||
my $compprog = "compBLZ.exe"; # 圧縮プログラム
|
||||
my $compoption = "-e \"\"";
|
||||
#my $compprog = "./ntrcomp/gcc/ntrcomp.exe";
|
||||
#my $compoption = "-h8 -A32 -s";
|
||||
|
||||
# 後始末
|
||||
sub deleteTemp {
|
||||
system ("rm -f $infoFile");
|
||||
system ("rm -f $headerFile");
|
||||
system ("rm -f $digestFile");
|
||||
system ("rm -f $signFile");
|
||||
system ("rm -f $tempFile");
|
||||
}
|
||||
|
||||
# 環境変数からSDKのルートをサーチして(ntrcompの場所特定に必要)
|
||||
foreach ( sort keys ( %ENV ) ){
|
||||
if ($_ =~ m/TWLSDK_ROOT/s) {
|
||||
$SDKROOT = $ENV{$_};
|
||||
}
|
||||
}
|
||||
printf "TWLSDK_ROOT is ${SDKROOT}\n";
|
||||
$compprog = "${SDKROOT}/tools/bin/" . $compprog;
|
||||
|
||||
my $signSize = 0x80;
|
||||
my $headerSize = 0x20;
|
||||
my @files;
|
||||
|
||||
# 要素数算出
|
||||
my $num = 0;
|
||||
foreach ( @ARGV ) {
|
||||
next if( $_ eq $ARGV[0] );
|
||||
next if( $_ eq $ARGV[1] );
|
||||
$files[ $num ] = $_;
|
||||
$num++;
|
||||
}
|
||||
|
||||
# 情報テーブルの出力
|
||||
{
|
||||
my $elementSize = 0x40;
|
||||
my $fileNameMax = 0x20;
|
||||
my $padLen = 0x04;
|
||||
# offset length = 0x04;
|
||||
# file length = 0x04;
|
||||
my $sha1Len = 0x14;
|
||||
|
||||
open INFO, ">$infoFile" or die;
|
||||
binmode INFO;
|
||||
|
||||
# オフセット算出
|
||||
my $offset = $signSize + $headerSize + $num * $elementSize;
|
||||
if( ( $offset % 32 ) > 0 ) { $offset += 32 - ( $offset % 32 ); }
|
||||
|
||||
printf "---------------------------------------------------------------\n";
|
||||
printf "filename\toffset \torig_size\tcompressed_size\n";
|
||||
foreach ( @files ) {
|
||||
# NULL指定時は、NULL出力
|
||||
if( "NULL" eq basename( $_ ) ) {
|
||||
syswrite( INFO, pack( "x$elementSize") );
|
||||
next;
|
||||
}
|
||||
|
||||
# ファイルネームの出力
|
||||
if( !( -e $_ ) ) {
|
||||
close( INFO );
|
||||
deleteTemp();
|
||||
die "file not exist. : $_\n";
|
||||
}
|
||||
my $name = basename( $_ );
|
||||
if( length $name >= $fileNameMax ) {
|
||||
close( INFO );
|
||||
deleteTemp();
|
||||
die "file name length must be smaller than $fileNameMax. : $_\n";
|
||||
}
|
||||
my $data = pack( "a$fileNameMax", $name );
|
||||
syswrite( INFO, $data, $fileNameMax );
|
||||
|
||||
# 圧縮
|
||||
my $compfile = "$_.comp";
|
||||
system ("${compprog} $compoption $_ -o $compfile");
|
||||
|
||||
# パディングの出力
|
||||
#syswrite( INFO, pack( "x$padLen") );
|
||||
|
||||
# 圧縮ファイル長を出力(もともとはpadding)
|
||||
$data = pack( "L", -s $compfile );
|
||||
syswrite( INFO, $data, 4 );
|
||||
|
||||
# ファイルオフセットの出力
|
||||
$data = pack( "L", $offset );
|
||||
syswrite( INFO, $data, 4 );
|
||||
|
||||
# ファイル長の出力
|
||||
$data = pack( "L", -s $_ );
|
||||
syswrite( INFO, $data, 4 );
|
||||
|
||||
# ファイルのSHA1ハッシュの出力
|
||||
{
|
||||
my $digest;
|
||||
#system ("openssl dgst -sha1 -binary -out $digestFile $_");
|
||||
system ("openssl dgst -sha1 -binary -out $digestFile $compfile"); # 圧縮後のファイルにハッシュをつける
|
||||
open DIGEST, $digestFile or die;
|
||||
binmode DIGEST;
|
||||
sysread( DIGEST, $digest, $sha1Len );
|
||||
close DIGEST;
|
||||
syswrite( INFO, $digest, $sha1Len );
|
||||
}
|
||||
|
||||
printf "%s\t0x%08x\t0x%08x\t0x%08x\n", $_, $offset, -s $_, -s $compfile;
|
||||
|
||||
# オフセット加算
|
||||
#$offset += -s $_;
|
||||
$offset += -s $compfile;
|
||||
if( ( $offset % 32 ) > 0 ) { $offset += 32 - ( $offset % 32 ); }
|
||||
}
|
||||
close INFO;
|
||||
printf "---------------------------------------------------------------\n";
|
||||
}
|
||||
|
||||
# ヘッダの出力
|
||||
{
|
||||
# timestampLen = 0x08;
|
||||
# elementNumLen = 0x02;
|
||||
my $padLen = 0x05;
|
||||
my $sha1Len = 0x14;
|
||||
|
||||
open HEADER, ">$headerFile" or die;
|
||||
binmode HEADER;
|
||||
|
||||
# タイムスタンプの出力
|
||||
# my $timestamp = strftime "%y%m%d%H", localtime;
|
||||
my $timestamp = $ARGV[ 0 ];
|
||||
my $region_code = $ARGV[ 1 ];
|
||||
printf "timestamp = %s\n", $timestamp;
|
||||
syswrite( HEADER, pack( "N", unpack( "L", pack( "H8", $timestamp ) ) ) );
|
||||
|
||||
# 要素数の出力
|
||||
syswrite( HEADER, pack( "S", $num ) );
|
||||
|
||||
# リージョンコードの出力
|
||||
syswrite( HEADER, pack( "C", $region_code ) );
|
||||
|
||||
# パディングの出力
|
||||
syswrite( HEADER, pack( "x$padLen") );
|
||||
|
||||
# 情報テーブルのSHA1ハッシュの出力
|
||||
{
|
||||
my $digest;
|
||||
system ("openssl dgst -sha1 -binary -out $digestFile $infoFile");
|
||||
open DIGEST, $digestFile or die;
|
||||
binmode DIGEST;
|
||||
sysread( DIGEST, $digest, $sha1Len );
|
||||
close DIGEST;
|
||||
syswrite( HEADER, $digest, $sha1Len );
|
||||
}
|
||||
close HEADER;
|
||||
}
|
||||
|
||||
# 環境変数サーチ
|
||||
foreach ( sort keys ( %ENV ) ){
|
||||
if ($_ =~ m/TWL_IPL_RED_PRIVATE_ROOT/s) {
|
||||
$KEYROOT = $ENV{$_};
|
||||
}
|
||||
}
|
||||
if (!$KEYROOT) {
|
||||
deleteTemp();
|
||||
die "No TWL_IPL_RED_PRIVATE_ROOT is found.\n";
|
||||
}
|
||||
|
||||
# ヘッダへの署名付加
|
||||
{
|
||||
system ( "openssl dgst -sha1 -binary -out $digestFile $headerFile" );
|
||||
system ( "openssl rsautl -sign -in $digestFile -inkey $KEYROOT/keys/rsa/private_sharedFont.der -keyform DER -out $signFile" );
|
||||
system ( "cat $signFile $headerFile >$tempFile" );
|
||||
system ( "cat $tempFile $infoFile >$outFile" );
|
||||
deleteTemp();
|
||||
}
|
||||
|
||||
|
||||
# フォントの出力
|
||||
{
|
||||
open FONTTABLE, ">>$outFile" or die;
|
||||
binmode FONTTABLE;
|
||||
|
||||
{
|
||||
# パディング出力
|
||||
my $fileLen = -s $outFile;
|
||||
my $padNum = ( $fileLen % 32 ) ? ( 32 - ( $fileLen % 32 ) ) : 0;
|
||||
my $padding = pack( "x$padNum" );
|
||||
syswrite( FONTTABLE, $padding, $padNum );
|
||||
}
|
||||
|
||||
foreach ( @files ) {
|
||||
# NULL指定時はスキップ
|
||||
if( "NULL" eq basename( $_ ) ) {
|
||||
next;
|
||||
}
|
||||
|
||||
# フォント出力
|
||||
#my $fileLen = -s $_;
|
||||
#open TEST, $_ or die;
|
||||
my $compfile = "$_.comp"; # 圧縮ファイルを出力
|
||||
$fileLen = -s $compfile;
|
||||
open TEST, $compfile or die;
|
||||
binmode TEST;
|
||||
sysread ( TEST, $buffer, $fileLen );
|
||||
close TEST;
|
||||
syswrite( FONTTABLE, $buffer, $fileLen );
|
||||
|
||||
# パディング出力
|
||||
my $padNum = ( $fileLen % 32 ) ? ( 32 - ( $fileLen % 32 ) ) : 0;
|
||||
my $padding = pack( "x$padNum" );
|
||||
syswrite( FONTTABLE, $padding, $padNum );
|
||||
|
||||
# 圧縮ファイルを削除
|
||||
system ("rm -rf $compfile");
|
||||
}
|
||||
close FONTTABLE;
|
||||
}
|
||||
@ -1,185 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
######################################################################
|
||||
# genVersion.pl
|
||||
#
|
||||
# generate SystemMenu Version Data
|
||||
#
|
||||
# [[ FILE FORMAT ]]
|
||||
#
|
||||
# Security code (128 bytes) : RSA signature of Header
|
||||
# Header + Data : NitroSystemArchive Format
|
||||
#
|
||||
######################################################################
|
||||
|
||||
use POSIX 'strftime';
|
||||
use File::Basename;
|
||||
|
||||
if ($#ARGV < 8) {
|
||||
printf STDOUT ("Usage: %s [genVersion] dir timestamp strVersion majorVersion minorVersion userAreaSize NUPHostName EULAURL outFile\n", $0);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
# アーカイブにまとめるデータファイル
|
||||
my $dataDir = $ARGV[0];
|
||||
my $versionFile = "$dataDir/version.bin";
|
||||
my $timeStampFile = "$dataDir/time_stamp.bin";
|
||||
my $userAreaSizeFile = "$dataDir/user_area_size.bin";
|
||||
my $nupHostFile = "$dataDir/nup_host.bin";
|
||||
my $urlEULAFile = "$dataDir/eula_url.bin";
|
||||
|
||||
# 証明書および鍵はIPL_privateで作成したものをそのまま使うのでここでは作成しない
|
||||
#my $cert4SSLClientFile = "$dataDir/cert4ssl";
|
||||
#my $privKeyCert4SSLClientFile = "$dataDir/priv_key_cert4ssl";
|
||||
#my $rootCACert4SSLFile1 = "$dataDir/root_ca_cert4ssl1";
|
||||
#my $rootCACert4SSLFile2 = "$dataDir/root_ca_cert4ssl2";
|
||||
#my $rootCACert4SSLFile3 = "$dataDir/root_ca_cert4ssl3";
|
||||
#my $rootCACert4SSLFile4 = "$dataDir/root_ca_cert4ssl4";
|
||||
#my $rootCACert4SSLFile5 = "$dataDir/root_ca_cert4ssl5";
|
||||
#my $rootCACert4SSLFile6 = "$dataDir/root_ca_cert4ssl6";
|
||||
|
||||
# 出力ファイル
|
||||
my $outFile = $ARGV[8];
|
||||
|
||||
# 中間ファイル
|
||||
my $archiveFile = "archive.narc";
|
||||
my $digestFile = "digest.bin";
|
||||
my $signFile = "sign.bin";
|
||||
|
||||
# 後始末
|
||||
sub deleteTemp {
|
||||
system ("rm -f $digestFile");
|
||||
system ("rm -f $signFile");
|
||||
system ("rm -f $archiveFile");
|
||||
system ("rm -f $versionFile");
|
||||
system ("rm -f $timeStampFile");
|
||||
system ("rm -f $userAreaSizeFile");
|
||||
system ("rm -f $nupHostFile");
|
||||
system ("rm -f $urlEULAFile");
|
||||
}
|
||||
|
||||
# 事前のテンポラリクリア
|
||||
|
||||
|
||||
# 環境変数サーチ
|
||||
foreach ( sort keys ( %ENV ) ){
|
||||
if ($_ =~ m/TWL_IPL_RED_PRIVATE_ROOT/s) {
|
||||
$KEYROOT = $ENV{$_};
|
||||
}
|
||||
}
|
||||
if (!$KEYROOT) {
|
||||
die "No TWL_IPL_RED_PRIVATE_ROOT is found.\n";
|
||||
}
|
||||
|
||||
my $TWLIPLRED_ROOT;
|
||||
|
||||
# 環境変数のキーにTWL_IPL_RED_ROOTがあるか
|
||||
if (exists($ENV{"TWL_IPL_RED_ROOT"}) ){
|
||||
$TWLIPLRED_ROOT = $ENV{"TWL_IPL_RED_ROOT"};
|
||||
}else
|
||||
{
|
||||
die "No TWL_IPL_RED_ROOT is found.\n";
|
||||
}
|
||||
|
||||
# システムメニューバージョンの出力
|
||||
{
|
||||
my $length = 0x1c;
|
||||
my $sysMenuVersion = $ARGV[2];
|
||||
if( length $sysMenuVersion >= $length ) {
|
||||
printf "ERROR: SystemMenu version length less than %d.\n", $length;
|
||||
die;
|
||||
}
|
||||
open VERSION, ">$versionFile" or die "File Open Error.\n";
|
||||
binmode VERSION;
|
||||
# my $ver = ( ( $ARGV[ 3 ] & 0xffff ) << 16 ) | ($ARGV[ 4 ] & 0xffff);
|
||||
# printf "version = %d.%d\n", ($ver >> 16), ($ver & 0xffff);
|
||||
# syswrite( VERSION, pack( "L", $ver ) );
|
||||
printf "SysMenu version = %s\n", $sysMenuVersion;
|
||||
$length /= 2; # to UTF16 length
|
||||
syswrite( VERSION, pack( "SSS$length", $ARGV[ 3 ], $ARGV[ 4 ], unpack( "C*", $sysMenuVersion ) ) );
|
||||
# pack "S*", unpack( "C*", $ascii ), 0;
|
||||
|
||||
close VERSION;
|
||||
}
|
||||
|
||||
# タイムスタンプの出力
|
||||
{
|
||||
open TIMESTAMP, ">$timeStampFile" or die "File Open Error.\n";
|
||||
binmode TIMESTAMP;
|
||||
# my $timestamp = strftime "%y%m%d%H", localtime;
|
||||
my $timestamp = $ARGV[ 1 ];
|
||||
printf "timestamp = %s\n", $timestamp;
|
||||
syswrite( TIMESTAMP, pack( "N", unpack( "L", pack( "H8", $timestamp ) ) ) );
|
||||
close TIMESTAMP;
|
||||
}
|
||||
|
||||
# ユーザエリアサイズの出力
|
||||
{
|
||||
open USERAREA, ">$userAreaSizeFile" or die "File Open Error.\n";
|
||||
binmode USERAREA;
|
||||
my $userAreaSize = $ARGV[ 5 ];
|
||||
printf "userAreaSize = $userAreaSize\n";
|
||||
syswrite( USERAREA, pack( "L", $userAreaSize ) );
|
||||
close USERAREA;
|
||||
}
|
||||
|
||||
# NUP_HOSTNAMEの出力
|
||||
{
|
||||
my $length = 0x40;
|
||||
my $nupHostName = $ARGV[ 6 ];
|
||||
if( length $nupHostName >= $length ) {
|
||||
printf "ERROR: NUP Host Name length less than %d.\n", $length;
|
||||
die;
|
||||
}
|
||||
if( $nupHostName ne "NULL" ) {
|
||||
open NUPHOSTNAME, ">$nupHostFile" or die "File Open Error.\n";
|
||||
binmode NUPHOSTNAME;
|
||||
printf "NUPHostName = $nupHostName\n";
|
||||
syswrite( NUPHOSTNAME, pack( "a$length", $nupHostName ) );
|
||||
close NUPHOSTNAME;
|
||||
}
|
||||
}
|
||||
|
||||
# EULA_URLの出力
|
||||
{
|
||||
my $length = 0x80;
|
||||
my $urlEULA = $ARGV[ 7 ];
|
||||
if( length $urlEULA >= $length ) {
|
||||
printf "ERROR: EULA URL length less than %d.\n", $length;
|
||||
die;
|
||||
}
|
||||
open EULAURL, ">$urlEULAFile" or die "File Open Error.\n";
|
||||
binmode EULAURL;
|
||||
printf "EULAURL = $urlEULA\n";
|
||||
syswrite( EULAURL, pack( "a$length", $urlEULA ) );
|
||||
close EULAURL;
|
||||
}
|
||||
|
||||
my $TWLSYSTEM_ROOT;
|
||||
|
||||
# 環境変数のキーにTWLSYSTEM_ROOTがあるか
|
||||
if (exists($ENV{"TWLSYSTEM_ROOT"}) ){
|
||||
$TWLSYSTEM_ROOT = $ENV{"TWLSYSTEM_ROOT"};
|
||||
}else
|
||||
{
|
||||
deleteTemp();
|
||||
die "No TWLSYSTEM_ROOT is found.\n";
|
||||
}
|
||||
|
||||
# アーカイブ作成
|
||||
{
|
||||
system ( "$TWLSYSTEM_ROOT/tools/bin/nnsarc.exe -c $archiveFile -A 16 -a $dataDir -s -E .svn" );
|
||||
}
|
||||
|
||||
# アーカイブのハッシュの出力
|
||||
{
|
||||
my $digest;
|
||||
system ("openssl dgst -sha1 -binary -out $digestFile $archiveFile");
|
||||
}
|
||||
|
||||
# 署名付加
|
||||
{
|
||||
system ( "openssl rsautl -sign -in $digestFile -inkey $KEYROOT/keys/rsa/private_sharedFont.der -keyform DER -out $signFile" );
|
||||
system ( "cat $signFile $archiveFile >$outFile" );
|
||||
deleteTemp();
|
||||
}
|
||||
@ -1,42 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
######################################################################
|
||||
# genFontTable.pl
|
||||
#
|
||||
# generate Secure Shared Font Data Table
|
||||
#
|
||||
######################################################################
|
||||
|
||||
if ($#ARGV < 1) {
|
||||
printf STDOUT ("Usage: %s SRL_file tgtDir\n", $0);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
open SRL, "<$ARGV[0]" or die;
|
||||
binmode SRL;
|
||||
|
||||
|
||||
# TitleID_Lo取得
|
||||
sysseek SRL, 0x230, SEEK_SET;
|
||||
my $data;
|
||||
sysread( SRL, $data, 4 );
|
||||
|
||||
my @id = unpack( "cccc", $data);
|
||||
my $titleID_Lo = pack( "cccc", $id[3], $id[2], $id[1], $id[0] );
|
||||
#printf "%s\n", $titleID_Lo;
|
||||
|
||||
|
||||
# ROMバージョン取得
|
||||
sysseek SRL, 0x1e, SEEK_SET;
|
||||
sysread( SRL, $data, 1 );
|
||||
my $version = sprintf "%d\n", unpack( "c", $data );
|
||||
#printf "%s\n", $version;
|
||||
|
||||
system( "mkdir -p $ARGV[1]/$titleID_Lo" );
|
||||
system( "mkdir -p $ARGV[1]/$titleID_Lo/V$version" );
|
||||
|
||||
#TAD格納ディレクトリprint
|
||||
printf "$ARGV[1]/$titleID_Lo/V$version";
|
||||
|
||||
close SRL
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -1,196 +0,0 @@
|
||||
#!/bin/perl
|
||||
|
||||
use strict;
|
||||
use Crypt::Rijndael;
|
||||
use Digest::SHA1 qw(sha1);
|
||||
|
||||
my $tad = $ARGV[0] or die "split_tad <tad>\n";
|
||||
my $outdir = "out";
|
||||
|
||||
my $buf;
|
||||
my $common_key = pack("H*", "A1604A6A7123B529AE8BEC32C816FCAA"); # dev
|
||||
|
||||
open(F, $tad) or die "cant open $tad\n";
|
||||
binmode(F);
|
||||
read(F, $buf, -s $tad);
|
||||
close(F);
|
||||
|
||||
mkdir $outdir;
|
||||
|
||||
|
||||
my $offset = 0;
|
||||
my $size = 32;
|
||||
my( $hdrSize, $tadType, $tadVersion, $certSize,
|
||||
$crlSize, $ticketSize, $tmdSize, $contentSize, $metaSize)
|
||||
= unpack("Na2nNNNNNN", substr($buf, $offset, $size));
|
||||
$offset += $size;
|
||||
|
||||
print <<__REPORT__;
|
||||
=============================
|
||||
hdrSize $hdrSize
|
||||
tadType $tadType
|
||||
tadVersion $tadVersion
|
||||
certSize $certSize
|
||||
crlSize $crlSize
|
||||
ticketSize $ticketSize
|
||||
tmdSize $tmdSize
|
||||
contentSize $contentSize
|
||||
metaSize $metaSize
|
||||
=============================
|
||||
__REPORT__
|
||||
|
||||
my $certOffset = &round_up($hdrSize, 64);
|
||||
my $crlOffset = &round_up($certOffset + $certSize, 64);
|
||||
my $ticketOffset = &round_up($crlOffset + $crlSize, 64);
|
||||
my $tmdOffset = &round_up($ticketOffset + $ticketSize, 64);
|
||||
my $contentOffset = &round_up($tmdOffset + $tmdSize, 64);
|
||||
my $metaOffset = &round_up($contentOffset + $contentSize, 64);
|
||||
my $fileSize = &round_up($metaOffset + $metaSize, 64);
|
||||
|
||||
die "file size is not expected size(=$fileSize)\n" if $fileSize != -s $tad;
|
||||
|
||||
my $ticket = substr($buf, $ticketOffset, $ticketSize);
|
||||
my $tmd = substr($buf, $tmdOffset, $tmdSize);
|
||||
my $content = substr($buf, $contentOffset, $contentSize);
|
||||
|
||||
&save_file("$outdir/cert.bin", substr($buf, $certOffset, $certSize));
|
||||
&save_file("$outdir/crl.bin", substr($buf, $crlOffset, $crlSize));
|
||||
&save_file("$outdir/ticket.bin", $ticket);
|
||||
&save_file("$outdir/tmd.bin", $tmd);
|
||||
#&save_file("$outdir/content.bin", substr($buf, $contentOffset, $contentSize));
|
||||
&save_file("$outdir/meta.bin", substr($buf, $metaOffset, $metaSize));
|
||||
|
||||
|
||||
my $title_key = &read_title_key($ticket);
|
||||
my $rci = &read_content_info($tmd);
|
||||
|
||||
print unpack("H*", $title_key), "\n";
|
||||
|
||||
my $offset = 0;
|
||||
foreach my $i ( @$rci )
|
||||
{
|
||||
my $size = &round_up($i->[3], 16);
|
||||
my $enc_content_x = substr($content, $offset, $size);
|
||||
my $content_x_iv = pack("n", $i->[1]) . pack("x14");
|
||||
my $dec_content_x = &dec_cbc($title_key, $content_x_iv, $enc_content_x);
|
||||
my $dec_content = substr($dec_content_x, 0, $i->[3]);
|
||||
my $hash = &sha1($dec_content);
|
||||
|
||||
print unpack("H*", $hash), " ";
|
||||
print((($hash eq $i->[4]) ? "OK": "hash mismatch"), "\n");
|
||||
&save_file("$outdir/content_$i->[1].encrypted.bin", $enc_content_x);
|
||||
&save_file("$outdir/content_$i->[1].bin", $dec_content);
|
||||
|
||||
$offset += &round_up($size, 64);
|
||||
}
|
||||
|
||||
my $cfg = read_cfg($tmd);
|
||||
save_cfg("$outdir/config.txt", $cfg);
|
||||
|
||||
print <<__REPORT__;
|
||||
=============================
|
||||
dataflg $cfg->[0]
|
||||
titleid $cfg->[1]
|
||||
groupid $cfg->[2]
|
||||
major_ver $cfg->[3]
|
||||
minor_ver $cfg->[4]
|
||||
=============================
|
||||
__REPORT__
|
||||
|
||||
maketad($tad, $cfg);
|
||||
system("/bin/rm -rf $outdir");
|
||||
|
||||
|
||||
sub round_up
|
||||
{ my( $x, $align ) = @_;
|
||||
|
||||
return int( ($x + $align - 1)/$align ) * $align;
|
||||
}
|
||||
|
||||
sub save_file
|
||||
{ my( $name, $data ) = @_;
|
||||
|
||||
open(OUT, ">$name") or die "cant open $name\n";
|
||||
binmode(OUT);
|
||||
print OUT $data;
|
||||
close(OUT);
|
||||
}
|
||||
|
||||
sub read_content_info
|
||||
{ my( $tmd ) = @_;
|
||||
my @ci = ();
|
||||
|
||||
my $nContent = unpack("n", substr($tmd, 0x1DE, 2));
|
||||
|
||||
for( my $i = 0; $i < $nContent; ++$i )
|
||||
{
|
||||
my( $cid, $idx, $type, $size, $hash )
|
||||
= unpack("Nnnx4Na20", substr($tmd, 0x1E4 + 36 * $i, 36));
|
||||
|
||||
push @ci, [$cid, $idx, $type, $size, $hash];
|
||||
}
|
||||
|
||||
return \@ci;
|
||||
}
|
||||
|
||||
sub maketad
|
||||
{ my( $tad, $cfg ) = @_;
|
||||
|
||||
my $maketad = "$ENV{TWL_IPL_RED_PRIVATE_ROOT}/tools/bin/maketad.updater.exe";
|
||||
$tad =~ s/tad/updater.tad/;
|
||||
|
||||
my $option = "";
|
||||
if( $cfg->[0] )
|
||||
{
|
||||
$option = "-d $cfg->[1] $cfg->[2] $cfg->[3] $tad -v $cfg->[4]";
|
||||
} else {
|
||||
$option = "-v $cfg->[4]";
|
||||
}
|
||||
|
||||
my $cmd = "$maketad $outdir/content_0.bin $option -s -o $tad";
|
||||
system("/bin/echo $cmd");
|
||||
system("$cmd");
|
||||
}
|
||||
|
||||
sub read_cfg
|
||||
{ my( $tmd ) = @_;
|
||||
|
||||
my( $titleid_h, $titleid_l ) = unpack("NN", substr($tmd, 0x18C, 8));
|
||||
my $groupid = sprintf("%04X", unpack("n", substr($tmd, 0x198, 2)));
|
||||
my( $major_ver, $minor_ver ) = unpack("CC", substr($tmd, 0x1DC, 2));
|
||||
|
||||
my $titleid = sprintf("%08X%08X", $titleid_h, $titleid_l);
|
||||
my $dataflg = ($titleid_h & 0x08) >> 3;
|
||||
|
||||
return [ $dataflg, $titleid, $groupid, $major_ver, $minor_ver ]
|
||||
}
|
||||
|
||||
sub save_cfg
|
||||
{ my( $name, $cfg ) = @_;
|
||||
|
||||
open(OUT, ">$name") or die "cant open $name\n";
|
||||
print OUT sprintf("dataflg = $cfg->[0]\n");
|
||||
print OUT sprintf("titleid = $cfg->[1]\n");
|
||||
print OUT sprintf("groupid = $cfg->[2]\n");
|
||||
print OUT sprintf("major_ver = $cfg->[3]\n");
|
||||
print OUT sprintf("minor_ver = $cfg->[4]\n");
|
||||
close(OUT);
|
||||
}
|
||||
|
||||
sub read_title_key
|
||||
{ my( $ticket ) = @_;
|
||||
|
||||
my $enc_title_key = substr($ticket, 0x1BF, 16);
|
||||
my $title_key_iv = substr($ticket, 0x1DC, 8) . pack("x8");
|
||||
|
||||
return &dec_cbc($common_key, $title_key_iv, $enc_title_key);
|
||||
}
|
||||
|
||||
sub dec_cbc
|
||||
{ my( $key, $iv, $data ) = @_;
|
||||
|
||||
my $cbc = Crypt::Rijndael->new($key, Crypt::Rijndael::MODE_CBC);
|
||||
$cbc->set_iv($iv);
|
||||
return $cbc->decrypt($data);
|
||||
}
|
||||
|
||||
Binary file not shown.
Loading…
Reference in New Issue
Block a user