
مشروع بحثي يعمل على الهندسة العكسية لواجهات COM الخاصة بمركز أمان Windows لتتبع تسجيل برامج مكافحة الفيروسات عبر ATL وvtable وWSCAPI وRPC، مع التحقق في وقت التشغيل عبر WMI.
OWN-Defender هو مشروع بحث أمني في Windows يركز على فهم كيفية قيام مركز أمان Windows (WSC) بتمثيل وإدارة منتجات الأمان المضادة للفيروسات من خلال واجهات COM الخاصة به.
بدأ المشروع كتحقيق في السلوك الذي أظهره DefendNot، ولكن بدلاً من التعامل مع التنفيذ الحالي كصندوق أسود، استخدمته كنقطة انطلاق للهندسة العكسية والتحقق المستقلين.
الهدف من هذا المشروع هو فهم مسار التنفيذ الكامل:
COM
↓
CLSID / IID
↓
CoCreateInstance
↓
QueryInterface
↓
ATL Interface Map
↓
vtable
↓
IWscAVStatus4
↓
CWscIsv
↓
WSCAPI.dll
↓
RPC
↓
Windows Security Center
تم تطوير المشروع واختباره في بيئة بحث Windows خاضعة للتحكم.
للاستخدام البحثي/التعليمي فقط
هذا المشروع مخصص لأبحاث داخل Windows، والهندسة العكسية، والتعليم الأمني، واختبارات الأمان المصرح بها. لا تستخدمه للتدخل في برامج الأمان على الأنظمة التي لا تملكها أو ليس لديك إذن صريح لاختبارها.
كان السؤال الأولي بسيطًا:
كيف يعرف مركز أمان Windows أن منتج مكافحة الفيروسات موجود؟
بدلاً من التوقف عند توثيق واجهة برمجة التطبيقات العامة، أردت فهم ما يحدث تحت الواجهة.
أدى هذا إلى عدة أسئلة:
QueryInterface() الواجهة؟__int64 a1 فقط لطريقة ما؟Register() هي فعليًا دالة تسجيل مكافحة الفيروسات؟كانت الخطوة الأولى هي تحديد فئة COM الخاصة بمركز أمان Windows.
يستخدم المشروع فئة COM الخاصة بـ WSC:
CLSID_WscIsv
F2102C37-90C3-450C-B3F6-92BE1693BDF2
يحتوي التنفيذ أيضًا على منطق لتحديد موقع CLSID ديناميكيًا من سجل Windows بدلاً من الاعتماد حصريًا على قيمة ثابتة.
من الناحية المفاهيمية:
HKLM
└── SOFTWARE
└── Classes
└── CLSID
└── {CLSID}
└── Windows Security Center ISV API
قدم هذا أول علاقة مهمة:
Registry
↓
CLSID
↓
Windows Security Center ISV API
كان التحدي التالي هو تحديد واجهة COM التي يجب طلبها.
يستخدم المشروع:
IWscAVStatus4
مع:
4DCBAFAC-29BA-46B1-80FC-B8BDE3C0AE4D
كان أحد الدروس المهمة من البحث:
اسم GUID وحده ليس دليلاً كافيًا.
تحققت من العلاقة من خلال الهندسة العكسية بدلاً من افتراض أن اسم الواجهة وGUID صحيحان.
شمل التحقيق:
QueryInterface_ATL_INTMAP_ENTRYQueryInterfaceكانت إحدى أكثر خطوات الهندسة العكسية فائدة هي تتبع تنفيذ:
CComAggObject<CWscIsv>::QueryInterface()
الذي يصل في النهاية إلى:
ATL::CComObjectRootBase::InternalQueryInterface()
تُستخدم خريطة واجهة ATL لمقارنة IID المطلوب مع إدخالات الواجهة المسجلة.
من الناحية المفاهيمية:
Requested IID
↓
QueryInterface()
↓
InternalQueryInterface()
↓
ATL Interface Map
↓
GUID comparison
↓
Matching interface
↓
Interface pointer
قدم هذا دليلاً مستقلاً على أن GUID قيد التحقيق يتوافق فعليًا مع واجهة COM المتوقعة.
Register()كان أحد أكبر تحديات الهندسة العكسية هو فهم سبب عدم عرض IDA/Ghidra دائمًا لتوقيع الطريقة الذي توقعته.
تحتوي الواجهة المعاد بناؤها على:
virtual HRESULT __stdcall Register(
BSTR path,
BSTR name,
unsigned int,
unsigned int
) = 0;
ومع ذلك، يمكن أن يعرض المفكك تنفيذًا مثل:
_IWscAVStatus4<CWscIsv>::Register(__int64 a1)
في البداية بدا هذا غير متسق.
أظهر التحقيق الإضافي أن تمثيل المفكك كان يصف غلافًا/كعبًا والاستدعاء غير المباشر الأساسي عبر vtable بدلاً من تقديم توقيع الواجهة المنطقي الكامل.
أصبح هذا درسًا مهمًا:
مخرجات المفكك هي تفسير لرمز الآلة، وليست الحقيقة الأصلية على مستوى المصدر.
لحل هذه التناقضات، قارنت:
COM interface definition
↓
vtable layout
↓
assembly
↓
wrapper/thunk
↓
calling convention
↓
actual target function
Register() المتعددةكان مصدر ارتباك آخر هو وجود دوال متعددة بأسماء مثل:
IWscAVStatus2::Register
IWscAVStatus4::Register
IWscFWStatus2::Register
RegisterAV
كان الإدراك المهم أن الأسماء المتشابهة لا تعني واجهات متطابقة.
على سبيل المثال:
AV
↓
IWscAVStatus4
↓
AV registration
بينما:
Firewall
↓
IWscFWStatus2
↓
Firewall registration
كان يجب التحقق من رقم الواجهة والتنفيذ المحيط بها بدلاً من اختيار دالة لمجرد أن اسمها يحتوي على Register.
كان هذا من أكثر الأجزاء فائدة في البحث لأنه أجبرني على الربط بين:
Interface
+
IID
+
vtable
+
implementation
+
parameter layout
+
call target
بعد تحديد الواجهة الصحيحة، تتبعت عملية التسجيل أعمق داخل الملف الثنائي.
كان المسار الملاحظ تقريبًا:
IWscAVStatus4::Register()
↓
CWscIsv
↓
RegisterSecurityProductFunction
↓
wscRegisterSecurityProduct()
↓
WSCAPI.dll
↓
s_wscRegisterSecurityProduct()
↓
NdrClientCall3()
↓
RPC
↓
Windows Security Center
كان هذا مهمًا بشكل خاص لأن طريقة COM نفسها لم تكن العملية النهائية.
عبر الاستدعاء في النهاية حدود RPC.
غيّر ذلك طريقة رؤيتي للبنية:
COM
≠
final implementation
بدلاً من ذلك:
COM
↓
local implementation
↓
WSC API
↓
RPC client
↓
Windows component
WSCAPI.dllكانت الطبقة التالية هي WSCAPI.dll.
وصل المسار المعكوس هندسيًا إلى:
wscRegisterSecurityProduct()
الذي استدعى في النهاية:
s_wscRegisterSecurityProduct()
ثم:
NdrClientCall3()
كانت هذه هي النقطة التي انتقل فيها التحقيق من استدعاء COM عادي إلى بنية RPC في Windows.
ساعد فهم هذه الطبقة في تفسير سبب عدم إمكانية فهم السلوك بالكامل من خلال النظر فقط إلى DLL الأصلي لـ COM.
كان التحليل الثابت جزءًا واحدًا فقط من البحث.
بعد إعادة بناء الواجهة ومسار الاستدعاء ذي الصلة، أنشأت تنفيذي الخاضع للتحكم وقارنت السلوك الناتج مع مركز أمان Windows.
استخدمت معلومات مركز أمان Windows / WMI مثل:
ROOT\SecurityCenter2
AntiVirusProduct
لمراقبة معلومات المنتج المسجل بشكل مستقل.
كانت عملية التحقق:
Reverse engineering
↓
Interface reconstruction
↓
Own implementation
↓
Runtime execution
↓
Windows Security Center
↓
WMI observation
↓
Compare results
سمح لي هذا بالتحقق من أن استنتاجات التحليل الثابت تتوافق مع سلوك Windows الملحوظ.
علّمني هذا المشروع أكثر بكثير من مجرد التفاعل مع واجهة COM واحدة.
CoCreateInstanceQueryInterfaceWSCAPI.dllNdrClientCall3الأهم من ذلك، تعلمت تجنب الاعتماد على دليل واحد فقط.
بدلاً من ذلك:
Symbol
↓
Decompiler
↓
Assembly
↓
GUID
↓
Interface Map
↓
vtable
↓
Call Graph
↓
RPC
↓
Runtime Verification
كل طبقة تزيد الثقة في الاستنتاج.
يتكون تنفيذ البحث من مكونين رئيسيين.
OWN-Defender
│
├── OWN-Defender.cpp
│ ├── WSC COM interaction
│ ├── CLSID discovery
│ ├── COM initialization
│ ├── IWscAVStatus4 interaction
│ ├── registration
│ ├── status update
│ └── cleanup
│
└── dllmain.cpp
├── DLL entry point
├── research loader
├── controlled execution
└── cleanup/stop handling
المستودع صغير عمدًا بحيث تظل العلاقة بين السلوك المعكوس هندسيًا والتنفيذ سهلة المتابعة.
بُني هذا المشروع حول أسئلة بدلاً من مجرد إعادة إنتاج الوظيفة:
How does WSC identify the COM class?
How is the IID mapped to the interface?
How does QueryInterface locate the interface?
Why does IDA show different function signatures?
Where is the actual vtable?
Which Register() is the AV implementation?
What happens after the COM method?
Where does WSCAPI.dll enter the call chain?
Where does RPC begin?
How can the result be independently verified?
كانت هذه الأسئلة في النهاية أكثر قيمة من التنفيذ النهائي نفسه.
يوفر المشروع أيضًا نقطة بداية مفيدة لدراسة الحدود الأمنية بين:
Application
↓
COM
↓
Windows Security Center
↓
Security Provider Information
من المهم التمييز أن تسجيل معلومات منتج الأمان لا يعادل تلقائيًا تعطيل محرك Defender أو تجاوز آليات الحماية الخاصة به.
لذلك، يجب النظر إلى هذا المشروع في المقام الأول على أنه:
بحث في الهندسة العكسية لمركز أمان Windows / COM
بدلاً من اعتباره ادعاءً بأن تسجيل WSC وحده يشكل ثغرة في Defender.
أي تأثير أمني يتطلب تحقيقًا وتحققًا منفصلين.
استُلهم هذا البحث جزئيًا من العمل المعروض في DefendNot بواسطة es3n1n.
شكر خاص للمؤلف على توفير نقطة بداية مفيدة لفهم آلية WSC.
المشروع الأصلي: https://github.com/es3n1n/defendnot
الغرض من هذا المستودع ليس ادعاء البحث الأصلي كبحث خاص بي، بل توثيق عملية الهندسة العكسية الخاصة بي، والتنفيذ المستقل، والتحقق من سلوك Windows الأساسي.
تم توفير هذا المستودع من أجل:
استخدم هذا المشروع فقط على الأنظمة التي تملكها أو مصرح لك باختبارها صراحةً.
المؤلف غير مسؤول عن سوء الاستخدام أو الضرر أو فقدان البيانات أو التدخل في ضوابط الأمان أو النشر غير المصرح به.
هذا المشروع مرخص بموجب رخصة GNU العامة العامة الإصدار 3.0.
انظر LICENSE للحصول على التفاصيل.
الهدف الرئيسي من OWN-Defender ليس مجرد إعادة إنتاج تقنية تسجيل مكافحة الفيروسات.
إنه إظهار منهجية هندسة عكسية قابلة للتكرار:
Find
↓
Map
↓
Reverse
↓
Reconstruct
↓
Trace
↓
Implement
↓
Verify
ما بدأ بسؤال حول مركز أمان Windows أصبح استكشافًا أعمق لـ COM وATL ورسم خرائط GUID/IID وvtables والكود المولد من المترجم وWSCAPI وRPC وبنية أمان Windows.
التنفيذ هو النتيجة. عملية الهندسة العكسية هي المشروع الحقيقي.