post by tommy @ 26 十一月, 2017 11:28
原作來自 XDA: https://forum.xda-developers.com/mi-mix-2/how-to/guide-reverse-engineering-xiaomi-ota-t3691612
方法一不能用了, 不過方法二仍可以使用, 而且... 是目前的更新機制, 應該不容易改... 也許一直能用下去.
不知道為什麼, 原作者的 python 程式碼在我的機器上無法正常執行, 在 decrypt 那一個部份一直無法成功.
所以... 就用 php 改寫一下.
<?php
$cipher = 'rijndael-128';
$mode = 'cbc';
$miui_key = 'miuiotavalided11';
$miui_iv = '0102030405060708';
function miui_decrypt($s)
{
global $cipher, $mode, $miui_key, $miui_iv;
$td = mcrypt_module_open($cipher, '', $mode, '');
mcrypt_generic_init($td, $miui_key, $miui_iv);
$decrypted = mdecrypt_generic($td, base64_decode($s));
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$pos = strrpos($decrypted, '}');
if ($pos !== false)
return substr($decrypted, 0, $pos + 1);
return $decrypted;
}
function miui_encrypt($s)
{
global $cipher, $mode, $miui_key, $miui_iv;
$td = mcrypt_module_open($cipher, '', $mode, '');
mcrypt_generic_init($td, $miui_key, $miui_iv);
$bs = mcrypt_get_block_size($cipher, $mode);
$n = $bs - (strlen($s) % $bs);
while ($bs - (strlen($s) % $bs) != $bs)
$s .= chr($n);
$encrypted = base64_encode(mcrypt_generic($td, $s));
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $encrypted;
}
$checkurl = 'http://update.miui.com/updates/miotaV3.php';
$device_data = array(
"a" => "0", # Don't know what this is.
"c" => "7.0", # Same as 'c' above, it's the Android version.
"b" => "F", # Same as above, 'X' for weekly build.
"d" => "mido_global", # The device name, same as above, chiron for Chinese, chiron_global for global.
"g" => "00000000000000000000000000000000", # This seems to be the android_id of the device. Maybe encoded somehow.
"cts" => "0", # I don't know what this is.
"i" => "0000000000000000000000000000000000000000000000000000000000000000", # This seems to be the imei of the device, obviously encoded somehow.
"isR" => "0", # I don't know what this is.
"f" => "1", # I don't know what this is.
"l" => "en_US", # The locale.
"n" => "", # I don't know what this parameter is
"sys" => "0", # I don't know what this is.
"p" => "msm8953", # The chipset
"unlock" => "1", # 1 means bootloader is unlocked. 0 means locked.
"r" => "CN", # I don't know what this is, maybe region of device?
"sn" => "0x00000000", # Probably the serial number of the device, maybe encoded somehow.
"v" => "MIUI-V9.0.5.0.NCFMIEI", # The version of MIUI installed.
//"v" => "MIUI-V8.5.8.0.NCFMIED",
"bv" => "9", # I don't know what this is.
"id" => "", # I don't' know what this is.
);
$js = json_encode($device_data);
$postdata = "q=".urlencode(miui_encrypt($js))."&t=&s=1";
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $checkurl);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
$data = curl_exec($curl);
if ($data === false) {
echo "*** curl_exec() failed: ".curl_errno($curl)." => ".curl_error($curl)."\n";
curl_close($curl);
exit;
}
$r = miui_decrypt($data);
$result = json_decode($r);
print_r($result);
exit;
上面那個是用紅米 Note4X 國際版為例子. 找 MIUI-V9.0.5.0.NCFMIEI 的升級版本.
如果要找其他的機型, 請改 c, d, v 這三個值, c 是 Android 版本, d 是機型代碼 (國際版加上 _global), v 是版本名稱.
會列出該版本之後的版本 (如果是最新的, 就會列出目前這個版本).
所以... 我們就可以取得 V9.0.5.0.NCFMIEI 這個版本的檔名: miui_HMNote4XGlobal_V9.0.5.0.NCFMIEI_d6176de291_7.0.zip
有檔名之後, 小米的路徑規則是 http://bigota.d.miui.com/版本/檔案
所以下載的網址就是 http://bigota.d.miui.com/V9.0.5.0.NCFMIEI/miui_HMNote4XGlobal_V9.0.5.0.NCFMIEI_d6176de291_7.0.zip