لینک کوتاه مطلب : https://hsgar.com/?p=6623

چرا رجیستری ویندوز از نظر فنی بد است

استفاده از رجیستری ویندوز بسیار محبوب است غیر فنی یا کمی فنی مقررات. من فقط چند هفته را صرف مهندسی معکوس فرمت باینری به طور کامل برای ما کرده ام کندو کتابخانه و پوسته که اکنون از خواندن و نوشتن در رجیستری پشتیبانی می کند. بنابراین اکنون می توانم به شما بگویم که چرا رجیستری از نظر فنی نیز بد است.

1. این یک پیاده سازی نیمه آرسه از یک سیستم فایل است

اغلب گفته می شود که رجیستری یک “فایل یکپارچه” است، در مقایسه با پیکربندی ذخیره سازی در بسیاری از فایل های مجزا مانند، مثلاً، یونیکس در زیر /etc. این نکته را از دست می دهد: رجیستری است یک سیستم فایل مطمئناً در یک فایل ذخیره می‌شود، اما اگر بخواهید آن را در یک mount حلقه‌ای ذخیره کنید، ext3 نیز ذخیره می‌شود. فرمت باینری Registry همه جنبه های یک فایل سیستم را دارد: موارد مربوط به دایرکتوری ها، inode ها، ویژگی های توسعه یافته و غیره.

تفاوت عمده این است که این فرمت فایل سیستم رجیستری نیمه آرسی است. قالب بد ساخته شده، شکننده، مختص به اندین، کم مشخص و کند است. فرمت از انتشار تا انتشار ویندوز تغییر می کند. قطعات بدون سند هستند، ظاهراً برای خود توسعه دهندگان ویندوز (با قضاوت در مورد نمادهای اشکال زدایی NT که یک کاغذ تکثیر شده است). بخش‌هایی از قالب فضا را هدر می‌دهد، در حالی که در بخش‌های دیگر «بهینه‌سازی‌های» احمقانه برای صرفه‌جویی در تعداد انگشت شماری از بایت‌ها (به قیمت پیچیده‌تر کردن دسترسی) انجام می‌شود.

2. سلام برنامه نویسان مایکروسافت، یک حافظه خالی است نه یک فرمت فایل

این قالب اساساً تخلیه ساختارهای 32 بیتی C در یک پشته حافظه C است. این احتمالاً در ابتدا برای سرعت انجام شده است، اما قالب را برای انواع مشکلات باز می کند:

  1. می توانید موارد را در بلوک های استفاده نشده پنهان کنید.
  2. می‌توانید رجیستری‌هایی حاوی بلوک‌ها یا حلقه‌ها یا اشاره‌گرهای غیرقابل دسترسی در خارج از پشته ایجاد کنید و باعث از کار افتادن یا هنگ کردن ویندوز شوید (نقطه 3 را ببینید).
  3. این endian و کلمات خاص است.
  4. این به بسته بندی ساختار کامپایلر اصلی در حدود سال 1992 بستگی دارد.

3. اجرای خواندن/نوشتن رجیستری در ویندوز NT ضعیف است

ممکن است انتظار داشته باشید، با توجه به اهمیتی که رجیستری برای یکپارچگی Window دارد، افرادی که کدی را که آن را بارگیری می‌کند نوشتند، کمی زمان را صرف بررسی یکپارچگی فایل کرده‌اند، اما ظاهراً این کار انجام نشده است.

  1. تمام نسخه های ویندوز تست شده به سادگی بلوک هایی را که به درستی تراز نشده اند نادیده می گیرند.
  2. همینطور، ورودی‌های دایرکتوری را که به ترتیب حروف الفبا نیستند نادیده می‌گیرد (در اولین جایی که زیر شاخه‌ای به نام B > ورودی بعدی A پیدا می‌کند خواندن متوقف می‌شود).
  3. همینطور، ورودی های فایلی که حاوی انواع مختلفی از فیلدهای نامعتبر هستند را نادیده می گیرد.

نتیجه این کار این است که شما به راحتی می توانید مواردی را در باینری رجیستری که کاملاً برای ویندوز نامرئی است، پنهان کنید، اما در ابزارهای دیگر آشکار خواهد شد. از نظر ابزارهای دیگر (مانند ابزار hivex ما) ما دارند نوشتن دقیقا همان بیت هایی که ویندوز می نویسد، تا مطمئن شوید که ویندوز قادر به خواندن آن خواهد بود. هر اشتباهی که مرتکب شویم، حتی اشتباهات ظاهراً بی ضرر، در سکوت مجازات می شود.

این را با استفاده از یک فرمت سیستم فایل ثابت مقایسه کنید، جایی که همه قوانین را می‌دانند و سازگاری (مثلاً fsck/chkdsk) اهمیت دارد.

نوشتن نیز بد است، زیرا برنامه نویسان فیلدها را به درستی صفر نمی کنند، بنابراین شما بخش هایی (به ویژه هدر Registry) را خواهید یافت که حاوی بیت های تصادفی از حافظه، احتمالاً حافظه هسته، در فایل ریخته شده است. من هنوز چیز جالبی آنجا پیدا نکردم…

من همچنین رجیستری‌هایی را پیدا کردم که حاوی بلوک‌های غیرقابل دسترس هستند (و نه، ممکن است اضافه کنم، بلوک‌هایی که سعی کرده‌ام آنها را اصلاح کنم). به نظر من خیلی عجیب است که ماشین های مجازی ویندوز 7 نسبتاً تازه ایجاد شده که هیچ گونه عفونت ویروسی ندارند، دارای خرابی رجیستری قابل مشاهده باشند.

4. انواع به خوبی مشخص نشده است

هر فیلد رجیستری به صورت سطحی است تایپ شده، بنابراین REG_SZ یک رشته است و REG_EXPAND_SZ هم یک رشته است. خوبه، درسته؟ نه، زیرا آنچه به عنوان “رشته” به حساب می آید به خوبی تعریف نشده است. یک رشته ممکن است در 7 بیت ASCII یا UTF-16-LE کدگذاری شود. تنها راه برای دانستن این است که بدانید چه نسخه هایی از ویندوز از رجیستری استفاده می کنند.

رشته‌ها نیز در فیلدهای REG_BINARY (در کدگذاری‌های مختلف) ذخیره می‌شوند، اما داده‌های باینری خام نیز در این فیلدها ذخیره می‌شوند.

اگر فقط به فیلدهای رسمی مایکروسافت دسترسی دارید، خود را خوش شانس بدانید زیرا برخی از برنامه ها اصلاً خود را به انواع منتشر شده محدود نمی کنند و فقط از فیلد نوع برای هر آنچه که دوست دارند استفاده می کنند.

و داشتن REG_DWORD (البته کمی اندین) و REG_DWORD_BIG_ENDIAN و REG_QWORD چیست، اما نه REG_QWORD_BIG_ENDIAN؟

5. فرمت های تبادل به خوبی مشخص نشده اند

بخش مهمی از نصب بسیاری از درایورها، ویرایش رجیستری است و برای این کار یک قالب متنی (.REG) همراه با برنامه REGEDIT استفاده می شود. موضوع این است که فرمت .REG از نظر بک اسلش به خوبی مشخص نشده است. می توانید نمونه هایی از فایل های .REG را بیابید که هر دو را دارند:


"Name"="Value"

و


"Name"="\Value"

علاوه بر این رمزگذاری رشته ها است از نو مشخص نشده است. به نظر می رسد که تا آنجا که هر کسی می تواند بگوید به رمزگذاری فایل .REG واقعی بستگی دارد. به عنوان مثال. اگر خود فایل .REG شما UTF-16-LE است، REGEDIT تمام رشته هایی را که به این صورت تعریف می کنید رمزگذاری می کند. احتمالاً اگر فایل .REG را به سیستمی منتقل کنید که کدگذاری را تغییر می‌دهد، هنگام بارگذاری رجیستری نتایج متفاوتی دریافت خواهید کرد.

6. ترتیبات رجیستری بهم ریخته است

یه نگاهی به این بنداز نمای پزشکی قانونی کلیدهای رجیستری جالب (PDF). لیست درایوهای نصب شده؟ HKEY_LOCAL_MACHINESYSTEMMountedDevices. اما آنچه کاربر می بیند در آن ذخیره می شود HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerMountPoints2CPCVolume. مگر اینکه منظورتان دستگاه‌های USB باشد که ممکن است در لیست بالا یا داخل باشند HKEY_LOCAL_MACHINESYSTEMCurrentControlSetEnumUSBSTOR. و ورودی های آن لیست ها به هیچ وجه واضح نیستند – حاوی فیلدهای باینری غیرقابل نفوذ و مسیرهای عجیب ویندوز.

اگر شما از طریق رجیستری مرور کنید مدتی می بینید که اطلاعات غیراستاندارد و متداخلی در مکان های تصادفی ذخیره شده است. بخشی از آن پیکربندی است، بیشتر آن داده های زمان اجرا است. این خیلی دور از ذهن است /etc/progname.conf در لینوکس

7. رجیستری یک فایل سیستم است

بازگشت به نقطه 1، رجیستری یک پیاده سازی نیمه کاره و بی کیفیت از یک فایل سیستم است. مهم این است پایگاه داده نیست. باید دیتابیس باشه! می‌تواند از شاخص‌هایی بهره ببرد تا امکان جستجوی سریع را فراهم کند، اما در عوض باید به صورت دستی و خطی آن را طی کنیم.

این منجر به کلیدهای رجیستری واقعاً عجیب می شود مانند:


ControlSet001ControlCriticalDeviceDatabasepci#ven_1af4&dev_1001&subsys_00000000

که فریاد می زنند که به عنوان ستون های نمایه شده در یک پایگاه داده واقعی پیاده سازی شوند.

8. امنیت، ها ها، بیایید وانمود کنیم

با وجود این واقعیت که رجیستری فقط یک فایل ساده است که می توانید با استفاده از انواع ابزارهای خارجی (مثلاً ما) آن را تغییر دهید. پوسته کندو)، می توانید کلیدهای “غیرقابل خواندن” و “غیرقابل نوشتن” ایجاد کنید. اینها از نظر ویندوز “امن” هستند، مگر اینکه فقط فایل باینری رجیستری را مستقیماً تغییر دهید.

ویندوز همچنین از دوز ناسالم امنیت از طریق ابهام استفاده می کند. نمک های رمز عبور را در قسمت مبهم «ClassName» کلید رجیستری پنهان می کند. “امنیت” در اینجا کاملاً بر این واقعیت متکی است که برنامه پیش فرض ویندوز REGEDIT نمی تواند ClassName یک کلید را مشاهده یا ویرایش کند. هر کسی که یک ویرایشگر باینری داشته باشد می تواند این محدودیت را به طور پیش پاافتاده دور بزند.

9. رجیستری منسوخ شده است

خوب خبر خوب این است که رجیستری منسوخ شده است. خبر بد این است که ویستا دارد معرفی کرد روش دیگر، ناسازگار برای ذخیره داده های برنامه، در AppData/Local و AppData/LocalLow دایرکتوری‌ها، اما ویندوز ویستا و ویندوز 7 همچنان برای انواع داده‌های حیاتی به رجیستری متکی هستند و به نظر نمی‌رسد که این آشفتگی به این زودی‌ها از بین برود.

* * *

libguestfs در فدورا اکنون ابزارهای مورد نیاز برای مدیریت رجیستری در ماشین های مجازی ویندوز را فراهم می کند. برای جزئیات بیشتر، نگاه کنید hivexsh و virt-win-reg مستندات.

به روز رسانی

با تشکر از همه کسانی که نظر دادند. بحث بیشتری وجود دارد اینجا در Reddit و اینجا در هکر نیوز (از جمله بحث در مورد عدم دقت در آنچه نوشتم). اگر می خواهید به کد تحلیل ما نگاه کنید، این است همه اینجا در مخزن منبع ما. برای ارجاع بیشتر به فرمت باینری رجیستری، پیوندها را دنبال کنید در فایل hivex README.

لینک منبع

ارسال یک پاسخ

آدرس ایمیل شما منتشر نخواهد شد.