
مجموعة أدوات PowerShell لتحليل حدود الكشف في AMSI/Defender والفرز الثابت للبرمجيات الخبيثة؛ تربط إزاحات البايت بمشغلات الكشف، بالإضافة إلى تحليل YARA والإنتروبيا والسلاسل النصية وPE/imphash. أداة مصاحبة لـ OffsetScan.
أداة PowerShell بذاكرة محدودة لفحص إزاحات البايت، وربط المصادر، ومقارنة الثنائيات، وتحليل حدود الكشف الدفاعي.
تجيب OffsetInspect عن سؤال محلل عملي:
ما المحتوى الموجود عند إزاحة البايت هذه، وما سياق المصدر أو الثنائي المحيط به؟
كما توفر سير عمل أصليًا لحدود الكشف مستوحىً من نفس مشكلة المحلل التي يعالجها ThreatCheck، دون تضمين مصدره أو ملفاته الثنائية: فهي تحدد أقرب بادئة محتوى لا يزال AMSI أو Microsoft Defender يكتشفها، وتتحقق من الحدود مرارًا، وتغذي الإزاحة الناتجة مباشرة إلى مفحص السياق. إضافة إلى ذلك النواة، تضيف مجموعة تحليل للفريق الأحمر وفرزًا ثابتًا - اكتشاف متعدد المناطق، ومسحًا لمجموعة الملفات، ومقارنة نتائج الكشف، وربط مشغلات الكشف، وتوثيق الانحراف، وتقارير المشاركة، وتحليل الإنتروبيا، واستخراج السلاسل النصية، وتحليل PE/imphash - وكلها للقراءة فقط، بالإضافة إلى مختبِر متانة التوقيع المخصص للاستخدام المصرّح به والذي يعدّل العينات في الذاكرة فقط، دون تعطيل أو إعادة تكوين حماية نقطة النهاية على الإطلاق.
للفرز الثابت على نطاق مجموعات الملفات (تحليل PE، والإنتروبيا، والسلاسل النصية، ومؤشرات IOC) دون عبء PowerShell، راجع OffsetScan - ملف ثنائي أصلي بلغة Rust يحمل نفس مخطط إخراج JSON. يستوعب OffsetInspect 3.1.0+ ملفات IOC JSON الصادرة عن OffsetScan مباشرة عبر -IocJsonPath.
-ContextLines.ProbeLog/ProbeCount) لكل استدعاء مميز للمزود، ويُبث مباشرة إلى -Verbose، ليكون نصًا جاهزًا للتقرير عن التكلفة الحقيقية للمزود في الفحص.-CaptureTelemetry): ما إذا تم إطلاق تنبيه Microsoft Defender، وبأي سياق، وما مصادر القياس عن بُعد التي كانت عمياء - مما يطبّق مبدأ "افترض الرؤية، ثم تحقق منها". للقراءة فقط، وبدون صلاحيات المسؤول، وخاص بنظام Windows.¹ هذان الأمران لهما تبعيات خارجية اختيارية: يحتاج Invoke-OffsetYaraScan إلى محرك YARA (winget install VirusTotal.YARA)، ويحتاج Invoke-OffsetClamScan إلى ClamAV مع قواعد بيانات التوقيعات (winget install Cisco.ClamAV، ثم freshclam). كل أمر آخر قائم بذاته. ClamAV هنا كاشف ملف واحد، وليس محرك بحث عن الحدود - clamscan يحمّل قاعدة بياناته الكاملة في كل استدعاء، لذا فإن الانقسام الثنائي يتطلب خدمة clamd.
² Add-OffsetDriftEntry يوثّق على جميع المنصات، لكن حقول إصدار محرك/توقيع Defender تُملأ فقط على ويندوز (عبر Get-MpComputerStatus)؛ وفي الأماكن الأخرى تُسجَّل على أنها فارغة ويستمر كتابة بقية اللقطة.
نواة فحص الإزاحات وجميع أدوات الفرز الثابت متعددة المنصات (ويندوز، لينكس، macOS)؛ بينما مزودا تهديدات AMSI/Defender خاصان بنظام ويندوز.
Install-Module OffsetInspect -Scope CurrentUser Import-Module OffsetInspect
### التحقق من المستودع```powershell
git clone https://github.com/warpedatom/OffsetInspect.git
cd OffsetInspect
Import-Module ./module/OffsetInspect/OffsetInspect.psd1 -Force
يتضمن المستودع أيضًا أغلفة CLI رفيعة:```powershell ./OffsetInspect.ps1 ./OffsetThreatScan.ps1 -Engine AMSI
## فحص الإزاحة
### المخرجات القابلة للقراءة```powershell
Invoke-OffsetInspect ./sample.bin 0x200
### الكائنات المهيكلة```powershell
$inspectParameters = @{
FilePaths = './script.ps1'
OffsetInputs = 0x80, 0x100
PassThru = $true
}
$results = Invoke-OffsetInspect @inspectParameters
$results | Where-Object BytesDiffer
Invoke-OffsetInspect ./sample.bin 0x200 -Json Invoke-OffsetInspect ./sample.bin 0x200 -Csv Invoke-OffsetInspect ./sample.bin 0x200 -CsvPath ./artifacts/offsets.csv
يُصدر وضع JSON دائمًا مصفوفة، حتى بالنسبة لنتيجة واحدة.
### المقارنة الثنائية```powershell
$compareParameters = @{
FilePaths = './before.bin'
OffsetInputs = 0x200
CompareFile = './after.bin'
PassThru = $true
}
Invoke-OffsetInspect @compareParameters
| الإدخال | التفسير |
|---|---|
القيم الرقمية فقط بدون بادئة أو لاحقة تُعامل عمدًا كقيم عشرية.
يُبلغ الإخراج عن كل من BytePositionInLine و CharacterPosition. هذا التمييز مهم عندما يحتوي الملف المصدر على أحرف متعددة البايت.
تحليل مزوّد التهديدات مخصص لنظام Windows فقط. أمر فحص الإزاحة العادي يظل متعدد المنصات.
$scanParameters = @{ FilePath = './script.ps1' Engine = 'AMSI' ScanMode = 'Text' RepeatCount = 3 PassThru = $true } $result = Invoke-OffsetThreatScan @scanParameters
يستخدم الوضع النصي `AmsiScanString`، ويبحث عن بادئات Unicode-scalar دون تقسيم الأزواج البديلة (surrogate pairs)، ويعيّن البادئة المكتشفة عبر ترميز المصدر المُتحقَّق منه، ويعيد فهارس Unicode-scalar ووحدات كود UTF-16 وفهارس البايت في الملف المصدر. تُرفض أحرف NUL المضمّنة في الوضع النصي؛ استخدم وضع البايت الخام (raw-byte) لتلك الملفات.
### فحص AMSI بالبايت الخام```powershell
Invoke-OffsetThreatScan ./content.bin -Engine AMSI -ScanMode RawBytes
$scanParameters = @{ FilePath = './sample.bin' Engine = 'Defender' RepeatCount = 3 TimeoutSeconds = 45 } Invoke-OffsetThreatScan @scanParameters
مزوّد Defender:
- يحدد مسار منصة `MpCmdRun.exe` الأحدث تثبيتًا.
- يكتب البادئات إلى دليل مؤقت فريد للمستخدم.
- يستخدم فحصًا مخصصًا مع `-DisableRemediation`.
- يعامل حالات انتهاء المهلة، وأخطاء المزوّد، والمخرجات المترجمة/غير المعروفة، والعلامات الغامضة على أنها غير حاسمة.
- يحذف مساحة العمل المؤقتة عند اكتمال الفحص.
### دلالات الحدود
نتيجة مثل `DetectionPrefixLength = 841` تعني:
- طول البادئة 840 صُنّف على أنه نظيف/غير مكتشف.
- طول البادئة 841 صُنّف على أنه مكتشف/محظور.
- تتحقق الفحوصات المتكررة من استقرار هذا الانتقال.
هذا **لا** يثبت أن البايت 840 هو التوقيع الكامل، أو البايت الوحيد المساهم، أو النطاق الخبيث بأكمله. قد تعتمد قرارات برامج مكافحة الفيروسات على الترميز tokenization، والسياق المحيط، ونوع الملف، وحالة المزوّد، وتحديثات التوقيعات.
### مثال عملي: محركان، ملف واحد
فحص نفس العينة (PowerUp.ps1، وهو سكربت عام لفريق red-team، بحجم 445,954 بايتًا) باستخدام كلا المزوّدين يُظهر ما هي الحدود وإلى أي مدى يمكن الوثوق بمحركين في الاتفاق. AMSI في وضع النص:```text
Threat boundary scan: C:\Ops\Samples\PowerUp.ps1
SHA-256: 7abc87d9620aef493617a4fc1f823850f32fb26ca9ae0f3befeadb04971e0246
Engine: AMSI
Scan mode: Text
Initial status: Detected
Scans performed: 25
Provider probes: 25 (see -Verbose or the ProbeLog property for the full audit trail)
Duration: 22771.419 ms
Known clean prefix: 445953
Detected prefix: 445954
Boundary offset: 445953 (0x6CE01)
Unicode scalar index: 445953
UTF-16 code-unit idx: 445953
Stable: True
Confidence: High
Line number: 4586
Byte in line: 46
Target byte: 0A (10)
--- Source Context ---
4585 | Set-Alias Get-CurrentUserTokenGroupSid Get-ProcessTokenGroup
4586 | Set-Alias Invoke-AllChecks Invoke-PrivescAudit
^
Microsoft Defender في وضع البايت الخام، نفس الملف:```text Engine: Defender Scan mode: RawBytes Initial status: Detected Scans performed: 25 Duration: 15370.562 ms Known clean prefix: 445951 Detected prefix: 445952 Boundary offset: 445951 (0x6CDFF) Stable: True Confidence: High Signature: Trojan:Win32/Kepavll!rfn
Line number: 4586 Byte in line: 44 Target byte: 69 (105)
--- Hex Dump --- 0006CDBF 74 2D 50 72 6F 63 65 73 73 54 6F 6B 65 6E 47 72 t-ProcessTokenGr 0006CDCF 6F 75 70 0A 53 65 74 2D 41 6C 69 61 73 20 49 6E oup.Set-Alias In 0006CDDF 76 6F 6B 65 2D 41 6C 6C 43 68 65 63 6B 73 20 49 voke-AllChecks I 0006CDEF 6E 76 6F 6B 65 2D 50 72 69 76 65 73 63 41 75 64 nvoke-PrivescAud 0006CDFF 69 74 0A it.
يتقارب المحركان عند **السطر 4586** - تقع حدود Defender داخل `it` الختامي من `Invoke-PrivescAudit`، بينما تقع حدود AMSI على حرف السطر الجديد الذي يختم السطر نفسه، بعد ذلك ببايتين. ولا تمثل أيٌّ من الإزاحتين "التوقيع": فهما أدنى بادئة لا يزال كل مزود يعلّمها، والخلاف البالغ بايتين هو بالضبط تأثير الترميز/السياق الموصوف أعلاه. ويسمّي Defender أيضًا ما طابقه (`Trojan:Win32/Kepavll!rfn`)؛ بينما لا يُبلغ AMSI عن اسم توقيع، ولهذا السبب وُجدت `Invoke-OffsetThreatScanRegion` و`Get-OffsetDetectionTrigger` لتوصيف إصابة AMSI.
بلغت تكلفة الفحصين 25 استطلاعًا للمزوّدين لملف بحجم ~436 KiB - فالتنصيف لوغاريتمي بالنسبة لحجم الملف، ويُسجَّل كل استطلاع في `ProbeLog`.
انظر [تصميم فحص التهديدات](https://github.com/warpedatom/offsetinspect/blob/HEAD/docs/THREAT-SCANNING.md) لعقد المزود وإرشادات التفسير، و[واجهة المزود](https://github.com/warpedatom/offsetinspect/blob/HEAD/docs/PROVIDER-INTERFACE.md) لعقد الماسح الضوئي وكيفية إضافة مزود دون لمس نواة البحث، و[مصدر فحص التهديدات](https://github.com/warpedatom/offsetinspect/blob/HEAD/docs/PROVENANCE.md) لحدود التنفيذ والإسناد، و[مخطط الإخراج](https://github.com/warpedatom/offsetinspect/blob/HEAD/docs/OUTPUT-SCHEMA.md) لعقد الكائن المزوّد بنسخة.
### تقارير حدود الاكتشاف
يحوّل `Export-OffsetThreatReport` نتيجة فحص واحدة أو أكثر إلى تقرير Markdown أو HTML مكتفٍ بذاته - ملخص لكل ملف، وبيانات وصفية للمزود/التوقيع/المحرك، ومسار تدقيق `ProbeLog` الكامل، وتحذيرات - لإرفاقه بتقرير مهمة. يقرأ النتائج فقط ولا يعيد الفحص أبدًا، لذا يعمل عبر المنصات. أضف `-IncludeIoc` لدمج لوحة مؤشرات التجزئة/الإنتروبيا/PE (نفس بيانات `Get-OffsetIOC`) في كل إدخال في التقرير، و`-IncludeTrigger` لإضافة تحليل مُحفِّز الاكتشاف (انظر أدناه) لكل نتيجة لها حد.```powershell
Invoke-OffsetThreatScan ./sample.ps1 -Engine AMSI -ScanMode Text -PassThru |
Export-OffsetThreatReport -Path ./report.html -Format Html
# Aggregate many scans into one report, with an indicators panel and trigger analysis per file:
$results | Export-OffsetThreatReport -Path ./engagement.md -IncludeIoc -IncludeTrigger
لتقارير على نطاق مجموعة الملفات الكاملة، يعيد -IncludeIoc فحص كل ملف في PowerShell، وهذا بطيء. يُصدر المحرك الأصلي المصاحب OffsetScan ملفات IOC JSON مطابقة للمخطط بسرعة أكبر بكثير؛ وجّه التقرير إليه باستخدام -IocJsonPath فيستمد كل لوحة من ذلك JSON (مع التراجع إلى Get-OffsetIOC المباشر فقط للملفات غير الموجودة فيه):```powershell
offsetscan ioc ./corpus --recurse > ./ioc.json
$results | Export-OffsetThreatReport -Path ./engagement.md -IocJsonPath ./ioc.json
### فحص الدُفعات / المجموعات النصية
يوسّع `Invoke-OffsetThreatScanBatch` الملفات والأدلة وأنماط البدل إلى قائمة ملفات، ويفحص كل ملف (متابعًا العمل حتى عند فشل ملف معيّن)، ويعيد نتيجة واحدة لكل ملف. يُرجع `-Summary` مصفوفة اكتشاف مُسطّحة؛ وتُمرَّر النتائج الكاملة مباشرة إلى مولّد التقارير. فحص المزوّد مقتصر على نظام Windows.```powershell
Invoke-OffsetThreatScanBatch ./payloads -Recurse -Engine AMSI |
Export-OffsetThreatReport -Path ./engagement.html -Format Html
Invoke-OffsetThreatScanBatch ./samples -Summary |
Format-Table File, DetectionPrefixLength, Confidence, ProbeCount
تقوم Compare-OffsetThreatResult بمقارنة نتيجتي فحص - على سبيل المثال نفس الملف قبل وبعد تحديث تعريفات التوقيعات - وتصنّف التغيير (NewlyDetected, NoLongerDetected, BoundaryEarlier, BoundaryLater, BoundaryUnchanged, BothClean) مع فرق الحدود والحقول المتغيّرة.```powershell
$before = Invoke-OffsetThreatScan ./sample.ps1 -Engine Defender -PassThru
$after = Invoke-OffsetThreatScan ./sample.ps1 -Engine Defender -PassThru Compare-OffsetThreatResult -Reference $before -Difference $after
### اكتشاف متعدد المناطق
يعثر بحث البادئة على *أول* حد اكتشاف. يعثر `Invoke-OffsetThreatScanRegion` على *مناطق* متعددة قابلة للاكتشاف بشكل مستقل عن طريق تقسيم الملف إلى مقاطع وفحص كل مقطع بمعزل عن الآخرين عبر AMSI **بالكامل في الذاكرة** - لا تتم كتابة أي شيء يتم اكتشافه على القرص، لذا لا يتم أبدًا تشغيل الحماية في الوقت الفعلي لـ Defender أو إعادة تكوينها. يتم تنصيف كل اكتشاف داخل المقطع الخاص به لتعيين الحدود المسببة للإطلاق بدقة إلى إزاحة ملف مطلقة.```powershell
Invoke-OffsetThreatScanRegion ./payload.bin -SegmentCount 16 |
Select-Object -ExpandProperty DetectedRegions |
Format-Table SegmentIndex, StartOffset, EndOffset, AbsoluteBoundaryOffset, SignatureName
يُبلغ هذا عن المناطق التي تُفعَّل من تلقاء نفسها؛ وقد يفوت توقيعات لا تعمل إلا في سياق الملف الكامل أو تلك التي تمتد عبر حد مقطع، لذا تعامل مع المناطق كمؤشرات أولية لتأكيدها باستخدام Invoke-OffsetThreatScan والتحقق اليدوي. AMSI (في الذاكرة) هو المحرك الوحيد المدعوم هنا - فحص ملفات Defender يتطلب كتابة المحتوى المكتشف إلى القرص.
يحدد الحدّ أين ينقلب الكشف؛ ويخبرك Get-OffsetDetectionTrigger بماذا يوجد هناك. وبما أن حد البادئة هو آخر بايت في أقدم بادئة مكتشفة، فإن المحتوى المشغِّل هو سلسلة تنتهي عند ذلك الإزاحة. يبلغ الأمر عن قسم PE الذي يقع فيه الحد، والإنتروبيا للسلسلة حتى ذلك الموضع (نص صريح مقابل مضغوط/مشفر)، والسلاسل المستخرجة التي تنتهي عنده أو تمتد عبره، مرتبة حسب القرب - محتوى التوقيع المرشح - مع تفسير من سطر واحد. يقرأ البايتات فقط ولا يعيد الفحص أبدًا، لذا فهو يعمل عبر المنصات على النتائج المحفوظة.```powershell
Invoke-OffsetThreatScan ./flagged.ps1 -Engine AMSI -PassThru | Get-OffsetDetectionTrigger
Get-OffsetDetectionTrigger -FilePath ./sample.bin -BoundaryOffset 0x4A1 | Select-Object Interpretation, Section, PreBoundaryEntropy -ExpandProperty CandidateStrings
### سجل انحراف الاكتشاف
«كان يُكتشف سابقًا ولم يعد كذلك الآن» له ثلاثة أسباب مختلفة جذريًا: تغيّر الملف، أو تغيّرت التواقيع، أو أن المزوّد غير حتمي. يسجّل `Add-OffsetDriftEntry` لقطات NDJSON للإلحاق فقط - SHA-256 للملف، والحالة، والحدود، واسم التوقيع، وإصدارات توقيع/محرك Defender المحلية - ويقرأ `Get-OffsetDrift` هذا السجلّ وينسب كل تغيير إلى سببه الصحيح.```powershell
# Record a snapshot over time (from a scan result, or directly):
Invoke-OffsetThreatScan ./sample.ps1 -Engine AMSI -PassThru | Add-OffsetDriftEntry
Add-OffsetDriftEntry -FilePath ./sample.ps1 -Status Detected -Engine AMSI -SignatureName 'Trojan:PowerShell/X'
# Later, explain what changed:
Get-OffsetDrift -FilePath ./sample.ps1 | Select-Object -ExpandProperty Transitions
كل انتقال مُوسوم: تغيّر SHA-256 يُقرأ على أنه تعديل ملف؛ تغيّر الحالة مع بقاء الملف دون تغيير ولكن انتقال إصدار توقيع Defender يُقرأ على أنه انجراف التوقيع؛ تغيّر الحالة دون أيٍّ منهما يُقرأ على أنه نتيجة غير حتمية من المزوّد. يقع ملف اليوميات افتراضيًا في %LOCALAPPDATA%\OffsetInspect\drift.ndjson؛ ويمكنك تجاوزه باستخدام -JournalPath.
يُجيب Invoke-OffsetMutationTest عن سؤال في هندسة الكشف: هل التوقيع مطابقة حرفية هشّة، أم أنه متين أمام أساليب الإخفاء الشائعة؟ بالنظر إلى عيّنة يكتشفها AMSI حاليًا، يطبّق تحويرات قياسية - عكس حالة الأحرف، دمج السلاسل النصية الحرفية، إدراج التعليقات، حقن المسافات البيضاء - ويعيد فحص كل متغيّر ليرصد أيّ الفئات تُبطل الكشف. كل شيء يتم في الذاكرة عبر واجهة AMSI داخل العملية؛ لا يُكتب أي متغيّر إلى القرص، وبالتالي لا يتم إنتاج أي آثار مراوغة ولا يتم إشراك الحماية الفورية من Defender. يرفض الأمر التنفيذ بدون -AuthorizedEngagement، وهو مخصّص فقط للعينات التي لديك إذن باختبارها.```powershell
Invoke-OffsetMutationTest -FilePath ./flagged.ps1 -AuthorizedEngagement |
Select-Object RobustnessSummary -ExpandProperty Results
على سبيل المثال، نتيجة مثل "brittle: neutralized by StringConcatenation, CommentInsertion" تخبر المدافع أن التوقيع يعتمد على نص حرفي متصل ويجب توسيعه؛ وتخبر المشغِّل المصرح له الأمر نفسه بشأن تغطية عنصر التحكم.
### ترابط القياس عن بعد
يكشف لك اكتشاف الحدود ما يراه *المحرك*؛ بينما يخبرك `-CaptureTelemetry` بما يراه *المدافع*. فهو يلتقط علامة الحد الأقصى لكل سجل قياس عن بعد يمكن الوصول إليه في Windows قبل الفحص، ثم يبلّغ ما إذا كان الإجراء قد أثار تنبيهًا، وبأي سياق، وأي المصادر كانت عمياء - سؤال "افترض الرؤية، ثم تحقق منها" مجابٌ عليه بالأدلة.```powershell
$r = Invoke-OffsetThreatScan ./flagged.ps1 -Engine AMSI -CaptureTelemetry -PassThru
$r.Telemetry | Format-List AlertGenerated, CorrelationConfidence, Findings
$r.Telemetry.Alert | Format-List ThreatName, SeverityName, SourceName, ProcessName, DetectionUser
الخاصية Telemetry (OffsetInspect.TelemetryCorrelation) تُبلِغ عن التالي:
AlertGenerated / Alert - ما إذا كان اكتشاف من Microsoft Defender (الحدث 1116/1117) قد سُجِّل للفحص، وسياقه (اسم التهديد، الخطورة، مصدر الاكتشاف، العملية، المستخدم).CorrelationConfidence - High فقط عندما يتطابق مصدر الاكتشاف مع المزوِّد وتتطابق عمليته مع المضيف المُجري للفحص، بحيث لا يُدَّعى أبدًا اكتشاف متزامن مصادَف؛ Medium عند تطابق المصدر فقط؛ Low عند عدم تحقق أيٍّ منهما.SourcesAccessible / SourcesUnavailable - أي سجلات التليمتري كانت قابلة للقراءة وأيها كانت عمياء (غياب Sysmon، وسجل الأمان الذي يتطلب صلاحيات مرتفعة). فجوة الرؤية بحد ذاتها تُعد استنتاجًا.Findings - استنتاجات بلغة بسيطة: تنبيه بسياق كامل، تنبيه يفتقر إلى اسم تهديد، عدم وجود تليمتري إطلاقًا، أو مصدر مفقود.المصدر الأساسي هو سجل Microsoft Defender التشغيلي (Operational)، وهو قابل للقراءة دون رفع الصلاحيات؛ يتم الربط عبر RecordId الخاص بالحدث (قيمة رتيبة التزايد ومستقلة عن المنطقة الزمنية). خاص بنظام Windows فقط، وهو خامل ما لم يتم تمرير -CaptureTelemetry.
ثلاثة أوامر تحليل ثابت متعددة المنصات تدعم فرز البرمجيات الخبيثة وتتكامل مع نواة الإزاحة:
Get-OffsetEntropy - إنتروبيا شانون لكل نافذة (بت/بايت) لتحديد المناطق المضغوطة أو المشفرة؛ طابق النوافذ المُعلَّمة مع اكتشافات Invoke-OffsetThreatScanRegion.Get-OffsetString - السلاسل النصية القابلة للطباعة بصيغتي ASCII وUTF-16LE مع إزاحات البايت؛ مرّر الإزاحات عبر الأنبوب (pipe) إلى Invoke-OffsetInspect للحصول على السياق.Get-OffsetPEInfo - نوع آلة PE (machine)/عرض البتات (bitness)، نقطة الدخول، جدول الأقسام، الاستيرادات وimphash، اكتشاف الـoverlay المُلحَق، وحجم الموارد، مع -Offset الذي يربط إزاحة البايت بقسمها (.text, .rsrc, ...). يستخدم imphash خوارزمية MD5 القياسية بصيغة library.function، مع التحقق من تطابقه بايتًا ببايت مع pefile/VirusTotal - بما في ذلك حلّ الترتيبيات (ordinals) للمكتبات الخاصة، بحيث يُحل الترتيبي المستورد من ws2_32/wsock32/oleaut32 إلى اسم دالته الحقيقي؛ بينما يُخرَج أي استيراد ترتيبي آخر بصيغة ، تمامًا كما يفعل pefile.### فحص YARA
تقوم `Invoke-OffsetYaraScan` بتشغيل قواعد YARA التي يكتبها المحللون وتُعيد كل تطابق مع إزاحة البايت الخاصة به - مكمّلةً بذلك عرض حدود الكشف في AMSI/Defender بتوقيعات تتحكم فيها أنت، ولا تتطلب تثبيت برنامج مكافحة فيروسات (فقط محرك YARA، مثلًا `winget install VirusTotal.YARA`). تُغذّى الإزاحات مباشرةً إلى المفتّش.```powershell
Invoke-OffsetYaraScan ./sample.bin -RulePath ./rules/malware.yar |
ForEach-Object { Invoke-OffsetInspect $_.File $_.Offset -ContextLines 2 }
يقوم Invoke-OffsetClamScan بفحص ملف باستخدام محرك ClamAV للفحص عند الطلب ويعيد نتيجة موحّدة (Clean / Detected / Error، بالإضافة إلى اسم التوقيع). نظرًا لأن clamscan يحمّل قاعدة بيانات التوقيعات الكاملة في كل استدعاء، فهو كاشف لملف واحد وليس محرك بحث بالحدود (وهذا يتطلب البرنامج الخفي clamd). يتطلب تثبيت ClamAV و تنزيل قواعد بيانات التوقيعات الخاصة به - لن يعمل freshclam حتى يوجد ملف إعداد:```powershell
Copy-Item "$env:ProgramFiles\ClamAV\conf_examples\freshclam.conf.sample" "$env:ProgramFiles\ClamAV\freshclam.conf" (Get-Content "$env:ProgramFiles\ClamAV\freshclam.conf") -notmatch '^\sExample\s$' | Set-Content "$env:ProgramFiles\ClamAV\freshclam.conf" # requires admin to write under Program Files & "$env:ProgramFiles\ClamAV\freshclam.exe"
Invoke-OffsetClamScan ./sample.bin
استخدم `-DatabasePath` للإشارة إلى دليل توقيعات في موقع قابل للكتابة (غير مخصص للمسؤول)، و`-ClamScanPath` إذا لم يكن `clamscan` في `PATH`.
## كائنات النتيجة
يُرجع `Invoke-OffsetInspect -PassThru` كائنات `OffsetInspect.Result` تحتوي على:
- مسار الملف الأساسي، حجم الملف، الإزاحات العشرية والست عشرية.
- الترميز المطلوب والمكتشف.
- رقم السطر، معاينة المصدر، أسطر السياق، موضع البايت، وموضع الحرف.
- البايت المستهدف وإلقاء سداسي عشري محدود النطاق.
- بايت المقارنة الاختياري وحالة الاختلاف.
- التحذيرات، المدة، حالة النجاح، ورسالة الخطأ.
يُرجع `Invoke-OffsetThreatScan -PassThru` كائنات `OffsetInspect.ThreatScanResult` تحتوي على:
- SHA-256 للملف، الطابع الزمني للمسح بصيغة UTC، المحرك، وضع المسح، الحالة الأولية للمزوّد، وبيانات المزوّد الوصفية.
- أطوال البادئة المعروفة بأنها نظيفة والمعروفة بأنها مكتشفة.
- حد البايت وحد الحرف الاختياري.
- الاستقرار، الثقة، عدد مرات المسح، حالات الحدود المتكررة، واسم التوقيع عند توفره.
- مسار تدقيق `ProbeLog` لكل استعلام مورّد متميز (يظهر كـ `ProbeCount` في مخرجات CSV، ويمكن تصديره إلى نص JSON مع `-ProbeLogPath`)؛ انظر [مخطط الإخراج](https://github.com/warpedatom/offsetinspect/blob/HEAD/docs/OUTPUT-SCHEMA.md).
- سياق `OffsetInspect.Result` المتداخل عند الحد المعيّن.
## نموذج الأداء
التنفيذ على نمط الإصدار 1 كان يعيد قراءة ملف كامل وفك ترميزه لكل إزاحة. الإصدار 2 يجمع العمل حسب الملف:```text
Previous approach: approximately O(file size × offset count)
Version 2: approximately O(file bytes scanned once + requested windows)
يستخدم تعيين المصدر آلة حالة متدفقة ويحتفظ فقط بواصفات الأسطر السابقة/التالية اللازمة للإزاحات المطلوبة. تُعرض الأسطر الفردية الطويلة للغاية عبر معاينة محدودة يتحكم فيها -MaxLineBytes.
OffsetInspect.ps1 Thin offset-inspection CLI wrapper OffsetThreatScan.ps1 Thin threat-scan CLI wrapper module/OffsetInspect/ Complete Gallery package OffsetInspect.psd1 OffsetInspect.psm1 OffsetInspect.Format.ps1xml Public/ Private/ tests/ Pester tests benchmarks/ Reproducible performance harness build/ Validation, packaging, signing, publishing .github/workflows/ CI, dependency review, release publishing docs/ Architecture, schemas, provider design, release checklist
## التطوير
قم بتثبيت أدوات التحقق المثبّتة على إصدارات محددة:```powershell
Install-Module Pester -RequiredVersion 5.7.1 -Scope CurrentUser
Install-Module PSScriptAnalyzer -RequiredVersion 1.25.0 -Scope CurrentUser
شغّل البوابة المحلية الكاملة:```powershell ./build/Test-Module.ps1
شغّل منصة الاختبار المرجعي الحتمية:```powershell
./benchmarks/Measure-OffsetInspect.ps1 -FileSizeMiB 64 -OffsetCount 5000
تختلف نتائج قياس الأداء حسب التخزين، وحمل المضيف، وإصدار PowerShell، وشكل الملف. سجّل هذه المدخلات عند مقارنة الالتزامات.
أنشئ أرشيف إصدار حتمي، وملف SHA-256:```powershell ./build/New-ReleasePackage.ps1
يتحقق CI من PowerShell 7 على Windows وLinux، وWindows PowerShell 5.1، وPSScriptAnalyzer، وتغليف الوحدة النمطية المعزولة، وأرشيف الإصدار. ينبغي على مشرفي الإصدارات أيضًا اتباع [قائمة مراجعة الإصدار](https://github.com/warpedatom/offsetinspect/blob/HEAD/docs/RELEASE-CHECKLIST.md).
## الأمان والاستخدام المسؤول
OffsetInspect مخصص للبحث الدفاعي المصرح به، وهندسة الكشف، والهندسة العكسية، وتحليل البرامج الضارة، واختبار الأمان. تحلل دوال موفّر التهديدات المحتوى، لكنها لا تعطّل حمايات نقاط النهاية أو تتجاوزها أو تعيد تكوينها.
`Invoke-OffsetMutationTest` يُنشئ متغيرات مراوغة للكشف لتقييم متانة التوقيعات. يعمل بالكامل في الذاكرة (لا تتم كتابة أي متغير على القرص)، ويرفض التشغيل دون الإقرار الصريح بـ `-AuthorizedEngagement`. استخدمه فقط مع العينات وعناصر التحكم المصرح لك باختبارها.
راجع [SECURITY.md](https://github.com/warpedatom/offsetinspect/blob/HEAD/SECURITY.md) قبل الإبلاغ عن ثغرة أمنية. لا ترسل عينات حساسة عبر مشكلات GitHub العامة.
## الترخيص
يُصدر OffsetInspect بموجب [رخصة MIT](https://github.com/warpedatom/offsetinspect/blob/HEAD/LICENSE).
Get-OffsetSignature): باستخدام تحقق الثقة الحقيقي للمنصة، يبلّغ ما إذا كان الملف موقّعًا وموثوقًا به بشكل صحيح، ومن وقّعه، وما إذا كان موقّعًا بشكل مضمّن أو عبر كتالوج - إشارة موقّع تكمل imphash وبصمة سلسلة أدوات البناء (الاستيرادات مقابل سلسلة الأدوات مقابل الموقّع). خاص بنظام Windows.| Command | الغرض | المنصة |
|---|
Invoke-OffsetInspect | تعيين إزاحات البايت إلى سياق المصدر/الثنائي، والسداسي العشري، والمقارنة | متعدد المنصات |
Invoke-OffsetThreatScan | البحث عن حدود الكشف عبر AMSI/Defender لملف واحد | ويندوز |
Invoke-OffsetThreatScanBatch | فحص مجموعة ملفات؛ -Summary يُرجع مصفوفة كشف | ويندوز |
Invoke-OffsetThreatScanRegion | اكتشاف متعدد المناطق عبر فحص AMSI داخل الذاكرة (بدون كتابة على القرص) | ويندوز |
Invoke-OffsetMutationTest | اختبار متانة التوقيع: تعديل عينة تم اكتشافها في الذاكرة، وتحديد التحويلات التي تفلت من الكشف (للاستخدام المصرّح به فقط) | ويندوز |
Compare-OffsetThreatResult | مقارنة نتيجتي فحص (مثلًا عبر تحديثات تعريفات التوقيع) | متعدد المنصات |
Get-OffsetDetectionTrigger | ربط حد الكشف بالمحتوى الأكثر ترجيحًا الذي أثار الكشف | متعدد المنصات |
Add-OffsetDriftEntry | تسجيل لقطة كشف (تجزئة الملف + إصدار توقيع Defender) في سجل | متعدد المنصات² |
Get-OffsetDrift | شرح كيفية تغيّر قابلية اكتشاف الملف: تغيّر الملف مقابل تحديث التوقيع مقابل عدم الحتمية | متعدد المنصات |
Export-OffsetThreatReport | عرض نتائج الفحص في تقرير مشاركة Markdown/HTML | متعدد المنصات |
Invoke-OffsetYaraScan | مطابقة ملف مع قواعد YARA؛ إرجاع الإصابات مع إزاحات البايت | متعدد المنصات¹ |
Invoke-OffsetClamScan | فحص ملف بمحرك ClamAV؛ نتيجة كشف موحّدة | متعدد المنصات¹ |
Get-OffsetEntropy | إنتروبيا شانون لكل نافذة لتحديد المناطق المضغوطة/المشفرة | متعدد المنصات |
Get-OffsetString | استخراج سلاسل ASCII/UTF-16LE مع إزاحات البايت | متعدد المنصات |
Get-OffsetPEInfo | رؤوس PE، والأقسام، والاستيرادات/imphash، وoverlay، والإزاحة→القسم | متعدد المنصات |
Get-OffsetIOC | لوحة مؤشرات موحّدة: التجزئات، والإنتروبيا، وPE/imphash، والسلاسل | متعدد المنصات |
Get-OffsetSignature | توقيع Authenticode: هل الملف موقّع وموثوق به بشكل صحيح، ومن وقّعه، مضمّن أم عبر كتالوج | ويندوز |
512| عدد عشري 512 |
0x200 أو 0X200 | سداسي عشري 0x200 |
200h | سداسي عشري 0x200 |
E1AB1 | سداسي عشري بدون بادئة لأنه يحتوي على A-F |
| النمط | السلوك |
|---|
Auto | يكتشف تواقيع BOM لـ UTF-8/UTF-16؛ وإلا يستخدم UTF-8 |
Default | يستخدم الترميز الافتراضي لنظام التشغيل المضيف |
UTF8 | تخطيط مصدر UTF-8 |
UTF16LE | تخطيط مصدر UTF-16 بنمط little-endian |
UTF16BE | تخطيط مصدر UTF-16 بنمط big-endian |
ASCII | تخطيط مصدر ASCII |
ordNNNGet-OffsetIOC - لوحة مؤشرات لمرة واحدة تجمع ما سبق: MD5/SHA-1/SHA-256 (تمريرة واحدة)، الإنتروبيا الكلية، عدد السلاسل القابلة للطباعة، ونوع آلة PE/imphash/overlay عندما ينطبق ذلك.```powershell
Get-OffsetEntropy ./sample.bin -HighOnly | Select-Object -ExpandProperty Windows
Get-OffsetString ./sample.bin -MinimumLength 6 | Where-Object Value -match 'http|.dll'
Get-OffsetPEInfo ./sample.exe | Select-Object Machine, EntryPointHex, ImpHash, ImportedDllCount, HasOverlay, OverlaySize
Get-OffsetIOC ./sample.exe | Format-List