|
аттачить мне не дает, так что исходник только, сможешь main.bin вытащить сам
Универсально пока не получилось, вот это для 6.20 подходит. там их почему-то 2 разных ipl с 2 разными main.bin - part2_nandipl_01g.bin и part2_nandipl_02g.ipl. может это для разных версий материнок разные грузятся
если перла нет, то ставишь http://strawberryperl.com/ и потом cpan Math::Random::MT
#!/usr/bin/perl -w
use strict;
use Math::Random::MT;
use Digest::SHA qw/sha224/;
use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ;
print("Use: $0 infile outfile\n"), exit unless @ARGV == 2;
my $ipl = load($ARGV[0]);
# this consts changed from version to version. todo - extracting from code
my @data = unpack 'I*', substr($ipl,0x2980,0x8180);
my $key1 = substr($ipl,0x2800,0x40);
my $key2 = substr($ipl,0x2840,0x40);
# get pre_ipl dependent key
my @psp_bios = unpack 'I*', load('psp_bios.bin');
my $gen = new Math::Random::MT(0xBFC00040);
my @buf = map {uint($psp_bios[$_] + $gen->rand(4294967296))} (0..1023);
my $key = hmac_sha224_modified(substr($ipl,0x2580,0x280), pack('I*',@buf))."\x00\x00\x00\x00";
my $sum = 0;
my @key = unpack 'C*', $key;
$sum = ($sum+$_) & 255 for @key;
if( $sum == ord(substr($ipl,0x28A0)) ) {
my @key2 = unpack 'C*', substr($ipl, 0x2880, 32);
$key[$_] ^= $key2[$_] for 0..31;
$key = pack 'C*', @key;
}
$key = hmac_sha224_modified($key1, $key);
# decrypt
$gen = sfmt_init(unpack('I*',$key));
for( my $i = 0; $i < @data; $i += 7 ) {
my @rnd = map {sfmt_gen($gen)} (1..16);
my @xor = unpack 'I*', hmac_sha224_modified($key2, pack('I*',@rnd));
for( my $j = 0; $j < 7 && $i+$j < @data; ++$j ) {
$data[$i+$j] ^= $xor[$j];
}
}
# decompress
gunzip \pack('I*', @data) => \my $unpacked or die "gunzip failed: $GunzipError\n";
open FO, ">$ARGV[1]";
binmode FO;
print FO $unpacked;
close FO;
print length($unpacked), "\n";
# hmac_sha224 with non-standard xor constants
sub hmac_sha224_modified
{
my($key, $data) = @_;
$key = sha224($key) if length($key) > 64;
$key .= "\x00" x (64-length($key)) if length($key) < 64;
$key = join '', map {chr($_ ^ 0x36)} unpack 'C*', $key;
my $key2 = sha224($key.$data);
$key = join '', map {chr($_ ^ 0x6A)} unpack 'C*', $key;
return sha224($key.$key2);
}
# standard sfmt random generator. i've not found perl implementation
sub sfmt_init
{
my(@seed) = @_;
my @buf = map {0x8b8b8b8b} (1..0x270);
my $count = @seed + 1 > 0x270 ? @seed + 1 : 0x270;
unshift @seed, scalar(@seed);
for(my $i = 0; $i < $count; ++$i) {
my $r = $buf[$i % 0x270] ^ $buf[($i+306) % 0x270] ^ $buf[($i+0x26F) % 0x270];
$r ^= ($r >> 27);
{use integer; $r *= 1664525}
$buf[($i+306)%0x270] = uint($buf[($i+306)%0x270] + $r);
$r = uint($r + $i + ($seed[$i]||0));
$buf[($i+317)%0x270] = uint($buf[($i+317)%0x270] + $r);
$buf[$i % 0x270] = $r;
}
my $i = $count % 0x270;
for my $j (0..0x26F) {
my $r = uint($buf[$i] + $buf[($i+306)%0x270] + $buf[($i+0x26F)%0x270]);
$r ^= ($r >> 27);
{use integer; $r *= 1566083941}
$buf[($i+306)%0x270] ^= $r;
$r = uint($r - $i);
$buf[($i+317)%0x270] ^= $r;
$buf[$i] = $r;
$i = ($i + 1) % 0x270;
}
my @parity = (1,0,0,0x13c9e684);
my $inner = 0;
$inner ^= ($buf[$_] & $parity[$_]) for 0..3;
$inner ^= $inner >> (1 << (4-$_)) for 0..4;
$buf[0] ^= 1 unless $inner & 1;
return [0x270,@buf];
}
sub sfmt_gen
{
my($ctx) = @_;
return $ctx->[++$ctx->[0]] if $ctx->[0] < 0x270;
for(my $i = 0; $i < 0x270; $i += 4) {
my $r1 = ($i + 0x268) % 0x270;
my $r2 = ($i + 0x26C) % 0x270;
my $pos1 = ($i + 488) % 0x270;
my @x = unpack 'I*', "\x00".pack 'I*', @$ctx[($i+1)..($i+4)];
my @y = unpack 'I*', substr(pack('I*', @$ctx[$r1+1..$r1+4]), 1)."\x00";
$ctx->[$i+1] = $ctx->[$i+1] ^ $x[0] ^ (($ctx->[$pos1+1] >> 11) & 0xdfffffef) ^ $y[0] ^ ($ctx->[$r2+1] << 18);
$ctx->[$i+2] = $ctx->[$i+2] ^ $x[1] ^ (($ctx->[$pos1+2] >> 11) & 0xddfecb7f) ^ $y[1] ^ ($ctx->[$r2+2] << 18);
$ctx->[$i+3] = $ctx->[$i+3] ^ $x[2] ^ (($ctx->[$pos1+3] >> 11) & 0xbffaffff) ^ $y[2] ^ ($ctx->[$r2+3] << 18);
$ctx->[$i+4] = $ctx->[$i+4] ^ $x[3] ^ (($ctx->[$pos1+4] >> 11) & 0xbffffff6) ^ $y[3] ^ ($ctx->[$r2+4] << 18);
}
return $ctx->[$ctx->[0] = 1];
}
sub uint
{
my($v) = @_;
$v += 4294967296 while $v < 0;
$v -= 4294967296 while $v > 4294967296;
return $v;
}
sub load
{
open F, "<$_[0]" or die "Can't open $_[0]";
binmode F;
my $res = join '', <F>;
close F;
return $res;
}
rustot добавил 14-02-2010 в 20:46
вот на эти данные желательно напустить kirk, очень вероятно что на выходе будут искомые ключи
0xAA, 0x76, 0x91, 0xDC, 0xB1, 0x25, 0x49, 0x0D,
0x2B, 0x2F, 0x4B, 0x35, 0x13, 0xC7, 0x1B, 0x85,
0x28, 0x40, 0x4B, 0x2E, 0x87, 0xD9, 0xB2, 0xA5,
0xEB, 0x9F, 0x74, 0xF8, 0xBC, 0xDD, 0x51, 0x65,
0xB8, 0x93, 0x14, 0xFF, 0xA7, 0x82, 0xD0, 0xBB,
0xFC, 0x3F, 0x59, 0xD0, 0xA4, 0x70, 0xC6, 0xE4,
0xB7, 0xCA, 0x4E, 0x5D, 0x4A, 0x96, 0x7C, 0x48,
0x41, 0x55, 0xFE, 0xD8, 0xE8, 0x36, 0x77, 0xAE,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xB1, 0xAD, 0x73, 0xC3, 0x34, 0xED, 0x51, 0x6B,
0x5F, 0x64, 0x8D, 0xC3, 0x76, 0x13, 0xEE, 0x2F,
0xFC, 0xE2, 0xE9, 0x85, 0xC9, 0x56, 0x0F, 0xE8,
0xCA, 0x61, 0x0F, 0xAF, 0x8E, 0x38, 0xDD, 0x43,
0x2A, 0x22, 0x03, 0x82, 0xE8, 0x2C, 0x1D, 0x73,
0xD2, 0x7C, 0x79, 0xB4, 0xDD, 0xC5, 0x70, 0x48,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
rustot добавил 15-02-2010 в 03:05
вот так выглядит стартовый код main.bin. в 0xBFC00000 лежат 256 байт положенные туда из ipl, после decrypt() они выглядят так как выше заквочено, а дальше идет kirk, это только на psp можно сделать (если никто еще не сломал его, ведь откуда-то знают что он AES делает, но как именно не говорят)
decrypt(0, 0, 0x400D580, 0x400D5C0, 0xBFC00000, 0x100)
memset(0x400D580, 0, 0x40);
memset(0x400D5C0, 0, 0x40);
M(0xBC10004C) |= 0x400;
M(0xBC100050) |= 0x80;
M(0xBC100050) &= ~0x80;
M(0xBC10004C) &= ~0x400;
M(0xBC100050) |= 0x80;
if( kirk_decrypt(0xBFC00000, 0xBFC00000) ) {
memset(0xBFC00000, 0, 0x1000)
fill_dcache();
clear_important_mem();
l04006824();
l04008250(0);
while(1);
}
memcpy(buf, 0xBFC00000, 0x20);
memset(0xBFC00000, 0, 0x1000);
memcpy(0xBFC00200, buf, 0x20);
rustot добавил 15-02-2010 в 14:53
мне уже раскриптовали. не те это ключи, это известные
0xEA, 0x95, 0xD0, 0x1B, 0x6C, 0x91, 0x4C, 0xED,
0xA2, 0x1C, 0x72, 0x45, 0xEE, 0x08, 0x21, 0xB0,
0xB7, 0x0D, 0x55, 0x62, 0x73, 0x5F, 0xB0, 0x99,
0xB8, 0x2D, 0x41, 0xF8, 0xBE, 0x7E, 0x67, 0x1F
its the kernel key seed for slim and phat. 0x00-0x10 is phat, 0x10-0x20 is slim. The slims seed goes through further processing.
|
Последний раз редактировалось rustot; 15.02.2010 в 14:53.
Причина: добавил, подумав
|