Talk:Sony Update Downloads
From Exploitee.rs
Jump to navigationJump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
I worked on expanding the pad a bit. Here's the script I use.
#!/usr/bin/perl use strict; package abliss; my $start = shift; open HEX, "<./history/other/RfHid_v0156_2010091601_NL.hex" or die; open OUT, ">>pad.bin"; open IN, "<pad.bin"; my @files = ( "./history/NBL/batch_sync-vfat.sh", "./history/board_conf.sh", "./history/other/check_spectra1_20100929.sh", "./history/other/factory_reset_conditional_keepremote_20101012.sh", "./history/other/format_sda_20100514.sh"); my @fds; for (my $i = 0; $i <= $#files; $i++) { open (my $fd, $files[$i]) or die "can't open " . $files[$i]; push(@fds, $fd); } my @contents; my $hexbyte; my @hexchars = qw(0 1 2 3 4 5 6 7 8 9 A B C D E F :); push(@hexchars, "\r"); push(@hexchars, "\n"); my @output = (); our $xorbyte; while (read(HEX, $hexbyte, 1)) { for (my $i = 0; $i <= $#files; $i++) { my $char; if (read($fds[$i], $char, 1)) { $contents[$i] .= $char; if (length($contents[$i]) > 30) { $contents[$i] = substr($contents[$i], 1); } } } if ($start-- > 0) { my $char; read(IN, $char, 1); $xorbyte = ord($char); } else { for (my $j = 0; $j <= $#hexchars; $j++) { $xorbyte = ord($hexbyte) ^ ord($hexchars[$j]); my $choices = ""; my $ok = 1; for (my $i = 0; $i <= $#files; $i++) { my $neword = (ord(substr($contents[$i],length($contents[$i]) - 1)) ^ $xorbyte); if ($neword > 127 || ($neword < 32 && $neword != 9 && # tab $neword != 10 && # LF $neword != 13 # CR )) { $ok = 0; #printf "==== %2d ====\n%s\n", $j, xorlastbyte($contents[$i]); last; } } if ($ok) { printf "==== %2d ====\n%s\n", $j, join("\n--\n", map {xorlastbyte($_)} @contents); } } my $answer = <STDIN>; chomp $answer; if ($answer eq "q") { close OUT; die; } $xorbyte = ord($hexbyte) ^ ord($hexchars[$answer]); print OUT chr($xorbyte); } @contents = map {xorlastbyte($_)} @contents; } sub xorlastbyte { my $content = shift; if ($content) { my @chars = split(//, $content); $chars[-1] = chr(ord($chars[-1])^ $xorbyte); return join('', @chars); } }
Here's my pad, 134 chars:
00000000 38 cf 4f aa 7a 8a 2e 3e 2b 41 82 9a ad 31 e9 dc |8.O.z..>+A...1..| 00000010 ef 47 2f 0b 26 76 12 fe 5f 5b 58 e1 10 18 7d e6 |.G/.&v.._[X...}.| 00000020 ad 92 1b 91 8e 90 69 f7 8a 9b 68 d8 98 58 fa 95 |......i...h..X..| 00000030 63 81 d6 5f 04 7d 29 8b 09 cf b9 21 b8 d9 df dd |c.._.})....!....| 00000040 c4 7e 71 d9 3f 35 ea 7b 0d ec 7f d1 a3 76 64 88 |.~q.?5.{.....vd.| 00000050 a5 8e 27 49 60 c0 a0 bc 77 54 31 e3 d6 6a bf e5 |..'I`...wT1..j..| 00000060 1b 42 25 da a3 97 b8 e1 ba 54 13 5b 68 31 da ff |.B%......T.[h1..| 00000070 1c 5c 15 46 4e 32 f1 76 50 e0 4e f3 ab 9a 28 bb |.\.FN2.vP.N...(.| 00000080 b5 cf 2f 50 24 45 |../P$E|
I checked the checksums in the .hex file and they all validate so far.
Catrane 2011.02.11: Nice work, Abliss. It sounds like we're running similar approaches. Here's my script. It prints one line for each byte, listing all the possibilities. I then do a human search for anything that looks predictable and work it by hand. The 756 byte key I posted was also verified using the .hex checksums in addition to visual inspection. The typos in the code make visual inspection a little tricky.
#!/usr/bin/perl use strict; use warnings; use IO::File; my @files = (); my @filters = (); my @rules = (); my %ruleinfo = (); my $files_left = 0; #my $textfilter = "[[:print:]\x0a\x0b\t\n\r\f ]"; my $textfilter = "[[:print:]\x0a\t ]"; my $intelhexfilter = "[0-9A-F:\x0d\x0a]"; my $knownmasks = ""; if ( -f 'knownmasks' ) { $knownmasks = `cat knownmasks`; } sub checkRules { my ($rule,$char) = @_; if ( "text" eq $ruleinfo{$rule}{'type'} ) { } elsif ( "intelhex" eq $ruleinfo{$rule}{'type'} ) { if ( $ruleinfo{$rule}{'is_colon'} ) { return 0 unless ( ":" eq $char ); } if ( $ruleinfo{$rule}{'was_colon'} > 0 ) { return 0 if ( ($ruleinfo{$rule}{'was_colon'} < 12) && ("\x0a" eq $char) ); return 0 if ( ($ruleinfo{$rule}{'was_colon'} < 11) && (("\x0a" eq $char) || ("\x0d" eq $char)) ); return 0 if ( ":" eq $char ); } return 0 if ( ( ":" eq $char ) && ! $ruleinfo{$rule}{'was_maybe_0a'} ); return 0 if ( ( "\x0a" eq $char ) && ! $ruleinfo{$rule}{'was_maybe_0d'} ); } return 1; } sub advanceRules { my ($rule,$options) = @_; if ( "text" eq $ruleinfo{$rule}{'type'} ) { } elsif ( "intelhex" eq $ruleinfo{$rule}{'type'} ) { my $is_nr = ( $options =~ m/^\\[nr]\\[nr]$/ ); # 0d0a == \r\n my $is_maybe_0d = ( $options =~ m/\\r/ ); my $is_maybe_0a = ( $options =~ m/\\n/ ); if ( $ruleinfo{$rule}{'was_colon'} ) { $ruleinfo{$rule}{'was_colon'}++; if ( $ruleinfo{$rule}{'was_colon'} > 12 ) { $ruleinfo{$rule}{'was_colon'} = 0; } } if ( $ruleinfo{$rule}{'is_colon'} ) { $ruleinfo{$rule}{'is_colon'} = 0; $ruleinfo{$rule}{'was_colon'} = 1; } elsif ( $ruleinfo{$rule}{'was_nr'} ) { $ruleinfo{$rule}{'is_colon'} = $is_nr; } $ruleinfo{$rule}{'was_nr'} = $is_nr; $ruleinfo{$rule}{'was_maybe_0d'} = $is_maybe_0d; $ruleinfo{$rule}{'was_maybe_0a'} = $is_maybe_0a; } } while ( my $filter = shift ) { if ( "text" eq $filter ) { push(@filters,$textfilter); push(@rules,$files_left); $ruleinfo{$files_left}{'type'} = "text"; } elsif ( "intelhex" eq $filter ) { push(@filters,$intelhexfilter); push(@rules,$files_left); $ruleinfo{$files_left}{'type'} = "intelhex"; $ruleinfo{$files_left}{'is_colon'} = 1; # First must be colon. $ruleinfo{$files_left}{'was_colon'} = 0; $ruleinfo{$files_left}{'was_nr'} = 1; # Make like normal colon setup. $ruleinfo{$files_left}{'was_maybe_0d'} = 0; $ruleinfo{$files_left}{'was_maybe_0a'} = 1; # Make like normal colon setup. } elsif ( "test_text" eq $filter ) { my $counter = 0; my $fh = IO::File->new("< ".shift) or die "Unable to open file.\n"; while ( defined( my $char = getc($fh) ) ) { die "failed test at index $counter.\n" unless ( $char =~ m/$textfilter/ ); $counter++; } print "test passed.\n"; exit; } elsif ( "test_intelhex" eq $filter ) { my $counter = 0; my $fh = IO::File->new("< ".shift) or die "Unable to open file.\n"; while ( defined( my $char = getc($fh) ) ) { die "failed test at index $counter.\n" unless ( $char =~ m/$intelhexfilter/ ); $counter++; } print "test passed.\n"; exit; } else { die "Invalid filter '$filter'.\n"; } my $file = shift; die "Missing filename parameter.\n" unless defined $file; die "File '$file' does not exist.\n" unless ( -f $file ); my $fh = IO::File->new("< $file") or die "Unable to open file '$file'.\n"; push(@files,$fh); $files_left++; } while ( $files_left ) { my @options = ("\x00","\x01","\x02","\x03","\x04","\x05","\x06","\x07","\x08","\x09","\x0a","\x0b","\x0c","\x0d","\x0e","\x0f", "\x10","\x11","\x12","\x13","\x14","\x15","\x16","\x17","\x18","\x19","\x1a","\x1b","\x1c","\x1d","\x1e","\x1f", "\x20","\x21","\x22","\x23","\x24","\x25","\x26","\x27","\x28","\x29","\x2a","\x2b","\x2c","\x2d","\x2e","\x2f", "\x30","\x31","\x32","\x33","\x34","\x35","\x36","\x37","\x38","\x39","\x3a","\x3b","\x3c","\x3d","\x3e","\x3f", "\x40","\x41","\x42","\x43","\x44","\x45","\x46","\x47","\x48","\x49","\x4a","\x4b","\x4c","\x4d","\x4e","\x4f", "\x50","\x51","\x52","\x53","\x54","\x55","\x56","\x57","\x58","\x59","\x5a","\x5b","\x5c","\x5d","\x5e","\x5f", "\x60","\x61","\x62","\x63","\x64","\x65","\x66","\x67","\x68","\x69","\x6a","\x6b","\x6c","\x6d","\x6e","\x6f", "\x70","\x71","\x72","\x73","\x74","\x75","\x76","\x77","\x78","\x79","\x7a","\x7b","\x7c","\x7d","\x7e","\x7f", "\x80","\x81","\x82","\x83","\x84","\x85","\x86","\x87","\x88","\x89","\x8a","\x8b","\x8c","\x8d","\x8e","\x8f", "\x90","\x91","\x92","\x93","\x94","\x95","\x96","\x97","\x98","\x99","\x9a","\x9b","\x9c","\x9d","\x9e","\x9f", "\xa0","\xa1","\xa2","\xa3","\xa4","\xa5","\xa6","\xa7","\xa8","\xa9","\xaa","\xab","\xac","\xad","\xae","\xaf", "\xb0","\xb1","\xb2","\xb3","\xb4","\xb5","\xb6","\xb7","\xb8","\xb9","\xba","\xbb","\xbc","\xbd","\xbe","\xbf", "\xc0","\xc1","\xc2","\xc3","\xc4","\xc5","\xc6","\xc7","\xc8","\xc9","\xca","\xcb","\xcc","\xcd","\xce","\xcf", "\xd0","\xd1","\xd2","\xd3","\xd4","\xd5","\xd6","\xd7","\xd8","\xd9","\xda","\xdb","\xdc","\xdd","\xde","\xdf", "\xe0","\xe1","\xe2","\xe3","\xe4","\xe5","\xe6","\xe7","\xe8","\xe9","\xea","\xeb","\xec","\xed","\xee","\xef", "\xf0","\xf1","\xf2","\xf3","\xf4","\xf5","\xf6","\xf7","\xf8","\xf9","\xfa","\xfb","\xfc","\xfd","\xfe","\xff"); my $options_left = 256; if ( $knownmasks =~ s/^(..)\n// ) { my $knownmask = $1; if ( $knownmask =~ m/[0-9a-f]{2}/i ) { my $val; eval('$val = "\\x'.$knownmask.'";'); $options[0] = $val; $options_left = 1; } } my @filechars = (); for ( my $i = 0; $i < $files_left; $i++ ) { my $char = getc($files[$i]); if ( defined($char) ) { $filechars[$i] = $char; my $filter = $filters[$i]; for ( my $x = 0; $x < $options_left; $x++ ) { #print "$x vs $options_left\n"; # print "char is $char\n"; # print "option is $options[$x]\n"; my $realchar = $char ^ $options[$x]; unless ( ($realchar =~ m/$filter/) && checkRules($rules[$i],$realchar) ) { splice(@options,$x,1); $x--; $options_left--; } } } else { $files[$i]->close; splice(@files,$i,1); splice(@filters,$i,1); splice(@rules,$i,1); $i--; $files_left--; } } last unless $files_left; die "Failed to solve.\n" unless $options_left; for ( my $i = 0; $i < $files_left; $i++ ) { my $options = ""; for ( my $x = 0; $x < $options_left; $x++ ) { my $realchar = $filechars[$i] ^ $options[$x]; $realchar = "\\t" if ( $realchar eq "\t" ); $realchar = "\\r" if ( $realchar eq "\r" ); $realchar = "\\n" if ( $realchar eq "\n" ); #$realchar = "\\v" if ( $realchar eq "\v" ); $realchar = "\\v" if ( $realchar eq "\x0b" ); $realchar = "\\a" if ( $realchar eq "\x0a" ); $realchar = "\\f" if ( $realchar eq "\f" ); $realchar = "\\s" if ( $realchar eq " " ); $options .= $realchar; } print $options."\n" unless $i; advanceRules($rules[$i],$options); } } print "Done\n";