
PowerShell-инструментарий для анализа границ обнаружения AMSI/Defender и статической триаж-сортировки вредоносных программ, сопоставляет смещения байтов с триггерами обнаружения, а также включает анализ YARA, энтропии, строк и PE/imphash. Дополнение к OffsetScan.
Инструментарий PowerShell с ограниченным потреблением памяти для проверки байтовых смещений, корреляции с исходным кодом, сравнения двоичных файлов и анализа границ обнаружения в целях защиты.
OffsetInspect отвечает на практический вопрос аналитика:
Какое содержимое находится по этому байтовому смещению, и какой исходный или бинарный контекст его окружает?
Он также предоставляет собственный рабочий процесс определения границ обнаружения, вдохновлённый той же задачей аналитика, которую решает ThreatCheck, без включения в комплект его исходников или бинарников: он находит самый ранний префикс содержимого, который AMSI или Microsoft Defender всё ещё обнаруживает, многократно проверяет границу и передаёт полученное смещение напрямую инспектору контекста. Поверх этого ядра он добавляет набор для red-team анализа и статической триаж-сортировки — обнаружение нескольких регионов, сканирование корпуса, сравнение результатов обнаружения, корреляцию триггеров обнаружения, ведение журнала дрейфа, отчёты об испытаниях, энтропийный анализ, извлечение строк и парсинг PE/imphash — всё только для чтения, плюс тестер устойчивости сигнатур для авторизованного использования, который изменяет образцы только в памяти и никогда не отключает и не перенастраивает защиту конечных точек.
Для статического триажа в масштабе корпуса (парсинг PE, энтропия, строки, IOC) без
накладных расходов PowerShell используйте OffsetScan
— нативный бинарник на Rust с той же схемой вывода JSON. OffsetInspect 3.1.0+
принимает IOC JSON от OffsetScan напрямую через -IocJsonPath.
-ContextLines.ProbeLog/ProbeCount) каждого отдельного вызова провайдера, передаваемый в реальном времени в -Verbose, для готовой к отчёту расшифровки фактической стоимости провайдера при сканировании.¹ У этих двух команд есть опциональные внешние зависимости: Invoke-OffsetYaraScan требует движок YARA (winget install VirusTotal.YARA), а Invoke-OffsetClamScan требует ClamAV с базами сигнатур (winget install Cisco.ClamAV, затем freshclam). Все остальные команды автономны. Здесь ClamAV — детектор для одиночных файлов, а не движок поиска границ: clamscan загружает полную базу при каждом вызове, поэтому для бисекции потребовался бы демон clamd.
² Add-OffsetDriftEntry ведёт журнал кроссплатформенно, но поля версии сигнатур/движка Defender заполняются только в Windows (через Get-MpComputerStatus); в других системах они записываются как null, а остальная часть снимка всё равно сохраняется.
Ядро проверки смещений и все вспомогательные средства статической сортировки кроссплатформенны (Windows, Linux, macOS); провайдеры угроз AMSI/Defender доступны только в Windows.
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
$ ls -l ~/.arduino15/packages/ATTinyCore/hardware/avr/1.5.2```powershell $inspectParameters = @{ FilePaths = './script.ps1' OffsetInputs = 128, 256, 512 ByteWindow = 64 ContextLines = 4 } Invoke-OffsetInspect @inspectParameters
### Структурированные объекты```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
### AMSI-сканирование в режиме сырых байтов
Текстовый режим использует `AmsiScanString`, ищет префиксы, состоящие из скалярных значений Unicode, не разбивая суррогатные пары, пропускает обнаруженный префикс через проверенную кодировку источника и возвращает индексы скалярных значений Unicode, кодовых единиц UTF-16 и байтов исходного файла. Встроенные NUL-символы в текстовом режиме отклоняются; для таких файлов используйте режим сырых байтов.```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 является полной сигнатурой, единственным влияющим байтом или полным вредоносным диапазоном. Решения антивируса могут зависеть от токенизации, окружающего контекста, типа файла, состояния провайдера и обновлений сигнатур.
### Пример из практики: два движка, один файл
Сканирование одного и того же образца (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 в режиме raw-byte, тот же файл:```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 КиБ — биссекция логарифмична по размеру файла, и каждая проба фиксируется в `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
### Multi-region discovery
The prefix search finds the *first* detection boundary. `Invoke-OffsetThreatScanRegion` finds *multiple* independently-detectable regions by splitting the file into segments and scanning each in isolation through AMSI **entirely in memory** - nothing detected is written to disk, so Defender real-time protection is never triggered or reconfigured. Each hit is bisected within its segment to map the exact triggering boundary to an absolute file offset.
---
### Обнаружение нескольких регионов
Префиксный поиск находит *первую* границу обнаружения. `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, читаемый без повышения привилегий; корреляция осуществляется по RecordId события (монотонный и не зависящий от часового пояса). Только для Windows и неактивен, если не передан -CaptureTelemetry.
Три кроссплатформенных команды статического анализа поддерживают триаж вредоносных программ и сочетаются с ядром поиска по смещениям:
Get-OffsetEntropy — для каждого окна энтропия Шеннона (бит/байт) для поиска упакованных или зашифрованных областей; сверяйте отмеченные окна с детекциями Invoke-OffsetThreatScanRegion.Get-OffsetString — печатные строки ASCII и UTF-16LE со смещениями в байтах; передавайте смещения в Invoke-OffsetInspect для контекста.Get-OffsetPEInfo — машинный тип/разрядность PE, точка входа, таблица секций, импорты и imphash, определение дописанного оверлея и размер ресурсов, с -Offset, сопоставляющим байтовое смещение с его секцией (.text, .rsrc, ...). Imphash использует стандартный MD5 в формате library.function и побайтово совпадает с pefile/VirusTotal — включая разрешение ординалов из специальных библиотек, поэтому ординал, импортированный из 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`, содержащие:
- Канонический путь к файлу, размер файла, десятичные и шестнадцатеричные смещения.
- Запрошенную и обнаруженную кодировки.
- Номер строки, предпросмотр исходного текста, строки контекста, позицию байта и позицию символа.
- Целевой байт и ограниченный hex-дамп.
- Необязательный сравниваемый байт и состояние расхождения.
- Предупреждения, длительность, состояние успеха и сообщение об ошибке.
`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` на сопоставленной границе.
## Модель производительности
Реализация в стиле v1 перечитывала и декодировала полный файл для каждого смещения. Версия 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 issues.
## Лицензия
OffsetInspect распространяется под [лицензией MIT](https://github.com/warpedatom/offsetinspect/blob/HEAD/LICENSE).
-CaptureTelemetry): было ли создано оповещение Microsoft Defender, с каким контекстом, и какие источники телеметрии оказались «слепыми» — воплощая принцип «исходи из видимости, затем проверяй её». Только чтение, без прав администратора, только Windows.Get-OffsetSignature): используя реальную проверку доверия платформы, сообщает, является ли файл действительным и доверенным по подписи, кто его подписал, а также является ли подпись встроенной или каталоговой, — сигнал подписанта, дополняющий imphash и отпечаток цепочки сборки (импорты против цепочки инструментов против подписанта). Только Windows.| Команда | Назначение | Платформа |
|---|
Invoke-OffsetInspect | Сопоставляет байтовые смещения с контекстом исходного кода/бинарника, hex и сравнением | Кроссплатформенно |
Invoke-OffsetThreatScan | Поиск границы обнаружения AMSI/Defender для одного файла | Windows |
Invoke-OffsetThreatScanBatch | Сканирует корпус файлов; -Summary возвращает матрицу обнаружений | Windows |
Invoke-OffsetThreatScanRegion | Обнаружение нескольких областей через AMSI в памяти (без записи на диск) | Windows |
Invoke-OffsetMutationTest | Проверка устойчивости сигнатур: изменение обнаруженного образца в памяти, отчёт о том, какие трансформации уклоняются (только для авторизованного использования) | Windows |
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: действительно ли файл подписан и доверен, кем, встроенная или каталоговая подпись | Windows |
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 с прямым порядком байт |
UTF16BE | Сопоставление исходного текста UTF-16 с обратным порядком байт |
ASCII | Сопоставление исходного текста ASCII |
ordNNNGet-OffsetIOC — панель индикаторов за один проход, объединяющая перечисленное: MD5/SHA-1/SHA-256 (за один проход), общая энтропия, количество печатных строк, а также машинный тип/imphash/оверлей PE, если применимо.```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