📄 typhooncidedit.pl
字号:
#!perl -w# (C) 2003-2007 Willem Jan Hengeveld <itsme@xs4all.nl># Web: http://www.xs4all.nl/~itsme/# http://wiki.xda-developers.com/## $Id: typhooncidedit.pl 1881 2008-06-26 10:49:11Z itsme $#use strict;use Getopt::Long;## pdocread -n 1 0 0x10000 cid-block.nb# perl typhooncidedit.pl cid-block.nb -c GSMK-000 -w cid-gsmk.nb# pdocwrite -n 1 cid-gsmk.nb## bootloader command 'info 2' should return the current cid# bootloader command 'set 32 0' should return the current security level## csum= dword_sum(data[0..0xfff7])# checksum: decrypt({csum, csum}, encrypt(data[0x010..0x017], key(g+19)) )# keyix= encrypt(data[0x1a0..0x1a7], key(g+53))[3]# cid = encrypt(data[0x160..0x17f], encrypt(data_1200[keyix], key(g+77)) )# 0x0000-0x0004 - version# 0x0010-0x0018 - checksum cryptkey# 0x0140-0x0148 - imei# 0x0160-0x0180 - cid# 0x01a0-0x01a8 - keyindex at byte +3# 0x1200-0x1a00 - cid cryptkey# 0x1c80-0x1c88 - lockflag# 0x1d00-0x1f00 - lockcodes# 0x4000-0x4400 - mccmnc# 0xfff8-0xffff - checksum of 0-0xfff8# parts changed from default value:# 0000-0003 version# 0140-0147 imei# 0160-017f cid# 01a0-01a7 keyindex# 16b0-16b7 cidcryptkey# 1c80-1c87 lockflag# 4000-400f mccmnc# fff8-ffff checksum# use Crypt::DES;use IO::File;my @keylist= ( pack("C*", 0x51, 0x0F, 0x54, 0x3A, 0xD7, 0xBF, 0xBE, 0xCF), pack("C*", 0xE1, 0x87, 0xEF, 0xDB, 0x1F, 0xEA, 0xB4, 0x07), pack("C*", 0x64, 0xFD, 0x18, 0x47, 0xA9, 0x62, 0x85, 0x67), pack("C*", 0x55, 0x7A, 0x2B, 0xE7, 0xBC, 0xD7, 0xA5, 0x08), pack("C*", 0xE5, 0xF0, 0xDA, 0x27, 0x90, 0x19, 0x22, 0x4A), pack("C*", 0x77, 0xB2, 0xAB, 0xF9, 0xD5, 0x9E, 0x1A, 0x4F), pack("C*", 0x25, 0xF7, 0x75, 0x50, 0x2C, 0xFF, 0x40, 0x7D), pack("C*", 0x39, 0x5A, 0xE6, 0xA6, 0xAC, 0x7B, 0x5B, 0x00), pack("C*", 0xB5, 0x5D, 0x00, 0x77, 0x5E, 0x73, 0xC7, 0x45), pack("C*", 0xCC, 0xE1, 0x97, 0xC4, 0xC1, 0xEC, 0xF2, 0x80), pack("C*", 0x66, 0xAF, 0xD5, 0x91, 0x48, 0x10, 0xDF, 0x28), pack("C*", 0xA0, 0xF3, 0xB6, 0x67, 0xD7, 0xAE, 0xA7, 0x76), pack("C*", 0x49, 0xBC, 0x8C, 0xD3, 0x4A, 0xB5, 0xF3, 0xE9), pack("C*", 0x66, 0x7D, 0x7C, 0xE5, 0xED, 0xBC, 0x83, 0xC5), pack("C*", 0xB0, 0x8F, 0xFF, 0xB1, 0x05, 0x7E, 0xAA, 0x8F), pack("C*", 0x11, 0xAD, 0x63, 0xD2, 0x46, 0x56, 0xD0, 0x92), pack("C*", 0x2A, 0x76, 0x47, 0xE2, 0x5A, 0xC7, 0xEF, 0x5E), pack("C*", 0xCF, 0xEF, 0x22, 0x03, 0x61, 0xF7, 0x16, 0x44), pack("C*", 0x89, 0xFE, 0xBD, 0x59, 0x6B, 0x2F, 0xE9, 0xDB), pack("C*", 0x14, 0xF0, 0xB4, 0x8E, 0x00, 0x5C, 0x1F, 0x7E), pack("C*", 0xDF, 0xF4, 0xF9, 0x4D, 0x98, 0x91, 0x03, 0xCB), pack("C*", 0x8F, 0x9E, 0x51, 0xC7, 0x24, 0x83, 0xF3, 0x25), pack("C*", 0x7C, 0x64, 0xD5, 0x31, 0x83, 0x0C, 0xE4, 0x33), pack("C*", 0x31, 0x24, 0x72, 0x44, 0x0D, 0xA9, 0xDC, 0x5F), pack("C*", 0xF0, 0x9D, 0x6A, 0xBB, 0x0C, 0xFC, 0x76, 0x58), pack("C*", 0x2C, 0xF1, 0xD1, 0xD8, 0x3D, 0x4A, 0x62, 0x91), pack("C*", 0x0E, 0x2A, 0x10, 0xE0, 0x54, 0xFD, 0xE3, 0xC0), pack("C*", 0xF1, 0xB1, 0x65, 0x9B, 0x76, 0x24, 0x4F, 0x60), pack("C*", 0xE6, 0xD8, 0x61, 0xD5, 0xBD, 0xEE, 0x92, 0x2F), pack("C*", 0x30, 0x52, 0x69, 0xE0, 0xB7, 0x33, 0xAB, 0xB0), pack("C*", 0xC9, 0xB6, 0x36, 0x0F, 0xE6, 0xEB, 0x2D, 0xA9), pack("C*", 0xDB, 0x00, 0x55, 0x3C, 0x42, 0xB4, 0xBF, 0xA6), pack("C*", 0x48, 0x0F, 0xA8, 0x43, 0xB3, 0x50, 0x9D, 0x75), pack("C*", 0x23, 0x28, 0xE3, 0x84, 0x97, 0x25, 0x15, 0xA9), pack("C*", 0x34, 0x71, 0x0F, 0x65, 0x42, 0xBC, 0x0B, 0x17), pack("C*", 0x78, 0x77, 0x0A, 0xCE, 0x79, 0x43, 0x76, 0x5C), pack("C*", 0x9E, 0xA9, 0x05, 0xAC, 0xF6, 0x0B, 0xE0, 0x55), pack("C*", 0x8B, 0xDA, 0x05, 0x6E, 0xE7, 0x0A, 0xE9, 0xA5), pack("C*", 0xD7, 0xC3, 0x62, 0x8B, 0x6F, 0x5A, 0xC5, 0x32), pack("C*", 0x4E, 0x7F, 0x4B, 0xFA, 0x24, 0xB8, 0xBA, 0xA8), pack("C*", 0x71, 0x0E, 0x41, 0xB8, 0x8F, 0x05, 0xA3, 0xF5), pack("C*", 0xF2, 0xD2, 0x98, 0x46, 0xAF, 0xC9, 0x70, 0xCB), pack("C*", 0x3B, 0x15, 0xF9, 0x28, 0x75, 0xAB, 0xA3, 0x21), pack("C*", 0xE7, 0x81, 0xE2, 0x68, 0x49, 0xFA, 0xD4, 0xB2), pack("C*", 0x47, 0xA5, 0x24, 0x10, 0x85, 0x28, 0x2E, 0x7D), pack("C*", 0xDF, 0x77, 0x63, 0xB3, 0xF5, 0x4A, 0xEF, 0x44), pack("C*", 0xE7, 0xCD, 0x9A, 0xE5, 0x5D, 0x99, 0xEC, 0x0D), pack("C*", 0xCB, 0xE3, 0x95, 0xBF, 0xF3, 0xF3, 0x0C, 0xA3), pack("C*", 0xAB, 0xD8, 0x75, 0x5C, 0xE0, 0x5B, 0xC8, 0x16), pack("C*", 0xDB, 0x31, 0x30, 0x5E, 0xC3, 0x75, 0xB1, 0x37), pack("C*", 0x63, 0x55, 0x0E, 0x6A, 0x2E, 0x0B, 0xEA, 0x1D), pack("C*", 0x80, 0x0F, 0x2D, 0xA7, 0x27, 0x8A, 0xA9, 0xA3), pack("C*", 0x22, 0x0E, 0xFE, 0x43, 0xA8, 0x85, 0xBA, 0xE8), pack("C*", 0x6D, 0x68, 0xC5, 0xEF, 0x20, 0x32, 0xFD, 0xCD), pack("C*", 0x38, 0x13, 0x1D, 0x5E, 0xF0, 0xE8, 0xE3, 0x7A), pack("C*", 0x90, 0x6B, 0x72, 0xCA, 0xEF, 0xA7, 0xF5, 0xD9), pack("C*", 0x36, 0xB0, 0x85, 0x6E, 0xE6, 0x90, 0x4D, 0x1A), pack("C*", 0x1D, 0x84, 0xEB, 0x0D, 0x15, 0x69, 0x1A, 0x2D), pack("C*", 0xED, 0x71, 0x8E, 0x6A, 0xAC, 0x1A, 0x20, 0x4B), pack("C*", 0x83, 0x61, 0x2B, 0xCD, 0x52, 0x32, 0x36, 0x6E), pack("C*", 0x6E, 0x24, 0xD3, 0x85, 0xA2, 0x63, 0xC6, 0xD4), pack("C*", 0x73, 0xED, 0x6A, 0x60, 0xA8, 0x02, 0x51, 0x81), pack("C*", 0x0A, 0xD5, 0x2B, 0x35, 0x69, 0x88, 0xE9, 0xB9), pack("C*", 0xDF, 0x57, 0x22, 0x5B, 0x59, 0x14, 0xB5, 0x8A), pack("C*", 0x52, 0xD3, 0xB0, 0x2F, 0xE2, 0xE6, 0x70, 0x40), pack("C*", 0xF8, 0x0C, 0x0A, 0x91, 0xE3, 0xE5, 0xEA, 0xEE), pack("C*", 0x18, 0xA9, 0xBA, 0x68, 0x2F, 0x1A, 0x86, 0xEC), pack("C*", 0x2E, 0xB7, 0x1D, 0x1A, 0x0A, 0x33, 0xBA, 0x53), pack("C*", 0x6B, 0x25, 0xE3, 0x14, 0xB0, 0x01, 0x92, 0x83), pack("C*", 0x33, 0x47, 0x93, 0x48, 0xCE, 0xFA, 0x2D, 0x9E), pack("C*", 0x9E, 0x54, 0x04, 0xAA, 0x06, 0xB8, 0x3E, 0x0B), pack("C*", 0xF7, 0xE8, 0xE5, 0xB2, 0x6F, 0x78, 0x8C, 0xF4), pack("C*", 0x40, 0x83, 0x36, 0xDD, 0x13, 0x9C, 0x73, 0xC8), pack("C*", 0xAC, 0x07, 0xCC, 0x2C, 0x70, 0x2A, 0x61, 0xB9), pack("C*", 0x24, 0x3E, 0xD1, 0xA4, 0xF7, 0x4A, 0x5A, 0x3F), pack("C*", 0xC3, 0x52, 0x42, 0xCC, 0x90, 0xCB, 0x75, 0x93), pack("C*", 0x5A, 0x53, 0x6F, 0x32, 0x14, 0x9F, 0x5C, 0x35), pack("C*", 0xEC, 0xB5, 0x7E, 0xE6, 0xD1, 0x5B, 0xD0, 0x66), pack("C*", 0x32, 0xCF, 0xE9, 0xFD, 0x09, 0xB8, 0x22, 0xAF), pack("C*", 0x19, 0x5D, 0xFB, 0x10, 0x73, 0x15, 0xBB, 0x59), pack("C*", 0x3F, 0xFE, 0x57, 0xBA, 0xB9, 0xF2, 0x95, 0xF2), pack("C*", 0x7A, 0xB7, 0x71, 0x1E, 0xF9, 0x76, 0xC0, 0xCE), pack("C*", 0x51, 0x6F, 0x13, 0x5E, 0x45, 0xEA, 0xDE, 0x84), pack("C*", 0x81, 0x71, 0xDA, 0x25, 0x22, 0x3C, 0xA7, 0x6D), pack("C*", 0x79, 0xED, 0xB6, 0x1E, 0x0C, 0x7E, 0x66, 0x28), pack("C*", 0xDE, 0x77, 0x6D, 0x7B, 0xF1, 0x64, 0x7A, 0x19), pack("C*", 0x08, 0x86, 0x19, 0x6F, 0xB1, 0xC9, 0xD6, 0xE5), pack("C*", 0x83, 0xF6, 0xA5, 0xB4, 0xA5, 0x2A, 0x81, 0xF7), pack("C*", 0x90, 0x87, 0x54, 0x06, 0x15, 0x29, 0x17, 0xFF), pack("C*", 0xA1, 0x5B, 0x3A, 0xA5, 0xC0, 0x0B, 0x46, 0x6E), pack("C*", 0xE0, 0x7C, 0xC1, 0xD7, 0x58, 0x3B, 0x52, 0xFB), pack("C*", 0xA8, 0x54, 0x25, 0x64, 0x02, 0xC5, 0x91, 0x21), pack("C*", 0x0A, 0x33, 0xF8, 0x18, 0xDB, 0xDC, 0xEF, 0x9E), pack("C*", 0x4A, 0xCD, 0x9F, 0x45, 0x6E, 0x55, 0x6B, 0xF5), pack("C*", 0x60, 0xB9, 0xD4, 0x3F, 0x3F, 0x29, 0x99, 0xED), pack("C*", 0x77, 0xF3, 0x22, 0xDE, 0x43, 0xF7, 0x1E, 0x11), pack("C*", 0x71, 0x5B, 0x6C, 0xFF, 0x66, 0x80, 0x37, 0x2E), pack("C*", 0x61, 0x34, 0x66, 0x03, 0x04, 0x29, 0x33, 0xD8), pack("C*", 0x10, 0xA5, 0x19, 0x4E, 0x70, 0x7C, 0xF4, 0xE4), pack("C*", 0x79, 0x3C, 0x64, 0xC9, 0x70, 0xA7, 0x72, 0xEF),);my $keyix;my $writefile;my $newcid;my $docid;sub usage { return <<__EOF__Usage: typhooncidedit [-i DOCID] [-k keyix] [-w outfile] [-c newcid] infile__EOF__}my %items= ( version=>{ offset=>0x0000, size=>4, encoding=>1}, chkkey=> { offset=>0x0010, size=>8, encoding=>0}, imei=> { offset=>0x0140, size=>8, encoding=>1}, #get_cid_data cid=> { offset=>0x0160, size=>32, encoding=>1}, #get_cid_data cidkeyix=>{ offset=>0x01a0, size=>8, encoding=>2}, #get_01a0_block cidkey=> { offset=>0x1200, size=>0x800, encoding=>3},#get_cid_decryption_key locks=> { offset=>0x1c80, size=>8, encoding=>1}, #get_cid_data codes=> { offset=>0x1d00, size=>0x200, encoding=>6}, #get_cid_data+decrypt_with_2keys mccmnc=> { offset=>0x4000, size=>0x400, encoding=>1},#get_cid_data checksum=>{ offset=>0xfff8, size=>8, encoding=>5},);my %newvalue;GetOptions( "k=s"=> \$keyix, "w=s"=> \$writefile, "c=s"=> \$newcid, "i=s"=> sub { $docid=pack("H*", $_[1]); }, "s=s"=> sub { if ($_[1]=~/(\w+)=(.*)/) { $newvalue{$1}= $2; } },) or die usage();my $fn= shift || die usage();my $fh= IO::File->new($fn, "r") or die "opening: $fn: $!\n";binmode $fh;my $g_securityblock;$fh->read($g_securityblock, -s $fh) or die "reading $fn: $!\n";$fh->close();printf("0x0000 - version : %08lx\n", unpack("V", substr($g_securityblock, 0, 4)));if (length($docid)) { use integer; my $keyix= unpack('%32C*', $docid)*(unpack('%32C*', substr($docid, 12, 4))-0x13dc25bb); # 96 == 2**32 % 100 $keyix = ($keyix+96)%100; $keyix += 100 if ($keyix<0);}if (!defined $keyix) { $keyix= find_key_index(); if (!defined $keyix) { die "could not determine a key index\n"; }}sub hex_or_quoted { my $data= shift; if ($data =~ /^([[:print:]]+)\x00*$/) { return "'$1'"; } else { return unpack("H*", $data); }}my $blockix= calc_1200_block_index($keyix);printf("0x01a0 - keyindex: %s -> %d\n", unpack("H*", get_01a0_block($keyix)), $blockix);my $cidkey= get_cid_decryption_key($keyix, $blockix);printf("0x%04x - cid key : %s\n", 8*$blockix+0x1200, hex_or_quoted($cidkey));my $ciddata= get_cid_data($cidkey, 0x160, 0x20);my $cidkeylen=unpack("v", $ciddata);printf("0x0160 - cid : %04x:'%s' %s\n", $cidkeylen, substr($ciddata, 2, $cidkeylen), unpack("H*", substr($ciddata, 2+$cidkeylen)));printf("0x1c80 - lockflag: %s\n", unpack("H*", get_cid_data($cidkey, 0x1c80, 8)));my $imei= unpack("H*", get_cid_data($cidkey, 0x140, 8));$imei =~ s/(.)(.)/$2$1/g;printf("0x0140 - imei : %s\n", $imei);# for (my $ofs =0; $ofs<8; $ofs++) {# my $ixblock= des_encrypt(substr($g_securityblock, $ofs*8+0x190, 8), $keylist[($keyix+53)%100]);# printf(" 0x%04x: %s\n", 0x190+$ofs*8, unpack("H*", $ixblock));# }# # for (my $kix= 0 ; $kix<0x100 ; $kix++) {# my $key= des_encrypt(substr($g_securityblock, 8*$kix+0x1200, 8), $keylist[($keyix+77)%100]);# printf(" 0x%04x: %s\n", 0x1200+8*$kix, unpack("H*", $key));# }for (my $kix= 0 ; $kix<5 ; $kix++) { my $dd= get_cid_data($cidkey, 0x1d00+0x10*$kix, 0x10); my $de= decrypt_with_2keys($keyix, $dd, $kix); printf("0x%04x - lock %2d : %s\n", 0x1d00+0x10*$kix, $kix, hex_or_quoted($de));}printf("0x4000 - mncmcc : %s\n", unpack("H*", get_cid_data($cidkey, 0x4000, 0x20)));if ($newcid) { printf("olddata: %s\n", unpack("H*", substr($g_securityblock, 0x160, 0x20))); substr($g_securityblock, 0x160, 0x20)= encrypt_cid_data($cidkey, $newcid); printf("newdata: %s\n", unpack("H*", substr($g_securityblock, 0x160, 0x20))); my $newsum= calcsum($g_securityblock, 0xfff8); my $sumenc= decrypt_cid_checksum($keyix, pack("VV", $newsum, $newsum)); substr($g_securityblock, 0xfff8, 8)= $sumenc; printf("newsum=%08lx encsum=%s\n", $newsum, unpack("H*", $sumenc)); if ($writefile) { my $ofh= IO::File->new($writefile, "w") or die "openfile: $writefile: $!\n"; binmode $ofh; $ofh->print($g_securityblock); $ofh->close(); }}exit(0);sub find_key_index { my $sum= calcsum($g_securityblock, 0xfff8); for (my $i=0 ; $i<100 ; $i++) { my $sumdec= decrypt_cid_checksum($i, pack("VV", $sum, $sum)); my $stored= substr($g_securityblock, 0xfff8, 8); if ($sumdec eq $stored) { printf("0xfff8 - checksum: keyix=%d: %08lx - %s\n", $i, $sum, unpack("H*", $sumdec)); return $i; } } return undef;}sub get_cid_data { my ($cidkey, $ofs, $len)= @_; return decrypt_cid_data($cidkey, substr($g_securityblock, $ofs, $len));}sub get_cid_decryption_key { my ($keyix, $blockix)= @_; return des_encrypt(substr($g_securityblock, 8*$blockix+0x1200, 8), $keylist[($keyix+77)%100]);}sub decrypt_with_2keys { my ($keyix, $data, $ix)= @_; return join("", map { des_encrypt(substr($data, 8*$_, 8), $keylist[($keyix+$ix+$_)%100]) } (0..length($data)/8));}sub decrypt_cid_data { my ($cidkey, $data)= @_; return des_encrypt($data, $cidkey);}sub encrypt_cid_data { my ($cidkey, $cid)= @_; return des_decrypt(pack("va30", length($cid), $cid), $cidkey);}sub decrypt_cid_checksum { my ($keyix, $sumsum)= @_; my $key= des_encrypt(substr($g_securityblock, 0x10, 8), $keylist[($keyix+19)%100]); return des_decrypt($sumsum, $key);}# ???sub encrypt_cid_checksum { my ($keyix, $sumsum)= @_; my $key= des_encrypt(substr($g_securityblock, 0x10, 8), $keylist[($keyix+19)%100]); return des_encrypt($sumsum, $key);}sub get_01a0_block { my ($keyix)= @_; my $ixblock= des_encrypt(substr($g_securityblock, 2*8+0x190, 8), $keylist[($keyix+53)%100]);}sub calc_1200_block_index { my ($keyix)= @_; my $ixblock= get_01a0_block($keyix); return ord(substr($ixblock, 3,1));}sub calcsum { my ($data, $length)= @_; return unpack("%32V*", substr($data, 0, $length));}sub des_encrypt { my ($data, $key)= @_; #$key &= "\xfe" x 8; my $des= Crypt::DES->new($key); my $result= ""; for (my $i=0 ; $i<length($data) ; $i+=8) { $result .= $des->encrypt(substr($data,$i,8)); } return $result;}sub des_decrypt { my ($data, $key)= @_; #$key &= "\xfe" x 8; my $des= Crypt::DES->new($key); my $result= ""; for (my $i=0 ; $i<length($data) ; $i+=8) { $result .= $des->decrypt(substr($data,$i,8)); } return $result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -