
محرك ربط (Hooking) في وضع المستخدم بدون تصحيح (Patch-less) يعتمد على نقاط توقف الأجهزة (DR0-DR7)، وأدوات قياس عن بُعد (Telemetry Instrumentation) — (إثبات مفهوم لـ AMSI وWLDP وETW).
نموذج إثبات مفهوم (POC) لأبحاث أمنية يوضح ربط الدوال عبر نقاط إيقاف الأجهزة (سجلات تصحيح المعالج) كبديل لأساليب الترقيع التقليدية للذاكرة في الكود.
الغرض والنطاق
هذا المستودع منشور بشكل صارم لأغراض الأبحاث الأمنية الدفاعية، وتعليم فرق الأحمر/الأرجواني، وهندسة الاكتشاف، والدراسة الأكاديمية لدواخل نظام Windows. وهو يوضح كيف يمكن للمهاجم إساءة استخدام سجلات تصحيح المعالج لتحييد التليمترية الأمنية في وضع المستخدم — والأهم بنفس القدر، ما الذي ينبغي للمدافعين مراقبته من أجل اكتشاف مثل هذه التقنيات. ليس المؤلف مسؤولاً عن أي إساءة استخدام لهذا الكود. استخدام هذه التقنية ضد أنظمة بدون تفويض صريح يعد غير قانوني وينتهك القوانين ذات الصلة بجرائم الحاسوب وإساءة الاستخدام في معظم الولايات القضائية. لا تنشر هذا في أي بيئة لا تملكها أو ليس لديك إذن كتابي صريح لاختبارها.
ينفّذ mora_hwbp.c مكتبة DLL تقوم، بمجرد تحميلها/حقنها في عملية هدف (مثل مضيف PowerShell)، بربط أربع دوال في وضع المستخدم حصريًا عبر نقاط إيقاف الأجهزة الخاصة بوحدة المعالجة المركزية المخزنة في سجلات التصحيح البنيوية (DR0–DR7) لكل خيط في العملية:
يستقبل معالج الاستثناءات الموجه (VEH) على مستوى العملية أخطاء EXCEPTION_SINGLE_STEP (0x80000004) الناتجة عن سجلات التصحيح، ويحاكي مسار الإرجاع الناجح للدالة الأصلية عبر إعادة كتابة سياق الاستثناء، ثم يستأنف التنفيذ — كل ذلك دون تعديل بايت واحد من الذاكرة القابلة للتنفيذ.
هذا يجعل التقنية مثيرة للاهتمام بشكل خاص من المنظورين الهجومي والدفاعي:
.text معدّلة (الربط التقليدي المضمّن، أو ترقيع EAT/IAT، أو استبدال Etwp*).GetThreadContext/SetThreadContext) يمكن استخدامها للاكتشاف.تشترك أساليب الربط التقليدية في وضع المستخدم — الالتفاف المضمّن (استبدالات من 5 إلى 14 بايت)، وربط جدول عناوين الاستيراد (IAT)، وربط جدول عناوين التصدير (EAT) — في نقطة ضعف مشتركة: فهي تعدّل ذاكرة يمكن لماسحات السلامة و ETW ملاحظتها.
تنفّذ منتجات AV/EDR الحديثة:
pageguard/guard-page، وتحولات VirtualProtect إلى PAGE_EXECUTE_READWRITE، وعدم تطابق تجزئات الأقسام.تتجاوز نقاط إيقاف الأجهزة كل ذلك:
.text.SetThreadContext، والتي لا تطلق إشارات "الذاكرة المعدّلة" الكلاسيكية التي تستخدمها ماسحات السلامة.يستكشف نموذج إثبات المفهوم هذا فعالية واكتشافية هذه التقنية ضد AMSI (واجهة فحص البرامج الضارة)، وWLDP (سياسة قفل Windows)، وETW (تتبع الأحداث لنظام Windows) — وهي البدائيات الأمنية الثلاث الأكثر اعتمادًا في وضع المستخدم ضمن حزمة أمان Windows الحديثة.
AMSI هي نقطة تكامل منصة Windows التي تتيح للتطبيقات (PowerShell، Office، VBScript، مضيفات .NET، إلخ) طلب فحص المحتوى من موفري مكافحة البرامج الضارة المسجلين. هناك نقطتا دخول ذات أهمية أساسية:
AmsiScanBuffer(HANDLE hamsiContext, PVOID buffer, ULONG length, LPCWSTR contentName, HANDLE hamsiSession, AMSI_RESULT *pResult)AmsiScanString(HANDLE hamsiContext, LPCWSTR string, LPCWSTR contentName, HANDLE hamsiSession, AMSI_RESULT *pResult)من خلال إجبار AMSI_RESULT المُرجَع على القيمة AMSI_RESULT_CLEAN (0)، يعتقد محرك البرمجة النصية أن المحتوى تم فحصه وتبيّن أنه غير ضار، فيستمر التنفيذ دون انقطاع.
تنفّذ WLDP تقييم السياسات لـ Windows Defender Application Control (WDAC / Device Guard). تجيب WldpIsClassInApprovedList عما إذا كانت فئة COM معينة (معرّفة بواسطة GUID) مسموحًا بها بموجب السياسة الحالية. تستشير AMSI داخليًا WLDP لتقرر ما إذا كانت بعض فئات البرامج النصية/المحتوى "موثوقة" (في القائمة المعتمدة). إذا أبلغت الدالة أن الفئة معتمدة، فقد تتخطى AMSI مزيدًا من التدقيق لنوع المحتوى هذا.
تضبط المكتبة معلمة الإخراج isApproved (RDX) إلى TRUE وتُعيد S_OK، مما يجعل الفئة المُقيَّمة تبدو موثوقة.
EtwEventWrite في ntdll.dll هو مصرف وضع المستخدم الأساسي لجميع إصدارات أحداث ETW تقريبًا على النظام. كتمه له آثار جانبية واسعة ذات صلة بمراقبة الأمان:
Microsoft-Windows-DotNETRuntime)تُرجع المكتبة ببساطة ERROR_SUCCESS (0) دون تنفيذ الدالة الحقيقية.
---``` ┌──────────────────────────────────────────────────────────────────────────┐ │ Target Process (e.g. powershell.exe) │ │ │ │ ┌──────────────────────────┐ ┌──────────────────────────────────┐│ │ │ mora_hwbp.dll │ │ CPU / Windows ││ │ │ │ │ ││ │ │ DllMain / InstallHook │ │ Thread A Thread B ││ │ │ │ │ │ ┌────────┐ ┌────────┐ ││ │ │ ▼ │ │ │ DR0..3 │ │ DR0..3 │ ││ │ │ Resolve exports │ │ └────────┘ └────────┘ ││ │ │ (amsi/wldp/ntdll) │ │ ││ │ │ │ │ │ #DB (single-step) ││ │ │ ▼ │ │ exception ──► Windows Dispatch ││ │ │ AddVectoredException │ │ │ ││ │ │ Handler(VEH) │ │ ▼ ││ │ │ │ │ │ ┌─────────────────────────────┐ ││ │ │ ▼ │ │ │ VectoredHandler (ours) │ ││ │ │ SetHwbpOnThread(ALL) │ │ │ • match #DB address │ ││ │ │ │ │ │ │ • rewrite context (RIP/RSP)│ ││ │ │ ▼ │ │ │ • spoof return value (RAX) │ ││ │ │ MonitorThread ◄──┐ │ │ │ • continue execution │ ││ │ │ (re-hook every │ │ │ └─────────────────────────────┘ ││ │ │ 500ms) └──────┘ │ ││ │ └──────────────────────────┘ └──────────────────────────────────┘│ └──────────────────────────────────────────────────────────────────────────┘
**نظرة عامة على التدفق:**
1. يتم تحميل ملف DLL في العملية الهدف (عبر أي تقنية حقن — انظر [الاستخدام](#injection--usage-example)).
2. عند `DLL_PROCESS_ATTACH` (أو عبر دالة `InstallHook` المُصدَّرة)، يتم حلّ الصادرات الهدف باستخدام `GetProcAddress` (مع إمكانية فرض تحميل الوحدات عبر `LoadLibraryW`).
3. يتم تسجيل **معالج استثناءات متجه (VEH)** باعتباره المعالج **الأول** في العملية (`AddVectoredExceptionHandler(1, ...)`).
4. يتم ربط **الخيط الحالي** فورًا، ثم تعداد **جميع الخيوط الموجودة** في العملية عبر `CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0)` وربطها.
5. يستيقظ **خيط مراقبة** كل 500 مللي ثانية ويعيد تطبيق نقاط التوقف على كل خيط — بما في ذلك **الخيوط المنشأة حديثًا** — مما يضمن استمرارية الخطاف حتى لو تم إنشاء خيط بعد الربط أو تم مسح نقاط التوقف خارجيًا.
6. عندما يتم استدعاء أي دالة مربوطة على أي خيط، تُطلق وحدة المعالجة المركزية استثناء خطوة واحدة `#DB`؛ وتقوم Windows بتوجيهه إلى VEH، الذي يحاكي عودة سليمة ويستمر في التنفيذ.
### مثال على مخرجات التصحيح

*الشكل 1 — نموذج لمخرجات التشخيص التي تم التقاطها باستخدام Sysinternals DebugView. كل سطر يعرض عنوان الهدف الذي تم حلّه وعداد الضربات المباشر لسجل التصحيح المقابل له.*
---
## الغوص التقني العميق
### 5.1 نقاط توقف الأجهزة على x64
في x86/x64، توفر كل وحدة معالجة مركزية **أربعة سجلات عناوين تصحيح أجهزة** (`DR0`–`DR3`) وسجل تحكم (`DR7`). أي خيط يعمل مع نقطة توقف غير صفرية في `DR0`–`DR3` سيُحدث خطأً (fault) كلما وصل مؤشر التعليمات إلى ذلك العنوان (أو طابق الوصول إلى البيانات الشروط المكوّنة). يسجّل سجل الحالة `DR6` أي نقطة توقف تم تفعيلها.
نقاط توقف الأجهزة **تعتمد على السياق (context-sensitive)**: فهي مخزّنة في بنية `CONTEXT` الخاصة بالخيط وتنطبق فقط على الخيط الذي تم ضبطها عليه. لهذا السبب يجب على أي تطبيق قوي ضبط نقاط التوقف على **كل خيط** في العملية (وإعادة تطبيقها باستمرار على الخيوط الجديدة).
### 5.2 تخطيط سجلات التصحيح (DR0–DR7)
`DR7` هو حقل بتات يتحكم في تفعيل نقاط التوقف وسلوكها:
| البتات | الحقل | المعنى |
|--------|--------|-----------------------------------------------------|
| `0` | `L0` | تمكين محلي لنقطة التوقف 0 (DR0) |
| `2` | `L1` | تمكين محلي لنقطة التوقف 1 (DR1) |
| `4` | `L2` | تمكين محلي لنقطة التوقف 2 (DR2) |
| `6` | `L3` | تمكين محلي لنقطة التوقف 3 (DR3) |
| `8` | `LE` | تمكين محلي قديم (مُبقى للتوافق) |
| `9` | `GE` | تمكين عام قديم (مُبقى للتوافق) |
| `16–17`| `R/W0` | نوع الوصول لنقطة التوقف BP0 (`00` = تنفيذ تعليمة) |
| `18–19`| `Len0` | الطول لنقطة التوقف BP0 (`00` = 1 بايت) |
| `20–21`| `R/W1` | نوع الوصول لنقطة التوقف BP1 (`00` = تنفيذ تعليمة) |
| `22–23`| `Len1` | الطول لنقطة التوقف BP1 (`00` = 1 بايت) |
| `24–25`| `R/W2` | نوع الوصول لنقطة التوقف BP2 (`00` = تنفيذ تعليمة) |
| `26–27`| `Len2` | الطول لنقطة التوقف BP2 (`00` = 1 بايت) |
| `28–29`| `R/W3` | نوع الوصول لنقطة التوقف BP3 (`00` = تنفيذ تعليمة) |
| `30–31`| `Len3` | الطول لنقطة التوقف BP3 (`00` = 1 بايت) |
تم تكوين نقاط التوقف الأربع جميعها على **التنفيذ (جلب التعليمات) لبايت واحد**، وهو الشرط المناسب لخطافات مداخل الدوال.
### 5.3 معالج الاستثناءات المتجهة (VEH)
عندما يتم تفعيل نقطة توقف، تُطلق المعالج استثناء `#DB`. في Windows على x64، يقوم روتين التوجيه في ntdll بتمريره عبر **سلسلة VEH** على مستوى العملية قبل سلسلة معالج الاستثناءات المهيكل (SEH) الخاصة بالخيط. المعالج في هذا المشروع:
1. **التصفية** — يعالج فقط `EXCEPTION_SINGLE_STEP` (`0x80000004`)؛ وكل ما عداه يمر إلى `EXCEPTION_CONTINUE_SEARCH`.
2. **المطابقة** — يقارن `ExceptionAddress` مع عناوين الدوال الأربع المعروفة.
3. **يعيد كتابة السياق (context)**:
- `RIP = *(RSP)` → "العودة" إلى المُستدعي الأصلي عن طريق إخراج عنوان العودة من المكدس.
- `RSP += 8` → محاكاة تعليمة `ret` (تراجع بتعليمة واحدة على x64).
- `RAX = 0` → تزوير `S_OK` / `ERROR_SUCCESS` (رمز إرجاع ناجح).
- `DR6 &= ~0xF` → مسح بتات حالة نقطة التوقف بحيث يمكن إعادة تنفيذ التعليمات لاحقًا دون حالة زائفة.
4. **يعدّل معاملات الإخراج (out-parameters)** (انظر [5.4](#54-per-component-interception-logic)).
5. **يعيد `EXCEPTION_CONTINUE_EXECUTION`**، مما يخبر Windows بإعادة تشغيل الخيط بالسياق المعدَّل — أي أن التنفيذ يستأنف عند *المُستدعي*، والدالة الهدف الحقيقية **لا تُنفَّذ أبدًا**.
كل موقع اعتراض مغلَّف إضافيًا بحارس SEH `__try/__except` بحيث لا يمكن لتخطيط مكدس تالف أو غير متوقع أن يعطّل العملية — اعتبار متانة للأهداف المعادية/المحصّنة.
### 5.4 منطق الاعتراض لكل مكوّن
**DR0 — `AmsiScanBuffer`** (x64، أول 6 وسائط في `RCX, RDX, R8, R9, [RSP+0x28], [RSP+0x30]`):```
HRESULT AmsiScanBuffer(HANDLE, PVOID, ULONG, LPCWSTR, HANDLE, AMSI_RESULT* pResult);
[RSP+0x28] [RSP+0x30]
AMSI_RESULT_CLEAN (0) إلى المعامل السادس (pResult، عند [RSP+0x30]).S_OK (0) في RAX.DR1 — AmsiScanString (x64، أول 5 وسائط في RCX, RDX, R8, R9, [RSP+0x28]):```
HRESULT AmsiScanString(HANDLE, LPCWSTR, LPCWSTR, HANDLE, AMSI_RESULT* pResult);
[RSP+0x28]
- يكتب `AMSI_RESULT_CLEAN (0)` إلى المعامل الخامس (`pResult`، عند `[RSP+0x28]`).
- يُرجع `S_OK (0)` في `RAX`.
**DR2 — `WldpIsClassInApprovedList`** (أول 3 وسائط في `RCX, RDX, R8`):```
HRESULT WldpIsClassInApprovedList(const GUID* classId, PBOOL isApproved, DWORD evalCriteria);
RCX RDX R8
TRUE إلى *isApproved (عبر RDX).S_OK (0) في RAX.DR3 — EtwEventWrite (أول 4 وسائط في RCX, RDX, R8, R9):```
ULONG EtwEventWrite(HANDLE RegHandle, PCEVENT_DESCRIPTOR EventDescriptor,
ULONG UserDataCount, PEVENT_DATA_DESCRIPTOR UserData);
- يُرجع `ERROR_SUCCESS (0)` في `RAX` دون لمس أي معامل إخراج.
- النتيجة: لا تتلقى موفِّرات ETW **أي** أحداث من العملية المُعلَّق عليها الخطاف، مما يمنع تسجيل تنفيذ البرامج النصية، وتحميل الوحدات، وإنشاء العمليات، وبيانات AMSI عن بُعد.
### 5.5 إدارة الخيوط واستمرارية الخطاف
نظرًا لأن سجلات التصحيح مخصصة لكل خيط، يجب على المحرك الحفاظ على الخطافات باستمرار:
1. **الخطاف الفوري** — يقوم `DllMain` (أو `InstallHook`) بتعليق الخطاف على الخيط المُنفِّذ باستخدام `SetHwbpOnThread(GetCurrentThread())`.
2. **مسح جميع الخيوط** — يقوم `HookAllThreads()` بتعداد كل خيط في العملية عبر لقطة `TH32CS_SNAPTHREAD`، ويعلّق كل خيط خارجي (`SuspendThread`)، ويطبّق نقاط التوقف (`SetHwbpOnThread`)، ثم يستأنفه ويغلق المقبض. يمنع التعليق حدوث حالة سباق يتعطل فيها الخيط في منتصف تبديل السياق بين `GetThreadContext` و`SetThreadContext`.
3. **مراقب الاستمرارية** — يعمل `MonitorThreadProc` في حلقة مع `Sleep(500)` ويستدعي `HookAllThreads()` كل 500 مللي ثانية. يعمل هذا على **إعادة تسليح أي نقاط توقف تمت إزالتها** (على سبيل المثال، عبر استدعاء خارجي لـ `SetThreadContext`، أو أداة تصحيح أخطاء، أو إنهاء/إنشاء خيط) و**يشمل الخيوط التي أُنشئت بعد الخطاف الأولي**.
4. **المزامنة** — يعمل `HookAllThreads` تحت `CRITICAL_SECTION` (`g_HookLock`) بحيث لا يتداخل خيط المراقب وإجراء الخطاف الأولي مع تبديلات السياق أبدًا.
5. **إنهاء نظيف** — يوقف `UninstallHook` المراقب، ويمسح `DR0–DR7` على كل خيط، ويلغي تسجيل VEH.
> **إجابة صريحة على سؤال «استمرارية الخطاف»:** نعم — إذا تمت إزالة نقاط التوقف من أي خيط (بواسطة وكيل آخر، أو مصحح أخطاء، أو EDR)، فإن خيط المراقب **يعيد تطبيقها خلال 500 مللي ثانية**. بالإضافة إلى ذلك، يتم تعليق الخطاف على أي خيط يُنشأ بعد تحميل DLL خلال دورة مراقبة واحدة. الطريقة الوحيدة الموثوقة لهزيمة هذا المحرك تحديدًا هي إنهاء خيط المراقب *و* مسح VEH *و* إزالة السجلات في النافذة الزمنية نفسها — أو استخدام مكافحة التصحيح التي ترفض `SetThreadContext` منذ البداية.
---
## واجهة API المُصدَّرة
| التصدير | التوقيع | السلوك |
|-------------------|------------------------------------|-----------------------------------------------------------------------|
| `InstallHook` | `BOOL WINAPI InstallHook(void)` | يحلّ الأهداف، ويسجّل VEH، ويعلّق الخطاف على جميع الخيوط، ويبدأ المراقب. |
| `UninstallHook` | `BOOL WINAPI UninstallHook(void)` | يوقف المراقب، ويمسح نقاط التوقف على جميع الخيوط، ويزيل VEH. |
| `GetStats` | `void WINAPI GetStats(void)` | يُصدر حالة الخطاف الحالية (عبر `OutputDebugStringA`) — العنوان وعدادات الإصابات. |
يتم الحفاظ على عدادات الإصابات (`g_HaveAmsiBuf`, `g_HaveAmsiStr`, `g_HaveWldp`, `g_HaveEtw`) باستخدام `InterlockedIncrement` وتظهر في مخرجات التصحيح، وهو أمر مفيد للتحقق من أن الاعتراض يحدث فعليًا في بيئة مختبر.
لاحظ أن `DllMain` نفسه ينفذ تسلسل الخطاف الكامل عند `DLL_PROCESS_ATTACH`، لذا فإن التصديرات هي وسائل راحة اختيارية لسيناريوهات التحميل/الإلغاء في وقت التشغيل.
---
## تعليمات البناء
**المتطلبات:** Windows 10/11 x64، وVisual Studio Build Tools (`icx.exe`)، وSDK.
قم بتجميع ملف DLL (x64):```bat
icx.exe /nologo /O3 /MT /EHsc "mora_hwbp.c" /link /DLL /out:"mora_hwbp.dll" /LIBPATH:"C:\Program Files (x86)\Intel\oneAPI\compiler\latest\lib"
شرح العلامات:
| العلامة | الغرض |
|---|---|
/O3 |
النتيجة هي mora_hwbp.dll، والتي يمكن تحميلها في عملية هدف.
يجب تحميل الـ DLL في عملية تستخدم AMSI/WLDP/ETW — يُعد مضيف PowerShell بيئة الاختبار المعيارية. يمكن إجراء التحميل بأي تقنية حقن DLL قياسية. يمكن تنفيذ عرض توضيحي بسيط ومستقل بذاته باستخدام الحقن الانعكاسي/عبر LoadLibrary من خلال محمّل صغير بلغة C:```bat
rem Run from an x64 developer prompt (example with a generic loader)
loader.exe mora_hwbp.dll powershell.exe
أو، لإجراء تحقق يدوي في بيئة اختبار، قم بالحقن باستخدام أداتك المفضلة ثم تحقق من خلال PowerShell:```powershell
# 1. Inject mora_hwbp.dll into the PowerShell process (via external tool).
# 2. Verify that classic AMSI test vectors now return clean.
"AmsiTestSample:7e72c3ce-861b-4339-8740-0ac1484c1386"
للتحقق المخبري فقط. لاحظ عبر مصحح أو
GetStats/OutputDebugStringأن نقاط التوقف الأربع جميعها تُبلغ عن إصابات عند تنفيذ محتوى البرنامج النصي.
إثبات المفهوم هذا ثنائي الغرض: الخصائص نفسها التي تجعله فعالًا هجوميًا هي تحديدًا ما ينبغي للمدافعين البحث عنه.
GetThreadContext(CONTEXT_DEBUG_REGISTERS) على العمليات عالية القيمة وتدقيق أي مؤشر ترابط بقيم DR0–DR3 غير صفرية خارج ملفات تعريف المصحح المعتمدة.Microsoft-Windows-Kernel-Process + Thread والتنبيه على NtGetContextThread/NtSetContextThread التي تستهدف عمليات ذات صلة بالأمن.EtwEventWrite، وETW على مستوى النواة، وإعادة فحص مستهلك AMSI) بدلًا من سلامة .text وحدها.SetThreadContext الموجّه من كل مؤشر ترابط إلى عمليات أخرى كإشارة صريحة عالية الخطورة.RCX/RDX/R8/R9 ثم [RSP+0x20…]). سيتطلب البديل x86 إعادة بناء معاملات بأسلوب [EBP+…].Sleep(500)؛ قد يؤدي إنشاء مؤشرات ترابط سريع للغاية مع تجريد عدواني إلى تجاوز المراقب نظريًا لبضع مئات من المللي ثانية.OutputDebugStringA — تعتمد التشخيصات على قناة إخراج تصحيح؛ في بيئة مجردة بالكامل/بدون واجهة رسومية، يجب إرفاق مصحح أو إعادة توجيه الإخراج للملاحظة المخبرية.هذا المشروع مرخّص بموجب رخصة MIT - راجع ملف LICENSE للتفاصيل.
يُصدر هذا المشروع لأغراض البحث التعليمي والدفاعي فقط. إذا كنت بائعًا أمنيًا، أو فريقًا أزرق، أو مهندس كشف، فأنت مدعو لاستخدام محتويات هذا المستودع لتحسين تغطية الكشف لديك ضد التهرب القائم على نقاط توقف العتاد. إذا اكتشفت إساءة استخدام هذه التقنية في البيئات الحية، فأبلغ عنها عبر عملية الإفصاح المسؤول في مؤسستك وقنوات البائع/الجهة المعنية.
استخدمه على مسؤوليتك الخاصة. قد ينتهك الاستخدام غير المصرح به لهذه التقنية القوانين المعمول بها.
| السجل | الدالة المربوطة | الوحدة | الغرض |
|---|
DR0 | AmsiScanBuffer | amsi.dll | تحييد فحص محتوى AMSI |
DR1 | AmsiScanString | amsi.dll | تحييد فحص سلاسل AMSI |
DR2 | WldpIsClassInApprovedList | wldp.dll | فرض موافقة فئة WLDP (Device Guard / WDAC) |
DR3 | EtwEventWrite | ntdll.dll | كتم تتبع أحداث ETW |
| التحسين الأقصى (كود الوظيفة، غير مطلوب) |
/MT | ربط CRT ثابت (بدون اعتماد على DLL لوقت التشغيل) |
/EHsc | معالجة استثناءات C++/SEH (مطلوبة لـ __try) |
/DLL | إنتاج DLL بجدول تصدير |
| المؤشر | الملاحظة |
|---|
استدعاءات GetThreadContext / SetThreadContext | تبديلات سياق سجلات تصحيح عالية التردد على عمليات/مؤشرات ترابط أخرى (ETW على مستوى النواة: Microsoft-Windows-Kernel-Process/Thread APIs). |
DR0–DR3 غير صفرية | أي مؤشر ترابط تحتوي CONTEXT_DEBUG_REGISTERS الخاصة به على عنوان وضع مستخدم خارج تدفقات عمل المصحح المعروفة. |
بتات التمكين المحلية في DR7 (L0–L3) مع R/W = 00 | نقاط توقف للتنفيذ فقط على مؤشرات ترابط غير مُدارة بواسطة مصحح — شذوذ قوي. |
حجم EXCEPTION_SINGLE_STEP | معدلات عالية من أخطاء #DB (0x80000004) الناشئة من VEH الخاصة بالعملية. |
| تسجيل VEH من الفرصة الأولى | VEH مُضاف حديثًا (AddVectoredExceptionHandler) قبل عاصفة #DB بفترة وجيزة. |
TH32CS_SNAPTHREAD + SuspendThread/ResumeThread | أنماط متكررة من تعداد مؤشرات الترابط + تعليقها (يستخدمها مراقب 500 مللي ثانية). |
تحميل wldp.dll/amsi.dll عبر LoadLibraryW عندما لم تكن محملة سابقًا | تحميلات وحدات شاذة في العملية المستهدفة. |
عدم الوصول إلى EtwEventWrite | غياب أحداث ETW المتوقعة (سجلات PowerShell التشغيلية صامتة أثناء تشغيل البرامج النصية). |