@Drovosek01

Какой нативный способ найти и заменить hex-шаблон байт в Windows?

В macOS и Linux в систему встроены разные консольные утилиты, в том числе perl и sed
С помощью perl и sed (и, возможно, каких-то других) утилит можно написать и выполнить команду, чтобы найти определенную последовательность байт в hex-формате и заменить эту последовательность.

Например так:
perl -pi -e 's/\x74\x7A\xE8\x9D/\x75\x7A\xE8\x9D/g' /путь к бинарнику


Ищу нативный (без установки каких-либо утилит и дополнений) способ в Windows найти hex-байты в бинарнике и заменить их.
Вроде бы с помощью cmd и Powershell такое провернуть нельзя.
Может быть с помощью Visual Basic это можно сделать? Или как-то еще?
Или нативных способов в Windows нет?
  • Вопрос задан
  • 122 просмотра
Решения вопроса 1
@Drovosek01 Автор вопроса
С помощью ChatGPT со второй попытки сделал получил почти готовый к работе скрипт, который решает задачу из заголовка темы.

Вот финальный код:
spoiler

# Main script
param (
    [string]$filePath,
    [string]$searchPattern,
    [string]$replacePattern
)

if (-not (Test-Path $filePath)) {
    Write-Error "File not found: $filePath"
    exit 1
}

# Function to convert hex string to byte array
function Convert-HexStringToByteArray {
    param (
        [string]$hexString
    )
    $hexString = $hexString -replace ' ', ''
    if ($hexString.Length % 2 -ne 0) {
        throw "Invalid hex string length."
    }
    [byte[]]$byteArray = @()
    for ($i = 0; $i -lt $hexString.Length; $i += 2) {
        $byteArray += [Convert]::ToByte($hexString.Substring($i, 2), 16)
    }
    return $byteArray
}

# Function to search and replace hex patterns in a binary file
function SearchAndReplace-HexPatternInBinaryFile {
    param (
        [string]$filePath,
        [string]$searchPattern,
        [string]$replacePattern
    )

    $searchBytes = Convert-HexStringToByteArray -hexString $searchPattern
    $replaceBytes = Convert-HexStringToByteArray -hexString $replacePattern

    if ($searchBytes.Length -ne $replaceBytes.Length) {
        throw "Search and replace patterns must be of the same length."
    }

    [byte[]]$fileBytes = [System.IO.File]::ReadAllBytes($filePath)
    [int]$searchLength = $searchBytes.Length
    [int]$index = 0

    while ($index -lt $fileBytes.Length) {
        $foundIndex = [Array]::IndexOf($fileBytes, $searchBytes[0], $index)

        if ($foundIndex -eq -1) {
            break
        }

        $match = $true
        for ($i = 1; $i -lt $searchLength; $i++) {
            if ($fileBytes[$foundIndex + $i] -ne $searchBytes[$i]) {
                $match = $false
                break
            }
        }

        if ($match) {
            [Array]::Copy($replaceBytes, 0, $fileBytes, $foundIndex, $searchLength)
            $index = $foundIndex + $searchLength
        } else {
            $index = $foundIndex + 1
        }
    }

    [System.IO.File]::WriteAllBytes($filePath, $fileBytes)
}


try {
    SearchAndReplace-HexPatternInBinaryFile -filePath $filePath -searchPattern $searchPattern -replacePattern $replacePattern
    Write-Output "Hex pattern replaced successfully in $filePath"
} catch {
    Write-Error $_.Exception.Message
    exit 1
}



Сохраняем его в файл с расширением .ps1, потом запускаем Powershell и изменяем политику выполнения (иначе получим ошибку при попытке выполнить скрипт)
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned

И потом выполняем скрипт примерно так:
.\test.ps1 -filePath "D:\TEMP\file.exe" -searchPattern "E8961A00000FB6D8488D4C2440FF1548" -replacePattern "11111111111111111111111111111111"

Проверил на .exe размером ~250 МБ и эта операция поиска и замены выполнилась примерно за 3-4 секунды. Не так быстро как хотелось бы, за то без сторонних утилит.

=====

UPDATE:

Я немного разобрался, как работает этот код, и немного его улучшил. Теперь он поддерживает передачу нескольких шаблонов, показывает время выполнения поиска и замены, а также выводит более подробную информацию после работы.

Это все еще не дотягивает до функциональности утилит perl и sed в macOS и Linux.
Вы не сможете использовать регулярные выражения типа "[\x00-\xFF]{17}\xEB\x6F\xD3\x01\x18\x00{3}\xFF{3}\xFE" и вы не сможете ограничить количество совпадений для поиска шаблонов.
Конечно, скрипт можно улучшить и добавить эту функциональность, но текущая реализация покрывает мои потребности.
Надеюсь, кто-нибудь улучшит этот код (функциональность и скорость выполнения)

https://gist.github.com/Drovosek01/9d47068365ea0bc...
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@NortheR73
системный инженер
Вроде бы с помощью cmd и Powershell такое провернуть нельзя
это кто вам такое сказал?
Гугл выдает кучу вариантов - пример
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы