
تستخرج هذه الأداة وتعرض البيانات من ميزة "الاسترجاع" في ويندوز 11، مما يوفر طريقة سهلة للوصول إلى معلومات حول لقطات نشاط جهاز الكمبيوتر الخاص بك.
Breaking Windows Recall. Again.
image
عندما أعادت Microsoft تصميم Recall باستخدام VBS enclaves وتشفير AES-256-GCM ومصادقة Windows Hello ومضيف Protected Process Light، كانت الرسالة واضحة: البيانات محصورة في خزنة.
الخزنة متينة. لكن شاحنة التوصيل ليست كذلك.
AIXHost.exe، العملية التي تعرض الجدول الزمني لـ Recall، لا تحتوي على PPL أو AppContainer أو تطبيق سلامة الكود. أي عملية تعمل كمستخدم مسجل الدخول يمكنها حقن كود فيها واستدعاء نفس واجهات COM API التي تستخدمها واجهة المستخدم المشروعة. بمجرد أن يوثق المستخدم باستخدام Windows Hello، تتدفق لقطات الشاشة المفكوكة والنص المستخرج من OCR والبيانات الوصفية عبر AIXHost.exe ككائنات COM حية. يجلس TotalRecall Reloaded داخل تلك العملية ويستخرج كل شيء.
لا يتطلب صلاحيات المسؤول. مستخدم عادي. لا استغلال kernel. لا تجاوز تشفير. مجرد استدعاءات COM.
TotalRecall Reloaded يتكون من ملفين: محقن (totalrecall.exe) و DLL حمولة (totalrecall_payload.dll).
يجد المحقن AIXHost.exe عبر CreateToolhelp32Snapshot، ويخصص ذاكرة في الهدف باستخدام VirtualAllocEx، ويكتب مسار DLL باستخدام WriteProcessMemory، ويطلق مؤشر ترابط عن بعد يشير إلى LoadLibraryW. حقن DLL كلاسيكي. لا شيء معقد، لأن لا شيء معقد مطلوب. AIXHost.exe لا يحتوي على أي حماية ضده.
يعمل هذا من مستخدم عادي. لا رفع صلاحيات، لا SeDebugPrivilege. يسمح DACL الافتراضي لنظام Windows بعمليات المستخدم نفسه بالوصول الكامل لبعضها البعض. تم التحقق: يعمل الرمز المميز بمستوى إلزامي Medium مع BUILTIN\Administrators مضبوطًا على deny-only.
لن يفك تشفير VBS enclave أي شيء بدون Windows Hello. لا يتجاوز الأداة ذلك. بل تجبر المستخدم على القيام بذلك، أو تركب بصمت عندما يفعل المستخدم ذلك، أو تنتظر حتى يفعل المستخدم ذلك.
يقوم --launch بمحاكاة Win+J عبر keybd_event، اختصار لوحة المفاتيح الذي يفتح الجدول الزمني لـ Recall. يرى المستخدم موجه Hello (وجه، بصمة إصبع، أو PIN)، يوثق، ويبدأ الـ enclave في تقديم البيانات المفكوكة. من منظور المستخدم، فتحت Recall بشكل طبيعي فقط. من منظورنا، الحمولة موجودة بالفعل بالداخل، تنتظر.
وضع --stealth هو الوضع الصامت تمامًا. يعمل كالتالي:
AIXHost.exe (يعمل دائمًا) ويصحح DiscardDataAccess بحيث يصبح no-opAIXHost.exe ويعاد تشغيله. تكتشف الأداة إعادة التشغيل وتعيد الحقن في العملية الجديدةaihost.exe (تم منع الإلغاء). يبدأ الاستخراج فورًا--wait هو النظير السلبي لـ --launch. بدلاً من محاكاة Win+J، تبقى الأداة خاملة بينما يفتح المستخدم Recall بنفسه — من شريط المهام، اختصار، أو أي مسار آخر. عندما يظهر AIXHost.exe ويكمل المستخدم Hello بشكل طبيعي، يتم حقن الحمولة ويبدأ الاستخراج. مفيد على جهاز يتم مراقبته، أو عندما تحتاج جلسة Recall إلى أن تبدو بالكامل من بدء المستخدم بدون إدخال لوحة مفاتيح اصطناعي.
بمجرد الدخول إلى AIXHost.exe، تقوم الحمولة بتهيئة شقة COM باستخدام CoInitializeEx(COINIT_APARTMENTTHREADED) وإعداد توجيه هوية الوكيل باستخدام CoSetProxyBlanket(EOAC_DYNAMIC_CLOAKING). هذا أمر بالغ الأهمية. بدون الإخفاء الديناميكي، لا يحمل وكيل COM الهوية الموثقة إلى الخادم.
يتبع الاستخراج نفس المسار الذي تستخدمه واجهة المستخدم المشروعة لـ Recall:
تهيئة enclave: يؤدي DataManager.Load() إلى تحميل مفتاح enclave. يقوم DataStoreManager.DecryptDatabase() (الفتحة 37) بإعداد عروض مفكوكة. تتحقق الحمولة من DataManager.DataStatus حتى يعيد 3 (مفكوك).
تعداد الكيانات: يقوم MemoryEntityStatics.GetLightMemoryItemsBefore() (الفتحة 9) بإرجاع متجه من مراجع كيانات خفيفة. كل منها يحمل معرف سياق في الإزاحة +8. على جهاز نموذجي، يعيد هذا مئات الكيانات التي تغطي أيامًا أو أسابيع من النشاط.
استخراج لكل كيان: لكل معرف سياق، تقوم الحمولة بتحميل الكيان الكامل عبر ContextEngine2.TryGetEntityForId() (الفتحة 6)، وتفكيكه عبر IEntityWrapper (الفتحة 6)، و QueryInterface إلى IMemoryEntity. من هناك:
TryGetBitmapCaptureAsync() (الفتحة 19) . إلى ، استدعاء للحصول على WIC bitmap، تشفير كـ PNG عبر .كل استدعاء ملفوف بـ __try/__except لأن خطأ وصول واحد على استدعاء وكيل COM يقتل قناة RPC بشكل دائم إلى aihost.exe. لا يوجد استرداد. سيتعين عليك إعادة تشغيل AIXHost.exe. تلتقط معالجات SEH الأعطال من أنواع المعاملات الخاطئة وتبقي الجلسة حية.
تعمل عدة عمليات بدون أي مصادقة Hello:
استخراج لقطة الشاشة: يعرض RecallPrivacyIndicatorSettings (CLSID {42C63551-...}) GetRecentCaptureThumbnail(width, height) في الفتحة 13. اسم الطريقة يقول "thumbnail" لكن الخادم لا يفرض حدًا للدقة. تمرير 3840x3840 يعيد أحدث لقطة Recall بدقة كاملة. يتم تحويل نتيجة IRandomAccessStream إلى IStream عبر CreateStreamOverRandomAccessStream (shcore.dll) وتفريغها كـ BMP.
تدمير البيانات: يمسح IDataStoreManager::DeleteEvents() (الفتحة 12) سجل الالتقاط بالكامل. لا معاملات، لا مصادقة. أكد تحليل Ghidra: معالج الحذف في FUN_1802ddd10 يحتوي على صفر استدعاءات لوظيفة بوابة التفويض. لم يتم توصيل فحص المصادقة مطلقًا.
الكشف عن البيانات الوصفية: مسارات التخزين (بما في ذلك GUID UKP الخاص بالمستخدم)، حجم قاعدة البيانات، سياسة الاحتفاظ، حالة الالتقاط، ومعرف سياق أحدث التقاط كلها قابلة للقراءة بدون مصادقة عبر IDataStoreManagerStatics و RecallPrivacyIndicatorSettings.
image``` totalrecall.exe --launch Open Recall, trigger Hello, extract everything totalrecall.exe --stealth Silent extraction (patches auth revocation, waits) totalrecall.exe --wait Wait for user to manually open Recall totalrecall.exe --preauth Grab latest screenshot + settings (no Hello) totalrecall.exe --search "password" Search OCR text in latest extraction totalrecall.exe --destroy Wipe all Recall data (confirmation required, no Hello)
| الوضع | مطلوب توثيق | ما يفعله |
|------|:---:|-------------|
| `--launch` | مرحبا | محاكاة Win+J، يصادق المستخدم، استخراج كامل |
| `--stealth` | سلبي | يصحح إلغاء التوثيق، ينتظر حتى يصادق المستخدم على Recall، يستخرج بصمت |
| `--wait` | مرحبا | انتظار فتح المستخدم لتطبيق Recall بشكل طبيعي، ثم استخراج |
| `--preauth` | **لا** | أحدث لقطة شاشة + جميع الإعدادات |
| `--search` | لا | بحث نصي OCR غير حساس لحالة الأحرف عبر أحدث استخراج |
| `--destroy` | **لا** | `DeleteEvents()`، لا رجعة فيه، يتطلب كتابة DESTROY للتأكيد |
### مثال الإخراج
**`--stealth` (التشغيل الأول، انتظار المستخدم):**```
[+] Target: AIXHost.exe PID 8648 (stealth mode)
[*] Patching auth revocation...
[+] Waiting for Recall session...
[+] Recall session detected
[*] Waiting for user to close Recall...
[*] Recall closed, waiting for AIXHost to respawn...
[+] Extracting from AIXHost PID 26208
[+] Payload active
[*] Extracting
[##############################] 384/384 entities
EXTRACTION COMPLETE 6 min 51 sec
Screenshots 192 328.8 MB
OCR Text 184 535.2 KB
Metadata (CSV) 384 97.4 KB
--stealth (تشغيل لاحق، جلسة مخبأة):```
[+] Target: AIXHost.exe PID 27532 (stealth mode)
[] Patching auth revocation...
[+] Waiting for Recall session...
[+] Cached session found, extracting...
[] Extracting
[##############################] 398/398 entities
**`--launch`:**```
[+] Target: AIXHost.exe PID 14636 Memory 60 MB
[*] Triggering Recall via Win+J...
[*] Waiting for Hello authentication authenticating
[+] Recall ready PID 14636 Memory 242 MB
[*] Extracting
[##############################] 212/212 entities
EXTRACTION COMPLETE 3 min 59 sec
Screenshots 104 184.0 MB
--preauth (لا يتطلب Hello):```
[+] Target: AIXHost.exe PID 27532 (pre-auth mode)
[*] Injecting payload (pre-auth only)...
[+] Payload active
PRE-AUTH EXTRACTION COMPLETE 0 min 1 sec
Screenshot 4K (3840x2464) 36.1 MB
Settings Storage Path C:\Users<user>\AppData\Local\CoreAIPlatform.00\UKP{...} Storage Size 178.3 MB Capture Count 0 Retention Days 90
**`--search`:**```
Searching for: "password"
In: extraction_20260406_152736
[1] === [12] ctxId=90443 Settings | Chrome ===
Saved passwords and passkeys
[2] === [47] ctxId=91201 inbox | Thunderbird ===
Your temporary password has been reset
extraction_20260404_143052/ screenshots/ Full-resolution decrypted PNGs screenshots/*.txt Per-image OCR text thumbnails/ Thumbnail PNGs (fallback when full screenshot unavailable) ocr_text.txt Combined OCR text for all captures recall_data.csv Structured metadata settings.txt Storage path, size, retention, capture state latest_capture_4k.bmp Pre-auth screenshot of most recent capture extraction.log Detailed extraction log with timing
## بناء
**المتطلبات:** Visual Studio مع أدوات C++ لـ ARM64، وWindows 11 ARM64 مع تمكين Recall.```
make.bat
ينتج totalrecall.exe و totalrecall_payload.dll. يجب أن يكون كلاهما في نفس الدليل عند التشغيل.
VTL1 (Secure World) +--------------------------------------------------+ | VBS Enclave: AES-256-GCM, sealed keys | | snapshot_support.dll / storage_support.dll | | Keys never leave here. Crypto is sound. | +--------------------------------------------------+ ^ CallEnclave | VTL0 (Normal World) +--------------------------------------------------+ | aihost.exe (PPL, Signer=5) | | +-- Microsoft.Windows.AI.Platform.dll (6.9 MB) | | 44 methods on IDataStoreManager alone | | Enclave bridge. Protected. Can't touch it. | | | | AIXHost.exe (NO PROTECTION) | | +-- Baker.dll: OCR, NER, AI classification | | +-- Receives decrypted data for rendering | | +-- CreateRemoteThread = game over | +--------------------------------------------------+
التسلسل الهرمي للمفاتيح: Hello -> NGC ECDH P-384 (مدعوم من TPM) -> مصادقة متبادلة VTL1 -> مواد المفاتيح المختومة في الإينكليف -> لكل صفحة AES-256-GCM مع nonces عشوائية و AAD رقم الصفحة. ست طبقات من اشتقاق المفاتيح. التشفير متين حقًا.
المشكلة هي ما يحدث بعد فك التشفير. النص العادي يعبر إلى `AIXHost.exe`، وهي عملية غير محمية وقابلة للحقن وتعمل تحت نفس المستخدم. الإينكليف لا يميز بين `Baker.dll` والكود المحقون. لا يمكنه ذلك.
---
## النتائج الرئيسية
### حد الثقة ينتهي مبكرًا جدًا
يذكر [مدونة بنية Windows](https://blogs.windows.com/windowsexperience/2024/09/27/update-on-recall-security-and-privacy-architecture/) من مايكروسوفت أن "العمليات خارج VBS Enclaves لا تتلقى أبدًا وصولًا مباشرًا إلى لقطات الشاشة أو مفاتيح التشفير" وأن التصميم "يقيد محاولات البرامج الضارة الكامنة التي تحاول ركوب موجة مصادقة المستخدم لسرقة البيانات."
في الممارسة العملية، يتلقى `AIXHost.exe` كل لقطة شاشة مفكوكة التشفير ونتيجة OCR ككائن COM حي. لا يوجد تحقق لكل متصل داخل العملية. لا يوجد فحص "هل أنت Baker.dll؟". إذا كنت داخل العملية، فأنت موثوق. الحد الأمني هو إينكليف VBS و PPL، وليس عملية العرض. البيانات المفكوكة تبعد مكالمة `CreateRemoteThread` واحدة عن أي تطبيق بنفس المستخدم.
### تجاوز التحكم في الوصول لـ IResponse4
ثغرة تفويض مباشرة.
عندما تستدعي `ContextDataSource.Search()` وتحصل على `IResponse`، المسار الطبيعي هو `IResponse.get_Items()` (الفتحة 9) للحصول على النتائج. في جلسة جديدة، يُرجع هذا `0x80005473`، وهو رمز خطأ مخصص لـ Recall. الخادم يرفض الاستدعاء عمدًا. `IResponse2.ItemsAfterIndex()` يُرجع نفس الخطأ. التحكم في الوصول يعمل.
لكن كائن `IResponse` ينفذ أربعة إصدارات من الواجهة. `IResponse4.get_UnfilledItems()` (الفتحة 9 على IID مختلف) يُرجع نفس مجموعة البيانات الأساسية دون أي فحص للوصول.```
IResponse.get_Items() -> 0x80005473 (ACCESS DENIED)
IResponse2.ItemsAfterIndex() -> 0x80005473 (ACCESS DENIED)
IResponse4.get_UnfilledItems() -> S_OK (all entities returned)
Same data. Different interface version. No authorization. The method was intended for internal lazy-loading in the search pipeline. The security review caught get_Items and ItemsAfterIndex, but missed get_UnfilledItems. This is the pattern that makes security engineering hard: the check exists on one code path (which means someone decided it was needed), and is missing on another.
From those items, each entity's context ID leads to ContextEngine2.TryGetEntityForId(), which loads the full entity with screenshots, OCR, and metadata. The enclave decrypts everything on request.
عندما يغلق المستخدم نافذة Recall، يقوم Baker.dll باستدعاء IDataProtectionManager3::DiscardDataAccess() لإلغاء صلاحية الوصول إلى البيانات بشكل صريح في aihost.exe. لهذا السبب لا يستمر المصادقة بعد جلسة Recall العادية للمستخدم: يقوم Baker.dll بتنظيف نفسه.
تجاوز: يمكن للكود المحقون داخل AIXHost.exe تصحيح جدول vtable الخاص بـ COM لاستبدال DiscardDataAccess (الفتحة 8) بوظيفة لا تفعل شيئًا (no-op). استدعاء واحد لـ VirtualProtect، كتابة واحدة للمؤشر. عندما يغلق المستخدم Recall، يستدعي Baker.dll الفتحة المعدلة، لا يحدث شيء، ويظل الإذن نشطًا في aihost.exe. أي مثيل لاحق من AIXHost.exe يرث الإذن المخبأ بصمت.
عمليًا، يقوم --stealth بنشر التصحيح داخل AIXHost.exe (الذي يعمل دائمًا) وينتظر. في المرة التالية التي يفتح فيها المستخدم Recall ويغلقه بشكل طبيعي، يتم قمع التنظيف ويظل إذن الوصول إلى البيانات نشطًا. تكتشف الأداة الوصول، وتتعامل مع إعادة تشغيل عملية AIXHost عبر الحقن التلقائي (إعادة التصحيح لكل مثيل جديد)، وتستخرج كل شيء بصمت. التصحيح خاص بكل عملية وكل تشغيل: فهو يحمي جلسة الاستخراج الحالية. يعود استخدام Recall اللاحق بعد خروج الأداة إلى السلوك الطبيعي.
IDataStoreManager::DeleteEvents() يمسح سجل الالتقاط بالكامل دون Windows Hello. أكدت Ghidra: معالج الحذف لا يحتوي على أي استدعاءات لوظيفة بوابة المصادقة. لم يتم توصيل فحص المصادقة أبدًا في مسار الحذف. يمكن للمهاجم الذي لا يستطيع قراءة البيانات تدميرها على أي حال. مضاد للأدلة الجنائية من مستخدم عادي.
RecallPrivacyIndicatorSettings.GetRecentCaptureThumbnail يعيد أحدث لقطة Recall بدقة الصورة التي تطلبها. الطريقة مخصصة لمؤشر الخصوصية الصغير في شريط المهام. لم يقيد أحد الدقة. يمكن لأي عملية من نفس المستخدم التقاط ما كان على الشاشة آخر مرة بصمت، دون حاجة إلى Hello.
GetWindowCaptureCount (الفتحة 26) يعيد E_ACCESSDENIED بدون Hello. لكن GetSecureStorageInfo (الفتحة 27) يعيد بنية StorageInfo تحتوي على نفس البيانات بالضبط، بدون مصادقة. تحتوي البنية على NumberOfItems (عدد الالتقاطات) و Size (إجمالي مساحة التخزين المشفرة بالبايت). يمكن للمهاجم مراقبة ذلك لتتبع نشاط Recall في الوقت الفعلي دون أي مصادقة.
بمجرد اكتمال Hello، يتم تخزين حالة المصادقة مؤقتًا في aihost.exe (PPL) طوال جلسة Windows. لا يؤدي قتل وإعادة تشغيل AIXHost.exe إلى مسحها. يمكن للمهاجم انتظار المستخدم لفتح Recall بشكل طبيعي، ثم استخراج البيانات بصمت بعد ساعات. إعادة استخراج غير محدودة بدون مطالبات إضافية، بدون نوافذ مرئية، بدون علم المستخدم.
Recall لا يلتقط لقطات شاشة فقط. بل يبني ملفًا سلوكيًا شاملاً لكل ما تفعله على حاسوبك. كل بضع ثوانٍ، يلتقط لقطة شاشة، ويشغل OCR وتصنيف ذكاء اصطناعي (من المفترض)، ويخزن النتيجة في قاعدة بيانات SQLite مشفرة.
كل ما يلي مؤكد من مصدرين مستقلين: البيانات الوصفية الخاصة لـ WinRT (Microsoft.Windows.AI.Platform.winmd، محللة عبر cppwinrt.exe) وثنائي enclave VBS (storage_support.dll، الذي يحتوي على مخطط قاعدة البيانات الكامل في سلاسل نصية عادية).
ملاحظة: أسماء الحقول أدناه مؤكدة من البيانات الوصفية لـ WinRT وسلاسل ثنائي enclave. الأوصاف حول ما يحتويه كل حقل مستنتجة من أسماء API وأنواعها، ولم يتم التحقق منها ديناميكيًا جميعها في وقت التشغيل.
ملاحظة: نفس التحذير أعلاه. أسماء الفئات والتعدادات مسرودة من البيانات الوصفية لـ WinRT وسلاسل DLL enclave؛ الأوصاف حول ما تمثله مستنتجة من الأسماء والسياق ولم يتم التحقق منها ديناميكيًا لكل إدخال.
فوق الالتقاط الخام، يقوم Recall بتشغيل تصنيف الذكاء الاصطناعي الذي ينتج:
PersonName، Organization، Product، Address، Location، DateTime، Event، Duration، WebUrl، EmailAddress. كل منها مستخرج من نص OCR مع موضع المصدر.Topic، Person، Emoji، App، FileKind، ، ، ، ، ، ، ، ، ، ، ، ، ، ، ، ، ، . كل منها مع درجات ثقة ومربعات إحاطة اختيارية.كل بضع ثوانٍ، تقوم خدمة الالتقاط في Recall بتقييم 12 سياسة قبل أن تقرر أخذ لقطة شاشة:
GameModeActive, BatterySaverActive, UserActivityIdle, UserPresenceIdle, StorageLow, PrivateWindow, BlockedByContentProtection, BlockedAppId, BlockedExecutable, BlockedURL, BlockedContentFilePath, BitLockerDisabled
إذا لم يتم تشغيل أي من هذه السياسات، فإنها تلتقط. بنية الإدخال لكل التقاط (من البيانات الوصفية لـ WinRT):``` WindowData { WindowId, Foreground, Title, Bounds, Minimized, PrivateState, InputScopePrivacy AppData { AppUserModelId, ProcessPath, IconUri, AppName, TileId RemoteClient, IsBrowserWindow } RestoreData { WebUrl, FilePath, ActivationUri, ActivityId, WebIconUri FileObjectId, VolumeId // NTFS persistent file identifiers SensitivityLabelData { State, Labels } } }
### قاعدة البيانات
قاعدة البيانات الرئيسية (`ukg.db`) تستخدم SQLite SEE مع تشفير AES-256-GCM. تم تأكيد المخطط من `storage_support.dll` (ثنائي بيئة VBS الذي يحتوي على عبارات CREATE TABLE بنص واضح):
**الجداول الأساسية (17):**```
WindowCapture Id, Name, ImageToken, IsForeground, WindowId, WindowBounds,
WindowTitle, Properties, IsProcessed, Retry, ActivationUri,
ActivityId, FallbackUri, TimeStamp, DwellTime
WindowCaptureAppRelation WindowCaptureId, AppId, IsBackground
WindowCaptureWebRelation WindowCaptureId, WebId, IsBackground
WindowCaptureFileRelation WindowCaptureId, FileId
WindowCaptureTopicRelation WindowCaptureId, TopicId, Score (float)
WindowCaptureTextIndex FTS5 virtual table (WindowCaptureId, WindowTitle, OcrText)
App Id, WindowsAppId, IconUri, Name, Path, TileId, Properties
Web Id, Domain, Uri, IconUri, Properties
File Id, Path, Name, Extension, Kind, Type, ObjectId, VolumeId
Topic Id, Title, Properties
ScreenRegion Id, WindowCaptureId, RegionKind, OcrText, Bounds
AppDwellTime Id, WindowsAppId, HourOfDay, DayOfWeek, HourStartTimestamp, DwellTime
WebDomainDwellTime Domain, HourOfDay, DayOfWeek, HourStartTimestamp, DwellTime
SearchHistory SessionId, CorrelationId, TimeStamp, Kind, Text, Language
SearchFeedback SessionId, CorrelationId, TimeStamp, Kind, Text, Language,
ItemChosenEventId, FeedbackType
IdTable NextId
_MigrationMetadata Id, Version
فهرس البحث الدلالي (SemanticTextStore.sidb / SemanticImageStore.sidb):``` si_items Core embedding storage si_embedding_metadata Embedding type and source mapping si_diskann_graph DiskANN approximate nearest neighbor graph si_diskann_references Graph edge references si_diskann_config Index configuration si_diskann_info Index statistics si_application_values Application-level settings
خلال يوم عمل نموذجي، تتراكم مئات اللقطات. فترة الاحتفاظ الافتراضية هي 90 يومًا مع حد تخزين 75 جيجابايت. كل بريد إلكتروني تم فتحه، كل مستند تم تحريره، كل موقع ويب تم زيارته، كل أمر طرفية على الشاشة، كل محادثة مراسلة مرئية. جميعها تمت معالجتها بواسطة OCR، واستخراج الكيانات، وتصنيف المواضيع، وفهرستها دلاليًا.
حياتك الرقمية بأكملها، مفهرسة وقابلة للبحث. كما هو مقصود.
---
## ما الذي فعلته مايكروسوفت بشكل صحيح
الـ VBS enclave صلب للغاية. المواد الأساسية لا تغادر VTL1 أبدًا. تشفير AES-256-GCM لكل صفحة مع nonces عشوائية صحيح نصيًا. حماية PPL لـ `aihost.exe` فعالة، النواة تمنع الحقن. CFG شامل على ARM64. استعلامات SQL معلمة بالكامل (عشرة حمولات حقن، تأثيرات جانبية صفرية). نموذج المصادقة عديم الحالة وخالٍ من السباق (آلاف الفحوصات، لا تجاوزات).
المشكلة الأساسية ليست في التشفير، أو الـ enclave، أو المصادقة، أو PPL. إنها إرسال المحتوى المفكوك تشفيره إلى عملية غير محمية للعرض. باب الخزنة من التيتانيوم. الجدار المجاور له من الحوائط الجافة.
---
## الإفصاح المسؤول
تم الإفصاح عن هذا البحث بمسؤولية إلى مركز استجابة الأمان من مايكروسوفت (MSRC).
### الجدول الزمني
| التاريخ | الحدث |
|------|-------|
| 2024-06-07 | تم إصدار [TotalRecall](https://github.com/xaitax/TotalRecall) الأصلي (Recall قبل التشفير) |
| 2024-06-13 | تؤجل مايكروسوفت إطلاق Recall، وتعلن عن إعادة تصميم مع VBS enclaves |
| 2025-04 | إعادة إطلاق Recall مع VBS enclaves، التشفير، مصادقة Hello |
| 2026-03-06 | تقديم تقرير MSRC: شرح كامل، كود مصدري، تعليمات بناء |
| 2026-03-09 | يفتح MSRC القضية 109586، الحالة: مراجعة / إعادة إنتاج |
| 2026-03-27 | MSRC: "فريق الهندسة في المرحلة النهائية من التحقيق" |
| 2026-04-03 | يغلق MSRC القضية على أنها **ليست ثغرة**: "تعمل ضمن التصميم الأمني الموثق الحالي" |
| 2026-04-09 | الإصدار العام لـ TotalRecall Reloaded |
### موقف مايكروسوفت
بعد المراجعة مع فرقهم الهندسية، قرر MSRC أن "السلوك الذي لوحظ يعمل ضمن التصميم الأمني الحالي الموثق لـ Recall" وأن "أنماط الوصول الموضحة متسقة مع الحماية المقصودة والضوابط الحالية." واستشهدوا [بمدونة الهندسة المعمارية](https://blogs.windows.com/windowsexperience/2024/09/27/update-on-recall-security-and-privacy-architecture/) الخاصة بهم، وتحديدًا أن التصريح "يقيد محاولات البرامج الضارة الكامنة التي تحاول الركوب مع مصادقة المستخدم لسرقة البيانات" وأن "العمليات خارج VBS Enclaves لا تتلقى أبدًا وصولًا مباشرًا إلى اللقطات أو مفاتيح التشفير ولا تتلقى سوى البيانات التي يتم إرجاعها من الـ enclave بعد التصريح."
أغلقت القضية على أنها ليست ثغرة.
نتائج ما قبل المصادقة الموثقة هنا (تدمير البيانات غير المصادق عليه، استخراج لقطات الشاشة) تم اكتشافها خلال متابعة البحث بعد إغلاق القضية.
---
## البيئة المختبرة
| | التفاصيل |
|---|---|
| **نظام التشغيل** | Windows 11 25H2 (Build 26300.8155) |
| **الهندسة المعمارية** | ARM64 |
| **AIXHost.exe** | v2126.7602.0.0 |
| **الامتياز** | مستخدم عادي (تكامل متوسط، بدون رفع صلاحيات) |
---
## الأعمال السابقة
- [TotalRecall](https://github.com/xaitax/TotalRecall) (يونيو 2024)، الأداة الأصلية بلغة Python لـ Recall قبل التشفير
- [تحليل Kevin Beaumont](https://doublepulsar.com/recall-stealing-everything-youve-ever-typed-or-viewed-on-your-own-windows-pc-is-now-possible-da3e12e9465e)، البحث الذي بدأ كل شيء
## الشكر والتقدير
شكرًا [Jeff McJunkin](https://x.com/jeffmcjunkin) و [Kevin Beaumont](https://cyberplace.social/@GossiTheDog) على الاختبار والتحقق.
---
**Alexander Hagenah ([@xaitax](https://x.com/xaitax))**
SoftwareBitmapQueryInterfaceISoftwareBitmapNativeGetData(IID_IWICBitmap)IWICBitmapEncoderContextEngine2.TryGetMemoryEntityDetailsForIdAsync() (الفتحة 8) تفاصيل الكيان. QI إلى IMemoryEntityDetails من أجل OcrLines (الفتحة 7)، و IMemoryEntityDetails2 من أجل كيانات النص NER (أشخاص، بريد إلكتروني، عناوين)، و IMemoryEntityDetails4 من أجل أوصاف نشاط AI.جولات إعادة المحاولة: يملأ Baker.dll (مكتبة واجهة Recall) ذاكرة التخزين المؤقت لـ ContextEngine بشكل غير متزامن. بعد المرور الأولي، تضخ الحمولة رسائل Windows لمدة 3 ثوانٍ (حلقة PeekMessage/DispatchMessage) وتعيد المحاولة لأي كيانات لم تكن متاحة. كل جولة تنتج عادةً حوالي 12 كيانًا إضافيًا. حتى 10 جولات إعادة محاولة.
| البيانات | المصدر | ما تحتويه |
|---|
| لقطة الشاشة | TryGetBitmapCaptureAsync | صورة PNG كاملة الدقة لشاشتك بأكملها |
| لقطة الشاشة المصغرة | TryGetBitmapCaptureAsync(Size, Mode) | لقطة شاشة بأي دقة مطلوبة مع استيفاء قابل للتكوين |
| الصورة المصغرة | TryGetBitmapCaptureThumbnailAsync | صورة معاينة بدقة أقل |
| نص OCR | OcrText (Details3) | نص OCR كامل موحد لكل ما هو مرئي على الشاشة |
| أسطر OCR | OcrLines (Details1) | أسطر OCR فردية كسلاسل منفصلة |
| كلمات OCR | OcrWord struct | كل كلمة مع مربع إحاطة دقيق بالبكسل (RectInt32) |
| عنوان النافذة | get_Title | نص شريط العنوان للنافذة النشطة |
| التطبيق | get_AppDisplayName | أي تطبيق كان في التركيز (Chrome, Outlook, Terminal, ...) |
| معرف نموذج التطبيق | get_AppUserModelId | سلسلة هوية تطبيق UWP/Win32 |
| مسار العملية | get_ProcessPath | مسار الملف التنفيذي الكامل (C:\Program Files\...\chrome.exe) |
| أيقونة التطبيق | IMemoryEntity2.IconUri | مسار أيقونة التطبيق |
| عنوان URL | get_WebUrl | عنوان URL الكامل في شريط عنوان المتصفح |
| المجال | get_WebDomain | مجال الموقع |
| فافيكون | get_WebIconUri | عنوان URL لأيقونة الموقع النشط |
| مسار الملف | get_FileUri | المستند النشط أو مسار الملف |
| موضع النافذة | get_WindowBounds | إحداثيات الشاشة الدقيقة بالبكسل: X, Y, Width, Height |
| الطابع الزمني | get_Timestamp | وقت الالتقاط الدقيق (دقة 100 نانوثانية) |
| مدة البقاء في التطبيق | IMemoryEntity3 | المدة التي قضيتها في كل تطبيق (مللي ثانية) |
| مدة البقاء في الويب | IMemoryEntity3 | المدة التي قضيتها في كل موقع (مللي ثانية) |
| تسمية الحساسية | IMemoryEntity5 | تصنيف Microsoft Purview/DLP: الاسم، اللون، تلميح الأداة |
| معرف نشاط المستخدم | IMemoryEntity6 | معرف ارتباط نشاط الجدول الزمني لنظام Windows |
| إمكانية الاستعادة | IMemoryEntity2 | قناع بت: يمكن إعادة تشغيل التطبيق (0x1)، الرابط (0x2)، الملف (0x4)، URI (0x8)، الجدول الزمني (0x10) |
| استعادة السياق | TryRestoreContextAsync | إعادة فتح التطبيق أو الصفحة أو المستند الدقيق من أي التقاط |
DomainUserTagOrganizationProductAddressLocationDateTimeEventDurationMemoryDscSensitivityLabelWebVideoMeetingChatMailingPackageTextRatioSkipTopicsAnyText، Image، Table، Container، Menu، ToolBar، AddressBar، Toolpane، TabBar، TitleBar. كل منها مع مربعات إحاطة دقيقة بالبكسل ونص OCR مضمن.L1Description (ملخص نصي من الذكاء الاصطناعي لما كنت تفعله)، L1Activity (مصنف: تصفح، برمجة، كتابة، قراءة بريد إلكتروني)، L1Application (سياق التطبيق المصنف بالذكاء الاصطناعي).Meeting (مكالمات مؤتمرات)، Chat (مراسلة)، WebVideo (تشغيل فيديو)، MailingPackage (بريد إلكتروني/نشرات إخبارية). يجمع التقاطات متعددة في جلسات نشاط منطقية.UserActivity، KMeansCluster، LobeTopicCluster، ApplicationDwellTime، WebsiteDwellTime، ClipboardImageCopied، Topic.IsContentFilteringEnabled على واجهة IAutomatedCaptureController6.