Guide: Reverse-engineering Xiaomi OTA Updates to Find Unreleased Versions

louwii_fr

Member
Jun 13, 2018
7
0
0
I hope found a new way ;)

But I need help : when the phone ask mi server for a new rom, It send a request to ... with this chain for my phone : q=RMnOGd%2Be0NNG2DwH7PkO1Wsudgf7Ss0CgFCRv5iTrpWO46ODkEI%2FQ9%2B9udjXENxgdcpwRKYiiGJW6Ov39q2eOUZtP%2BhwvQ4daM2Jd0wxBkWSuNYVfRIsZZMJyaPAtxnWP6whLNUi1DE%2F3zm%2BNX947TAAwJ%2BwisR031Am8nJDsHNv%2F22dtzK3XRJNCF9j2zhdriYDs5lIfV2R1CLKN6mlBKZ8%2Br8nROK5oXd1ji%2FW%2BdsY%2BsxSoaMyR221oMQYwg%2Flxw8nUX1ZQqyBd1Qtipr7L9QKPJYnwEnyVZqw3qG6nVI%3D&t=&s=1

But I don't understand this ? Somebody can decode this ?

Thanks
That's a URI string

Code:
q = RMnOGd%2Be0NNG2DwH7PkO1Wsudgf7Ss0CgFCRv5iTrpWO46ODkEI%2FQ9%2B9udjXENxgdcpwRKYiiGJW6Ov39q2eOUZtP%2BhwvQ4daM2Jd0wxBkWSuNYVfRIsZZMJyaPAtxnWP6whLNUi1DE%2F3zm%2BNX947TAAwJ%2BwisR031Am8nJDsHNv%2F22dtzK3XRJNCF9j2zhdriYDs5lIfV2R1CLKN6mlBKZ8%2Br8nROK5oXd1ji%2FW%2BdsY%2BsxSoaMyR221oMQYwg%2Flxw8nUX1ZQqyBd1Qtipr7L9QKPJYnwEnyVZqw3qG6nVI%3D
t = 
s = 1

URL Decoded q
RMnOGd+e0NNG2DwH7PkO1Wsudgf7Ss0CgFCRv5iTrpWO46ODkEI/Q9+9udjXENxgdcpwRKYiiGJW6Ov39q2eOUZtP+hwvQ4daM2Jd0wxBkWSuNYVfRIsZZMJyaPAtxnWP6whLNUi1DE/3zm+NX947TAAwJ+wisR031Am8nJDsHNv/22dtzK3XRJNCF9j2zhdriYDs5lIfV2R1CLKN6mlBKZ8+r8nROK5oXd1ji/W+dsY+sxSoaMyR221oMQYwg/lxw8nUX1ZQqyBd1Qtipr7L9QKPJYnwEnyVZqw3qG6nVI=
I've tried different simple conversion on that string but nothing convincing...
I have no knowledge in cracking/decryption unfortunately

EDIT: that string looks a bit like a base64 encoded string, but when using base64 decode on it, it gives me
Code:
D…Œflû–”Fÿ<Ï˘’k.v˚JÕÄPëøòìÆïé„£ÉêB?CflΩπÿ◊‹`u*pD¶"àbVËΘˆ≠û9Fm?ËpΩhÕâwL1Eí∏÷},eì	…£¿∑÷?¨!,’"‘1?fl9æ5xÌ0¿ü∞äƒtflP&ÚrC∞soˇmù∑2∑]M_c€8]Æ&≥ôH}]ë‘"*7©•¶|˙ø'D‚π°wué/÷˘€˙ÃR°£2Gmµ†ƒ¬«'Q}YB¨ÅwT-äö˚/‘
<ñ'¿IÚUö∞fi°∫ùR
Which I don't know what to do with it.
 
Last edited:

geminids14

Member
Jan 16, 2018
17
29
0
Bangkok
Use this code and I get the array as follow.

That's a URI string

Code:
q = RMnOGd%2Be0NNG2DwH7PkO1Wsudgf7Ss0CgFCRv5iTrpWO46ODkEI%2FQ9%2B9udjXENxgdcpwRKYiiGJW6Ov39q2eOUZtP%2BhwvQ4daM2Jd0wxBkWSuNYVfRIsZZMJyaPAtxnWP6whLNUi1DE%2F3zm%2BNX947TAAwJ%2BwisR031Am8nJDsHNv%2F22dtzK3XRJNCF9j2zhdriYDs5lIfV2R1CLKN6mlBKZ8%2Br8nROK5oXd1ji%2FW%2BdsY%2BsxSoaMyR221oMQYwg%2Flxw8nUX1ZQqyBd1Qtipr7L9QKPJYnwEnyVZqw3qG6nVI%3D
t = 
s = 1

URL Decoded q
RMnOGd+e0NNG2DwH7PkO1Wsudgf7Ss0CgFCRv5iTrpWO46ODkEI/Q9+9udjXENxgdcpwRKYiiGJW6Ov39q2eOUZtP+hwvQ4daM2Jd0wxBkWSuNYVfRIsZZMJyaPAtxnWP6whLNUi1DE/3zm+NX947TAAwJ+wisR031Am8nJDsHNv/22dtzK3XRJNCF9j2zhdriYDs5lIfV2R1CLKN6mlBKZ8+r8nROK5oXd1ji/W+dsY+sxSoaMyR221oMQYwg/lxw8nUX1ZQqyBd1Qtipr7L9QKPJYnwEnyVZqw3qG6nVI=
I've tried different simple conversion on that string but nothing convincing...
I have no knowledge in cracking/decryption unfortunately

EDIT: that string looks a bit like a base64 encoded string, but when using base64 decode on it, it gives me
Code:
D…Œflû–”Fÿ<Ï˘’k.v˚JÕÄPëøòìÆïé„£ÉêB?CflΩπÿ◊‹`u*pD¶"àbVËΘˆ≠û9Fm?ËpΩhÕâwL1Eí∏÷},eì	…£¿∑÷?¨!,’"‘1?fl9æ5xÌ0¿ü∞äƒtflP&ÚrC∞soˇmù∑2∑]M_c€8]Æ&≥ôH}]ë‘"*7©•¶|˙ø'D‚π°wué/÷˘€˙ÃR°£2Gmµ†ƒ¬«'Q}YB¨ÅwT-äö˚/‘
<ñ'¿IÚUö∞fi°∫ùR
Which I don't know what to do with it.
<?php
define('AES_128_CBC', 'aes-128-cbc');

$q = 'RMnOGd%2Be0NNG2DwH7PkO1Wsudgf7Ss0CgFCRv5iTrpWO46ODkEI%2FQ9%2B9udjXENxgdcpwRKYiiGJW6Ov39q2eOUZtP%2BhwvQ4daM2Jd0wxBkWSuNYVfRIsZZMJyaPAtxnWP6whLNUi1DE%2F3zm%2BNX947TAAwJ%2BwisR031Am8nJDsHNv%2F22dtzK3XRJNCF9j2zhdriYDs5lIfV2R1CLKN6mlBKZ8%2Br8nROK5oXd1ji%2FW%2BdsY%2BsxSoaMyR221oMQYwg%2Flxw8nUX1ZQqyBd1Qtipr7L9QKPJYnwEnyVZqw3qG6nVI%3D';
$q_urldecode = urldecode($q);
$miui_key = 'miuiotavalided11';
$miui_iv = '0102030405060708';

$device_data = openssl_decrypt(base64_decode($q_urldecode), AES_128_CBC, $miui_key, $options=OPENSSL_RAW_DATA, $miui_iv);

print_r ("device_data = $device_data\n\n");
?>

Result
==============================================
device_data = {
"b" : "F",
"c" : "7.1.2",
"d" : "vince_global",
"f" : "1",
"id" : "",
"isR" : 0,
"l" : "fr-FR",
"n" : "",
"r" : "FR",
"sid" : "2",
"sn" : "0xc67d1d89",
"v" : "V9.5.11.0.NEGMIFA"
}
 

palexis06

Senior Member
Mar 23, 2011
98
20
0
Nice
<?php
define('AES_128_CBC', 'aes-128-cbc');

$q = 'RMnOGd%2Be0NNG2DwH7PkO1Wsudgf7Ss0CgFCRv5iTrpWO46ODkEI%2FQ9%2B9udjXENxgdcpwRKYiiGJW6Ov39q2eOUZtP%2BhwvQ4daM2Jd0wxBkWSuNYVfRIsZZMJyaPAtxnWP6whLNUi1DE%2F3zm%2BNX947TAAwJ%2BwisR031Am8nJDsHNv%2F22dtzK3XRJNCF9j2zhdriYDs5lIfV2R1CLKN6mlBKZ8%2Br8nROK5oXd1ji%2FW%2BdsY%2BsxSoaMyR221oMQYwg%2Flxw8nUX1ZQqyBd1Qtipr7L9QKPJYnwEnyVZqw3qG6nVI%3D';
$q_urldecode = urldecode($q);
$miui_key = 'miuiotavalided11';
$miui_iv = '0102030405060708';

$device_data = openssl_decrypt(base64_decode($q_urldecode), AES_128_CBC, $miui_key, $options=OPENSSL_RAW_DATA, $miui_iv);

print_r ("device_data = $device_data\n\n");
?>

Result
==============================================
device_data = {
"b" : "F",
"c" : "7.1.2",
"d" : "vince_global",
"f" : "1",
"id" : "",
"isR" : 0,
"l" : "fr-FR",
"n" : "",
"r" : "FR",
"sid" : "2",
"sn" : "0xc67d1d89",
"v" : "V9.5.11.0.NEGMIFA"
}
Great work thank you very mutch ;)
But It's not what I expected :/

---------- Post added at 06:08 PM ---------- Previous post was at 06:07 PM ----------

Anyone got it to work with miui x alpha updates ?
unfortunately not for the moment :/
 

louwii_fr

Member
Jun 13, 2018
7
0
0
<?php
define('AES_128_CBC', 'aes-128-cbc');

$q = 'RMnOGd%2Be0NNG2DwH7PkO1Wsudgf7Ss0CgFCRv5iTrpWO46ODkEI%2FQ9%2B9udjXENxgdcpwRKYiiGJW6Ov39q2eOUZtP%2BhwvQ4daM2Jd0wxBkWSuNYVfRIsZZMJyaPAtxnWP6whLNUi1DE%2F3zm%2BNX947TAAwJ%2BwisR031Am8nJDsHNv%2F22dtzK3XRJNCF9j2zhdriYDs5lIfV2R1CLKN6mlBKZ8%2Br8nROK5oXd1ji%2FW%2BdsY%2BsxSoaMyR221oMQYwg%2Flxw8nUX1ZQqyBd1Qtipr7L9QKPJYnwEnyVZqw3qG6nVI%3D';
$q_urldecode = urldecode($q);
$miui_key = 'miuiotavalided11';
$miui_iv = '0102030405060708';

$device_data = openssl_decrypt(base64_decode($q_urldecode), AES_128_CBC, $miui_key, $options=OPENSSL_RAW_DATA, $miui_iv);

print_r ("device_data = $device_data\n\n");
?>

Result
==============================================
device_data = {
"b" : "F",
"c" : "7.1.2",
"d" : "vince_global",
"f" : "1",
"id" : "",
"isR" : 0,
"l" : "fr-FR",
"n" : "",
"r" : "FR",
"sid" : "2",
"sn" : "0xc67d1d89",
"v" : "V9.5.11.0.NEGMIFA"
}
How were you able to find that out?
 

geminids14

Member
Jan 16, 2018
17
29
0
Bangkok
I don't know why the pythod code is not working in my environment (can't decrypt the result correctly), so I write the code using php to do this.

Code:
<?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.
    "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;
the above code is for Redmi Note 4X, get the current stable nightly version V9.0.5.0.NCFMIEI => miui_HMNote4XGlobal_V9.0.5.0.NCFMIEI_d6176de291_7.0.zip
How were you able to find that out?
Just implement php above quot and the result is inconsiderable:crying:
 
  • Like
Reactions: louwii_fr

Mr.frich

New member
Jun 27, 2019
3
0
0
<?php
define('AES_128_CBC', 'aes-128-cbc');

$q = 'RMnOGd%2Be0NNG2DwH7PkO1Wsudgf7Ss0CgFCRv5iTrpWO46ODkEI%2FQ9%2B9udjXENxgdcpwRKYiiGJW6Ov39q2eOUZtP%2BhwvQ4daM2Jd0wxBkWSuNYVfRIsZZMJyaPAtxnWP6whLNUi1DE%2F3zm%2BNX947TAAwJ%2BwisR031Am8nJDsHNv%2F22dtzK3XRJNCF9j2zhdriYDs5lIfV2R1CLKN6mlBKZ8%2Br8nROK5oXd1ji%2FW%2BdsY%2BsxSoaMyR221oMQYwg%2Flxw8nUX1ZQqyBd1Qtipr7L9QKPJYnwEnyVZqw3qG6nVI%3D';
$q_urldecode = urldecode($q);
$miui_key = 'miuiotavalided11';
$miui_iv = '0102030405060708';

$device_data = openssl_decrypt(base64_decode($q_urldecode), AES_128_CBC, $miui_key, $options=OPENSSL_RAW_DATA, $miui_iv);

print_r ("device_data = $device_data\n\n");
?>

Result
==============================================
device_data = {
"b" : "F",
"c" : "7.1.2",
"d" : "vince_global",
"f" : "1",
"id" : "",
"isR" : 0,
"l" : "fr-FR",
"n" : "",
"r" : "FR",
"sid" : "2",
"sn" : "0xc67d1d89",
"v" : "V9.5.11.0.NEGMIFA"
}
I believed this key is out of date now.