Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » PowerShell - [решено] Поиск hex значения в файле, замена значения на заданное, сохранение файла

Ответить
Настройки темы
PowerShell - [решено] Поиск hex значения в файле, замена значения на заданное, сохранение файла

Старожил


Сообщения: 286
Благодарности: 10

Профиль | Отправить PM | Цитировать


Изменения
Автор: 9119
Дата: 02-08-2021
Добрый.

Сейчас делаю так:
Есть файл, скажем B2DD.tmp. около 20МБ.
Открываю его в hex редакторе, нахожу нужное а именно (35 32 88 65 59 18 01).
Важно! сама искомая комбинация выглядит так: 08 3А 35 32 88 65 59 18 01, но почему то по полному запросу не находит.
Меняю полную найденную строку на 08 8A XX XX XX XX XX XX XX. Сохраняю файл.


Можно ли это проделать в powershell? без использования hex-редактора.
Или с помощью любой другой консольной утилиты. (если можно с примерами)
Спасибо.

Отправлено: 15:36, 02-08-2021

 

Старожил


Сообщения: 286
Благодарности: 10

Профиль | Отправить PM | Цитировать


DJ Mogarych, я наверное криво объясняю...простите.


Значение которое находится в файле - всегда одно (08 3a 35 32 88 65 59 18)
ЗначениЙ которыми искомое заменяется - НЕ ОДНО! Их список. Скажем 10 шт.
Файлов TMP тоже НЕ ОДИН.
Т.е сначала находим в первом файле 1.tmp значение 08 3a 35 32 88 65 59 18 и меняем на 08 8a XX XX XX XX XX XX 01
Потом берется следующий 2.TMP файл. В нем опять находится все тоже 08 3a 35 32 88 65 59 18, но меняется уже на следлующее значение из списка
08 8a XX XX XX XX XX XX 02.... и так далее пока не закончатся строки в списке.

Отправлено: 11:31, 03-08-2021 | #11



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1171
Благодарности: 487

Профиль | Отправить PM | Цитировать


Цитата 9119:
Что значение не одно. »
Пост выше дополнил, это должно помочь

-------
scio me nihil scire. Ѫ

Это сообщение посчитали полезным следующие участники:

Отправлено: 11:32, 03-08-2021 | #12


Аватара для DJ Mogarych

fascinating rhythm


Moderator


Сообщения: 6494
Благодарности: 1466

Профиль | Отправить PM | Цитировать


9119, надо всегда описывать задачу целиком, это избавит от двойной работы.
Как определять соответствие файлов списку, т. е., как понять, в каком файле какое значение в списке применять?

-------
Powershell 7.x | Powershell 5.1 | ffmpeg (docs)

Это сообщение посчитали полезным следующие участники:

Отправлено: 11:40, 03-08-2021 | #13


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1171
Благодарности: 487

Профиль | Отправить PM | Цитировать


Цитата 9119:
* строки в txt подогнаны под формат 0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX
как сделать, чтобы в [byte[]]$rep в вашем коде попадала сначала первая строка, потом вторую и т.д? »
Чтобы считывать из текстового файла строковые значения и преобразовывать их в массив байтов, можно сделать, что-то типа:
Код: Выделить весь код
gc test.txt|%{
    [byte[]]$a = $_ -split ','
    # здесь организовать вызов функции с передачей параметра $a
}

-------
scio me nihil scire. Ѫ


Отправлено: 11:43, 03-08-2021 | #14


Старожил


Сообщения: 286
Благодарности: 10

Профиль | Отправить PM | Цитировать


Цитата YuS_2:
Пост выше дополнил, это должно помочь »
да действительно, так мне проще. Один нюанс.
Стартую ваш скрипт так:
Код: Выделить весь код
$list = Get-content C:\Users\Administrator\Desktop\list.txt
$number = 0
$my_data = ($list)[$number]
.\find_replace.ps1 -fin (0x08,0x3A,0x35,0x32,0x88,0x65,0x59,0x18,0x01) -rep ($my_data)
$number = $number + 1
$my_data
pause
при запуске получаю следующее:
Код: Выделить весь код
PS C:\Users\Administrator\Desktop\script_PS> ./start.ps1
find_replace.ps1: C:\Users\Administrator\Desktop\script_PS> ./start.ps1:4
Line |
   4 |  : 1 -fin (0x08,0x3A,0x35,0x32,0x88,0x65,0x59,0x18,0x01) -rep ($my_data)
     |                                                               ~~~~~~~~~~
     | Cannot process argument transformation on parameter 'rep'. Cannot
     | convert value "0x08,0x8a,0x26,0x41,0x07,0x04,0x38,0x40,0x21" to type
     | "System.Byte[]". Error: "Cannot convert value
     | "0x08,0x8a,0x26,0x41,0x07,0x04,0x38,0x40,0x21" to type "System.Byte".
     | Error: "Additional non-parsable characters are at the end of the
     | string.""
0x08,0x8a,0x26,0x41,0x07,0x04,0x38,0x40,0x21
Press Enter to continue...:
list.txt:
Код: Выделить весь код
0x08,0x8a,0x26,0x41,0x07,0x04,0x38,0x40,0x21
0x08,0x8a,0x26,0x41,0x07,0x04,0x38,0x40,0x97
0x08,0x8a,0x26,0x41,0x07,0x04,0x38,0x30,0x12
0x08,0x8a,0x26,0x41,0x07,0x04,0x38,0x40,0x83
0x08,0x8a,0x26,0x41,0x07,0x04,0x38,0x40,0x40
0x08,0x8a,0x26,0x41,0x07,0x04,0x38,0x70,0x10

DJ Mogarych,
пример списка привел, файлы всегда одинаковые по размеру, имеют просто разные имена, но все всегда содержат одну и туже искомую строку:
0x08,0x3A,0x35,0x32,0x88,0x65,0x59,0x18,0x01, которую нужно находить и менять на значение из списка.
Пример файла выкладывал на 1ой странице

Последний раз редактировалось 9119, 03-08-2021 в 11:53.


Отправлено: 11:47, 03-08-2021 | #15


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1171
Благодарности: 487

Профиль | Отправить PM | Цитировать


Цитата 9119:
при запуске получаю следующее: »
Там должна быть не строка, а массив байтов...
В общем, сделайте лучше так:
Пример для трех файлов и трех шаблонов замены:
Код: Выделить весь код
function Replace-Bytes {
	param(
		$file = '.\F0D7.tmp',
		$fout = '.\F0D7_1.tmp',
		[byte[]]$fin = (0x08,0x3A,0x35,0x32,0x88,0x65,0x59,0x18,0x01),
		[byte[]]$rep = (0x08,0x8A,0x34,0x31,0x87,0x64,0x58,0x17,0x00)
	)
	
	$bytes = [io.file]::readallbytes($file)
	$i = -1
	$a = -join $fin
	do {
		$i = [byte[]]::indexof($bytes,$fin[0],($i+1))
		[byte[]]$tmp = @()
		for ($k = $i; $k -lt ($i+$fin.count);$k++){
			$tmp += $bytes[$k]
		}
		$b = -join $tmp
	} while ($a -ne $b)
	for ($j,$n=0,$i;$j -lt $rep.count;$n++,$j++){
		$bytes[$n] = $rep[$j]
	}
	[io.file]::writeallbytes($fout, $bytes)
}

[byte[]]$findb = 0x08,0x3A,0x35,0x32,0x88,0x65,0x59,0x18,0x01
# количество шаблонов должно соответствовать количеству файлов
$files = '.\F0D1.tmp','.\F0D2.tmp','.\F0D3.tmp' # 3 файла
$frep = gc test.txt # здесь в файле содержится 3 строки шаблонов замены

0..2|%{
	replace-bytes -file $files[$_] -fout "fout$($_+1).tmp" -fin $findb -rep $([byte[]]($frep[$_] -split ','))
}

-------
scio me nihil scire. Ѫ

Это сообщение посчитали полезным следующие участники:

Отправлено: 12:04, 03-08-2021 | #16


Аватара для YuS_2

Crazy


Contributor


Сообщения: 1171
Благодарности: 487

Профиль | Отправить PM | Цитировать


Цитата DJ Mogarych:
Как определять соответствие файлов списку, т. е., как понять, в каком файле какое значение в списке применять? »
9119, Кстати, да... это важное замечание.
Чтобы не путаться в шаблонах и файлах, проще создавать файл в формате CSV, с содержимым типа:
Цитата:
File,Pattern
F0D1.tmp,"0x08,0x5A,0x54,0x51,0x57,0x54,0x78,0x77,0x10"
F0D2.tmp,"0x08,0x8A,0x34,0x31,0x87,0x64,0x58,0x17,0x00"
F0D3.tmp,"0x08,0x9A,0x24,0x21,0x27,0x24,0x28,0x27,0x20"
Функция не меняется, а вот запуск действий, будет выглядеть так:
Код: Выделить весь код
...
[byte[]]$findb = 0x08,0x3A,0x35,0x32,0x88,0x65,0x59,0x18,0x01
$list = import-csv test.csv

for ($i=0;$i -lt $list.count;$i++){
	replace-bytes -file $list.file[$i] -fout "fout$($i+1).tmp" -fin $findb -rep $([byte[]]($list.pattern[$i] -split ','))
}
- в этом случае, не придется вручную указывать количество файлов/шаблонов, скрипт сам посчитает количество и сделает замену, по списку из файла test.csv

-------
scio me nihil scire. Ѫ

Это сообщение посчитали полезным следующие участники:

Отправлено: 12:27, 03-08-2021 | #17


Старожил


Сообщения: 286
Благодарности: 10

Профиль | Отправить PM | Цитировать


YuS_2, с задачей немного не идет это просто.

Суть в том, что изначально есть только список значений для замены в файлах, а списка файлов нет. Файл tmp на момент выполнения скрипта - только один.

Запускается exe, который кладет файл.tmp во временную папку (каждый запуск exe имя файла меняется и это имя каждый раз рандомное я его не знаю!)
Далее я получаю имя этого файла (получаю все файлы tmp и сортирую по дате изменения, беру первый в списке) и кладу в переменную.
нахожу в нем искомое и меняю на строку из txt файла.
Далее запускаю опять этот же exe. Опять появляется новый tmp файл. опять получаю его в переменную. и делаю замены, но беру уже следующую строку из txt файла.... и так далее... пока не закончатся строки в txt файле.

Отправлено: 12:36, 03-08-2021 | #18


Аватара для DJ Mogarych

fascinating rhythm


Moderator


Сообщения: 6494
Благодарности: 1466

Профиль | Отправить PM | Цитировать


Тогда надо запускать не .exe, а скрипт, который будет запускать .exe, а потом обрабатывать его выхлоп, и писать в отдельный файл номер последней использованной строки.

Что будет, когда строки в файле закончатся?

-------
Powershell 7.x | Powershell 5.1 | ffmpeg (docs)

Это сообщение посчитали полезным следующие участники:

Отправлено: 12:51, 03-08-2021 | #19


Старожил


Сообщения: 286
Благодарности: 10

Профиль | Отправить PM | Цитировать


DJ Mogarych, когда строки закончатся - должно об этом сообщить и стать на паузу.

Для себя все таки максимально удобным считаю вариант запуска основного скрипта с параметрами от ув. YuS_2. http://forum.oszone.net/post-2963519-8.html


Стартовать пытаюсь его скрипт так:
Код: Выделить весь код
$file = Get-ChildItem -Path "C:\Windows\Temp" -recurse -include *.tmp | Sort-Object LastAccessTime -Descending | Sort-Object -Descending -Property length | Select-Object -First 1 |%{$_.FullName}
$list = Get-content C:\Users\Administrator\Desktop\list.txt
$number = 0
$my_data = ($list)[$number]
pause
.\find_replace.ps1 -file ($file) -fin (0x08,0x3A,0x35,0x32,0x88,0x65,0x59,0x18,0x01) -rep ($my_data)
$number = $number + 1
$my_data
$file
pause
Пожалуйста, помогите правильно передать $my_data в -rep.
чтобы строка передалась как набор байтов, и дальнейший скрипт её "схавал")
Пока получаю это:
Код: Выделить весь код
find_replace.ps1: C:\Users\Administrator\Desktop\script_PS\start.ps1:6
Line |
   6 |  : ) -fin (0x08,0x3A,0x35,0x32,0x88,0x65,0x59,0x18,0x01) -rep ($my_data)
     |                                                               ~~~~~~~~~~
     | Cannot process argument transformation on parameter 'rep'. Cannot
     | convert value "0x08,0x8a,0x26,0x41,0x07,0x04,0x38,0x40,0x21" to type
     | "System.Byte[]". Error: "Cannot convert value
     | "0x08,0x8a,0x26,0x41,0x07,0x04,0x38,0x40,0x21" to type "System.Byte".
     | Error: "Additional non-parsable characters are at the end of the
     | string.""
* может нужно к какому-то виду привести сам список..

Последний раз редактировалось 9119, 03-08-2021 в 13:13.


Отправлено: 13:02, 03-08-2021 | #20



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » PowerShell - [решено] Поиск hex значения в файле, замена значения на заданное, сохранение файла

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
VBA - Редактировать hex значения в файле blackeangel Программирование и базы данных 14 21-05-2019 16:33
CMD/BAT - [решено] замена значения в xml-файле firstarey Скриптовые языки администрирования Windows 20 13-11-2017 11:24
VBS/WSH/JS - поиск значения в текстовом файле и выбор данной строки God-of-Chaos Скриптовые языки администрирования Windows 10 07-06-2015 19:06
работа с файлами в HEX формате, поиск и замена по 16ричному адресу значения в файле. andr_mozg AutoIt 3 10-03-2012 10:20
CMD/BAT - [решено] Поиск файла, значения в файле и создания для них переменных popoves Скриптовые языки администрирования Windows 4 29-02-2012 20:59




 
Переход