دسترسی به داخل emmc با چیپ کوالکام& پشت پرده 9008
در 1,2,3,4,5, قسمت این مقاله گانجانیده شده است
بخش اول
همه دسترسی ها منوط به داشتن دسترسی 9008 یا Emergency Download Mode (EDL) h است که با زدن تست پوینت مخصوص هر گوشی امکان پذیر است. اصلی ترین بوت-مد (boot-mode) دستگاه های با چیپ کوالکام (Primary Bootloader) است.
برای استفاده از این حالت، کاربران باید فایل پروگرامر یا (programmer files) دارای امضای OEM را در اختیار داشته باشند که به نظر میرسد برای دستگاههای مختلفی از این دست در دسترس عموم هستند.
نکته مهم : اینجا پروگرامر, باکس پروگرامر نیست یک فایل است و برای هر CPU فرق دارد . مثلا
LG G4 | MSM8992 | prog_emmc_firehose_8992_lite.mbn | no | 73C51DE96B5F6F0EE44E40EEBC671322071BC00D705EEBDD7C60705A1AD11248 |
Nokia 6 (d1c) | MSM8937 | prog_emmc_firehose_8937_lite.mbn | yes | 74F3DE78AB5CD12EC2E77E35B8D96BD8597D6B00C2BA519C68BE72EA40E0EB79 |
Nokia 5 | MSM8937 | prog_emmc_firehose_8937_lite.mbn | no | D18EF172D0D45AACC294212A45FBA91D8A8431CC686B164C6F0E522D476735E9 |
Nexus 6 (shamu) | APQ8084 | programmer.mbn (non-Firehose) | yes | 9B3184613D694EA24D3BEEBA6944FDB64196FEA7056C833D38D2EF683FD96E9B |
Nexus 6P (angler) | MSM8994 | prog_emmc_firehose.mbn | yes | 30758B3E0D2E47B19EBCAC1F0A66B545960784AD6D428A2FE3C70E3934C29C7A |
Moto G4 Plus | MSM8952 | programmer.mbn (non-Firehose) | no | 8D417EF2B7F102A17C2715710ABD76B16CBCE8A8FCEB9E9803733E731030176B |
OnePlus 5 (cheeseburger) | MSM8998 | <embedded in an archive> | yes | 02FFDAA49CF25F7FF287CAB82DA0E4F943CABF6E6A4BFE31C3198D1C2CFA1185 |
OnePlus 3T | MSM8996 | prog_ufs_firehose_8996_lite.elf | yes | EEF93D29E4EDDA26CCE493B859E22161853439DE7B2151A47DAFE3068EE43ABE |
prog_ufs_firehose_8996_ddr.elf | yes | A1B7EB81C61525D6819916847E02E9AE5031BF163D246895780BD0E3F786C7EE | ||
OnePlus 3 | MSM8996 | prog_ufs_firehose_8996_lite.elf | yes | 97EFF4D4111DD90523F6182E05650298B7AE803F0EC36F69A643C031399D8D13 |
prog_ufs_firehose_8996_ddr.elf | yes | C34EC1FDDFAC05D8F63EED3EE90C8E6983FE2B0E4B2837B30D8619A29633649C | ||
OnePlus 2 | MSM8994 | prog_emmc_firehose_8994_lite.mbn | yes | 63A47E46A664CCD1244A36535D10CA0B97B50B510BD481252F786177197C3C44 |
OnePlus X | MSM8974 | prog_emmc_firehose_8974.mbn | yes | 964B5C486B200AA6462733A682F9CEAD3EBFAD555CE2FF3622FEA8B279B006EE |
OnePlus One | MSM8974 | prog_emmc_firehose_8974.mbn | no | 71C4F97535893BA7A3177320143AC94DB4C6584544C01B61860ACA80A477D4C9 |
ZTE Axon 7 | MSM8996 | prog_emmc_firehose_8996_ddr.elf | no | CB06DECBE7B1C47D10C97AE815D4FB2A06D62983738D383ED69B25630C394DED |
ZUK Z1 | MSM8974 | prog_emmc_firehose_8974.mbn | no | A27232BF1383BB765937AEA1EBDEE8079B8A453F3982B46F5E7096C373D18BB3 |
ZUK Z2 | MSM8996 | prog_emmc_firehose_8996_ddr.elf | no | 3FDAF99FC506A42FCBC649B7B46D9BB8DD32AEABA4B56C920B45E93A4A7080EA |
prog_emmc_firehose_8996_lite.elf | no | 48741756201674EB88C580DF1FDB06C7B823DC95B3FC89588A84A495E815FBD4 | ||
Xiaomi Note 5A (ugglite) | MSM8917 | prog_emmc_firehose_8917_ddr.mbn | yes | 8483423802d7f01bf1043365c855885b0eea193bf32ed25041a347bc80c32d6b |
Xiaomi Note 5 Prime (ugg) | MSM8937 | prog_emmc_firehose_8937_ddr.mbn | no | 5F1C47435A031331B7F6EC33E8F406EF42BAEF9A4E3C6D2F438A8B827DD00075 |
Xiaomi Note 4 (mido) | MSM8953 | prog_emmc_firehose_8953_ddr.mbn | yes | 5D45ECF8864DBBC741FB7874F878126E8F23EE9448A3EA1EDE8E16FE02F782C0 |
Xiaomi Note 3 (jason) | SDM660 | prog_emmc_firehose_Sdm660_ddr.elf | no | 1D4A7043A8A55A19F7E1C294D42872CD57A71B8F370E3D9551A796415E61B434 |
Xiaomi Note 2 (scorpion) | MSM8996 | prog_ufs_firehose_8996_ddr.mbn | no | BF4E25AE6108D6F6C8D9218383BD85273993262EC0EBA088F6C58A04FC02903B |
Xiaomi Mix (lithium) | MSM8996 | prog_ufs_firehose_8996_ddr.elf | no | 3DB3B7FD2664D98FD16F432E8D8AD821A85B85BD37701422F563079CB64D084C |
Xiaomi Mix 2 (chiron) | MSM8998 | prog_ufs_firehose_8998_ddr.elf | no | ADEB0034FC38C99C8401DCDBA9008EE5A8525BB66F1FC031EE8F4EFC22C5A1DF |
Xiaomi Mi 6 (sagit) | MSM8998 | prog_ufs_firehose_8998_ddr.elf | no | 67A7EA77C23FDD1046ECCE7628BFD5975E9949F66ADDD55BB3572CAF9FE97AEA |
Xiaomi Mi 5s (capicorn) | MSM8996 | prog_ufs_firehose_8996_ddr.elf | no | 2DDE12F09B1217DBBD53860DD9145326A394BF6942131E440C161D9A13DC43DD |
Xiaomi Mi 5s Plus (natrium) | MSM8996 | prog_ufs_firehose_8996_ddr.elf | no | 69A6E465C2F1E2CAABB370D398026441B29B45C975778E4682FC5E89283771BD |
Xiaomi Mi 5x (tiffany) | MSM8953 | prog_emmc_firehose_8953_ddr.mbn | no | 61135CB65671284290A99BD9EDF5C075672E7FEBA2A4A79BA9CFACD70CD2EA50 |
Xiaomi Mi 5 (gemini) | MSM8996 | prog_ufs_firehose_8996_ddr.elf | no | C215AC92B799D755AF0466E14C7F4E4DC53B590F5FBC0D4633AFAFE5CECC41C3 |
Xiaomi Mi 3 (cancro) | MSM8974 | prog_emmc_firehose_8974.mbn | no | 964B5C486B200AA6462733A682F9CEAD3EBFAD555CE2FF3622FEA8B279B006EE |
Xiaomi Mi A1 (tissot) | MSM8953 | prog_emmc_firehose_8953_ddr.mbn | no | A38C6F01272814E0A47E556B4AD17F999769A0FEE6D3C98343B7DE6DE741E79C |
Xiaomi Mi Max2 (oxygen) | MSM8953 | prog_emmc_firehose_8953_ddr.mbn | no | BB5E36491053118486EBCCD5817C5519A53EAE5EDA9730F1127C22DD6C1B5C2B |
Xiaomi Redmi Note 3 (kenzo) | MSM8976 | prog_emmc_firehose_8976_ddr.mbn | no | 5C9CCCF88B6AB026D8165378D6ADA00275A606B8C4AD724FBCA33E8224695207 |
Xiaomi Redmi 5A (riva) | MSM8917 | prog_emmc_firehose_8917_ddr.mbn | no | 67D32C753DDB67982E9AEF0C13D49B33DF1B95CC7997A548D23A49C1DD030194 |
Xiaomi Redmi 4A (rolex) | MSM8917 | prog_emmc_firehose_8917_ddr.mbn | no | 7F6CE28D52815A4FAC276F62B99B5ABEB3F73C495F9474EB55204B3B4E6FCE6D |
بوت امن در چیپ های کوالکام
یه حالت کلی در این تصویر زیر به نمایش خواهیم گذاشت که ذهنیت شمارا تغییر دهد:
emmc آدرس شروع بوت-لودر اصلی رو در خودش داره که بعد از زدن دکمه پاور شریع به اجرا میشود که بوت نرمال یا حالت آماده به کار گوشی رو هدیه میکند اما اول زودی SBL با امضای دیجیتال را در حافظه داخلی (imem) بارگیری می کند و صحت آن را تأیید می کند.
این تایید صحت مرحله بسیار مهمی است .
همه PBL های استخراج شده ما 32 بیتی بودند (در aarch32 اجرا می شدند)، که در آن SBL ها یا aarch32 یا aarch64 بودند که در آن PBL مسئول انتقال است.
برخی از دستگاه ها به جای SBL دارای XBL (بوت لودر قابل توسعه) هستند. SBL, DDR را مقداردهی اولیه می کند و img دارای امضای دیجیتالی مانند ABOOT (که رابط fastboot را پیاده سازی می کند) و TrustZone بارگیری می کند و دوباره صحت آنها را تأیید می کند. گواهینامه های امضا شده دارای گواهی ریشه هستند که در سخت افزار مستقر شده اند.
سپس ABOOT صحت بوت یا recovery را تأیید می کند، “”هسته لینوکس و initramfs را از بوت یا تصاویر بازیابی بارگیری می کند. initramfs یک آرشیو cpio (gzipped) است که در هنگام شروع اولیه هسته لینوکس در rootfs (یک سیستم فایل RAM نصب شده در “/” یعنی ریشه فایل لینوکس) بارگذاری می شود. این شامل باینری init، اولین فرآیند فضای کاربر است. ABOOT خط فرمان هسته و پارامترهای initramfs را برای هسته لینوکس در “Device Tree Blob (DTB)”آماده می کند و سپس “اجرا” (اشاره گر خط اجرا) را به هسته اندروید (لینوکس) منتقل می کند.””
“” یک نکته خیلی تخصصی است که در فرآیند راه اندازی لینوکس و دستکاری هسته لینوکس به درد میخورد
واین توصیحات درمورد راه اندازی نرمال گوشی است اما اگر تست پونت بزنیم به گوشی چطور میاد بالا از لحاظ علمی باز هم مثل بالا برسی میکنیم
در این حالت، دستگاه از طریق USB خود را به عنوان Qualcomm HS-USB 9008 معرفی می کند. EDL توسط PBL فراخوانی می شود. از آنجایی که PBL مقیم ROM است، EDL نمی تواند توسط نرم افزار خراب شود(به نوعی فقط خواندنی میشود) حالت EDL خود پروتکل *Qualcomm Sahara را پیادهسازی میکند، که یک پروگرامر(firehose) با امضای دیجیتالی OEM (یک باینری ELF در دستگاههای اخیر، MBN در دستگاههای قدیمیتر) را از طریق USB، آپلود میکند روی گوشی و یک ترمینال برای اهداف ما میشود.
*یک پروتکل است
که همه این ها داخل یک img به نام pbl انجام میشود که به صورت کد هست که با زبان ++C توسعه داده شده
PBL(Primary Bootloader)
برای تأیید دانش مبتنی بر تجربی خود، قبل از آن، ما برخی از تجزیه و تحلیل اولیه در چیپ PBL ;MSM8937/MSM8917 مربوط به چیپ های مذبور انجام دادیم تا طرح آن را در یک دیدگاه سطح بالا درک کنیم. ما معتقدیم PBL های دیگر آنقدرها متفاوت نیستند. (شبه به هم هستند)
کنترل کننده بازنشانی (آدرس 0x100094) PBL تقریباً به صورت زیر است .
(برخی از کدهای شبه برای خوانایی حذف شده اند)
یک شبه کد داریم فقط برای ارضای حس کنجکاوی شما عزیزان است:
int init()
{
int (__fastcall *v5)(pbl_struct *); // r1
__mcr(15, 0, 0x100000u, 12, 0, 0);
if ( !(MEMORY[0x1940000] & 1) )
{
if ( !reset_MMU_and_other_stuff() )
infinite_loop();
memzero_some_address();
timer_memory_stuff();
init_pbl_struct();
v4 = 0;
while ( 1 )
{
v5 = *(&initVector + v4);
if ( v5 )
v3 = v5(&pbl);
if ( v3 )
pbl_error_handler("./apps/pbl_mc.c", 516, 66304, v3);
if ( ++v4 >= 0x14 )
{
while (1);
}
}
}
}
توضیح برای این کد نیازی نیست مافقط قصد تداعی بهتر این پروسه را در ذهن شما را داریم
فراخوانی پروسیجر یا img , بوت لودر ثانویه توسط PBL و مرور حالت کلی که گفتیم به صورت شبه کد برای حالت edl:
int __fastcall pbl_sense_jtag_test_points_edl(pbl_struct *pbl)
{
[...]
pbl->bootmode_reason = bootmode_reason_0;
if ( !(MEMORY[0xA601C] & 8) ) // jtag fuse
{
if ( MEMORY[0xA606C] & 0x8000 ) // check test points
{
pbl->bootmode = edl;
pbl->bootmode_reason = tp;
return 0;
}
v4 = MEMORY[0x193D100];
v5 = MEMORY[0x193D100] & 0xF;
switch ( v5 )
{
case 1:
v6 = bootmode_reason_2;
pbl->bootmode = edl;
break;
case 2:
pbl->bootmode = bootmode_80;
pbl->bootmode_reason = bootmode_reason_3;
goto LABEL_17;
case 3:
pbl->bootmode = bootmode_81;
v6 = bootmode_reason_4;
break;
default:
goto LABEL_17;
}
pbl->bootmode_reason = v6;
LABEL_17:
MEMORY[0x193D100] = v4 & 0xFFF0;
if ( pbl->bootmode_reason )
return 0;
}
v2 = (MEMORY[0xA602C] >> 1) & 7;
if ( v2 >= 8 )
pbl_error_handler("./apps/pbl_hw_init.c", 227, 262656, ((MEMORY[0xA602C] >> 1) & 7));
pbl->bootmode = v2;
return 0;
}
پرایمری بوت_لودر تا این حد کافی است.
داخل firehose چه میگذرد؟
دروافع یک ترمینال یا به عنوان دروازه عمل میکند بین کامپیوتر و گوشی که از طریف usb تمامی فرمان هایی راکه دوست داریم اجرا میکنیم مثلا حذف Mi Account یا FRP یا IMEI .
همانطور که در بالا ذکر شد،پروگرام های edl , پروتکل Qualcomm Firehose را پیاده سازی می کنند. تجزیه و و دستورات از طریق XML (از طریق USB) منتقل می شوند. برای مثال، XML زیر باعث میشود که برنامهنویس یک img بوتلودر ثانویه (SBL) جدید (که از طریق USB نیز منتقل میشود) فلش کند .
اینطوری هست xml:
<?xml version="1.0" ?> <data> <program SECTOR_SIZE_IN_BYTES="512" file_sector_offset="0" filename="sbl1.bin" label="sbl1" num_partition_sectors="1024" physical_partition_number="0" size_in_KB="512.0" sparse="false" start_byte_hex="0xc082000" start_sector="394256"/> </data>
همانطور که مشاهده می شود، تگ مربوطه که به پروگرامر دستور می دهد یک img جدید را فلش کند.
بررسی کد پروگرامر (پروگرامر Xiaomi Note 5A uglite aarch32 در این مورد) نشان می دهد که در واقع یک نوع SBL توسعه یافته است. روال اصلی آن به شرح زیر است:
int __cdecl SBLMain(pbl2sbl_struct *pbl2sbl_data)
{
sbl_struct *vSbl; // r6
[...]
SBLStart(&off_805C070, vSbl);
sub_801D0B0(off_805C078);
sub_8040A2C(vSbl);
initSBLStruct(&sblStruct, &unk_80678A0);
sub_80408F4(&sblStruct);
[...]
return callImageLoad(&sblStruct, 0x15, imageLoad);
}
pbl2sbl_data دادهای است که از PBL به SBL در انتهای تابع pbl_jmp_to_sbl منتقل میشود. sbl داده های متنی SBL را حفظ می کند، جایی که اولین فیلد آن به یک کپی از pbl2sbl_data اشاره می کند.
ImageLoad تابعی است که وظیفه بارگیری بوت لودرهای بعدی از جمله ABOOT را بر عهده دارد:
[…] حذف شده ها هستند
int __fastcall ImageLoad(sbl_struct *sbl, image_load_struct *aImageLoad)
{
[...]
loop_callbacks(sbl, aImageLoad->callbacks);
[...]
if ( imageLoad->field_14 == 1 )
{
v5 = sub_801CCDC();
uartB("Image Load, Start");
v8 = imageLoad->field_C;
if ( v8 == 1 )
{
if ( !boot_pbl_is_flash() )
{
[...]
ERROR("sbl1_sahara.c", 816, 0x1000064);
while ( 1 )
;
}
[...]
boot_elf_loader(v9, &v27);
[...]
loop_callbacks(sbl, imageLoad->callbacks2);
[...]
return result;
}
تابع ImageLoad با فراخوانی (با استفاده از روال loop_callbacks) یک سری توابع اولیه آغاز می شود:
LOAD:0805C0C8 callbacks DCD nullsub_35+1
LOAD:0805C0CC DCD boot_flash_init+1
LOAD:0805C0D0 DCD sub_801ACB0+1
LOAD:0805C0D4 DCD sub_804031C+1
LOAD:0805C0D8 DCD sub_803FF08+1
LOAD:0805C0DC DCD sub_803FCD0+1
LOAD:0805C0E0 DCD firehose_main+1
LOAD:0805C0E4 DCD sub_8040954+1
LOAD:0805C0E8 DCD clock_init_start+1
LOAD:0805C0EC DCD sub_801B1AC+1
LOAD:0805C0F0 DCD boot_dload+1
firehose main در نهایت در حلقه اصلی firehose قرار می گیرد و هرگز باز نمی گردد. جالب اینجاست که در SBL واقعی uglite، این سری از فراخوانی اولیه به صورت زیر است:
LOAD:0805B0C8 callbacks DCD nullsub_36+1
LOAD:0805B0CC DCD boot_flash_init+1
LOAD:0805B0D0 DCD sub_8018E8C+1
LOAD:0805B0D4 DCD sub_8039C80+1
LOAD:0805B0D8 DCD sub_803986C+1
LOAD:0805B0DC DCD sub_8039634+1
LOAD:0805B0E0 DCD nullsub_37+1
LOAD:0805B0E4 DCD sub_803A2B8+1
LOAD:0805B0E8 DCD clock_init_start+1
LOAD:0805B0EC DCD sub_8019388+1
LOAD:0805B0F0 DCD boot_dload+1
بنابراین، آنها فقط در پاسخ به تماس Firehose_main تفاوت دارند!
واینطوری میشود firehose میشیند روی گوشی و به عنوان ترمینال عمل میکند و ساختار داخلی نیز با زیان c/c++ ساخته شده است. است که باز هم بنویسم میتونیم فقط شبه کد بنویسیم
خیلی جالب بود نمی دونستم یه ایرانی انقدر سواد داره