Bạn nào có nhu cầu tìm hiểu về hợp ngữ và các kết cấu bên trong ppc thì pm cho mình, chúng ta sẽ cùng tìm hiểu, ko nên múa rìu trên diễn đàn, mọi người cười chết.
Dưới đây là đoạn code dùng để edit cid đối với những dòng sử dụng boot loader phiên bản cũ, viết bằng perl:
#!perl -w
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:
ES;
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__
}
GetOptions(
"k=s"=> \$keyix,
"w=s"=> \$writefile,
"c=s"=> \$newcid,
"i=s"=> sub { $docid=pack("H*", $_[1]); },
) 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 =~ /^([[
rint:]]+)\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:
ES->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:
ES->new($key);
my $result= "";
for (my $i=0 ; $i<length($data) ; $i+=8) {
$result .= $des->decrypt(substr($data,$i,8));
}
return $result;
}
==> Sau khi có code này, người ta bắt đầu unlock cid, ví dụ unlock cho Wizard:
+ pdocread -n 1 0 0x10000 cidblock.nb
+ perl typhooncidedit.pl cidblock.nb
+ perl typhooncidedit.pl cidblock.nb -c newcid -w modifiedcidblock.nb
+ pdocwrite -n 1 modifiedcid.nb 0 0x10000
==> cid-unlocking
Dựa vào đó ta có thể tìm hiểu về cách unlock cid của mọi người, với dòng máy chúng ta đang tìm hiểu thì boot loader phiên bản cao hơn nhiều.
Mình sẽ ko bàn về vấn đề này nữa, Bạn nào có nhu cầu và chung sở thích với mình thì pm riêng cho mình, mình sẽ cố gắng giúp trong khả năng có thể, thanks