Что нового

Hex редактирование фаила

maxd2007

Новичок
Сообщения
89
Репутация
0
Версия AutoIt: 3.3.6

Описание: Имеется файл который нужно отредактировать таким образом: в файле ищется фиксированное значение (например "global hex") от него нужно отступить 229 байт и следующие 8 байт забить нулями и так пока не просканирует весь фаил. Буду признателен за помощь ;D
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Попробуйте сделать примерно так.
Создать тестовый файл:
Код:
Local $s_File = @ScriptDir & '\test.txt', $h_File, $s_Txt

$h_File = FileOpen($s_File, 2)
For $j = 1 To Random(30, 50, 1)
	For $i = 1 To Random(30000, 40000, 1)
		$s_Txt &= Chr(Random(33, 126, 1))
	Next
	FileWrite($h_File, $s_Txt)
	$s_Txt = 'global hex'
Next
FileClose($h_File)
Патчить его:
Код:
;~ #include <Constants.au3>

Local $s_File = @ScriptDir & '\test.txt', $s_Search = 'global hex', $i_OffSet = 229, _
		$s_Replace = Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0)

Local $h_FileRead, $h_FileWrite, $i_Size, $s_Txt, $i_LenReplace, $i_Occurrence, $i_Search, $i_Pos, $i_ByteRead = 1024, $i_Count = 0, _
		$i_CountReplace = 0

$i_Size = FileGetSize($s_File)
$h_FileRead = FileOpen($s_File, 0)
If $h_FileRead = -1 Then Exit ConsoleWrite('Error open file' & @LF)
$h_FileWrite = FileOpen($s_File, 1)
If $h_FileWrite = -1 Then Exit ConsoleWrite('Error open file' & @LF)
$i_LenReplace = StringLen($s_Replace)
$i_OffSet += StringLen($s_Search) - 1

While 1
	$s_Txt = FileRead($h_FileRead, $i_ByteRead)
	If @error Then ExitLoop
	$i_Occurrence = 0
	While 1
		$i_Occurrence += 1
		$i_Search = StringInStr($s_Txt, $s_Search, 1, $i_Occurrence)
		If $i_Search Then
			$i_Pos = $i_Search + $i_OffSet + $i_Count * $i_ByteRead
			If $i_Pos + $i_LenReplace - 1 < $i_Size Then
				FileSetPos($h_FileWrite, $i_Pos, 0);$FILE_BEGIN = 0
				FileWrite($h_FileWrite, $s_Replace)
				$i_CountReplace += 1
			EndIf
		Else
			ExitLoop
		EndIf
	WEnd
	$i_Count += 1
WEnd

FileClose($h_FileRead)
FileClose($h_FileWrite)
ConsoleWrite('Replace: ' & $i_CountReplace & @LF)
 
Автор
M

maxd2007

Новичок
Сообщения
89
Репутация
0
madmasles сказал(а):
Попробуйте сделать примерно так.
Создать тестовый файл:
Код:
Local $s_File = @ScriptDir & '\test.txt', $h_File, $s_Txt

$h_File = FileOpen($s_File, 2)
For $j = 1 To Random(30, 50, 1)
	For $i = 1 To Random(30000, 40000, 1)
		$s_Txt &= Chr(Random(33, 126, 1))
	Next
	FileWrite($h_File, $s_Txt)
	$s_Txt = 'global hex'
Next
FileClose($h_File)
Патчить его:
Код:
;~ #include <Constants.au3>

Local $s_File = @ScriptDir & '\test.txt', $s_Search = 'global hex', $i_OffSet = 229, _
		$s_Replace = Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0)

Local $h_FileRead, $h_FileWrite, $i_Size, $s_Txt, $i_LenReplace, $i_Occurrence, $i_Search, $i_Pos, $i_ByteRead = 1024, $i_Count = 0, _
		$i_CountReplace = 0

$i_Size = FileGetSize($s_File)
$h_FileRead = FileOpen($s_File, 0)
If $h_FileRead = -1 Then Exit ConsoleWrite('Error open file' & @LF)
$h_FileWrite = FileOpen($s_File, 1)
If $h_FileWrite = -1 Then Exit ConsoleWrite('Error open file' & @LF)
$i_LenReplace = StringLen($s_Replace)
$i_OffSet += StringLen($s_Search) - 1

While 1
	$s_Txt = FileRead($h_FileRead, $i_ByteRead)
	If @error Then ExitLoop
	$i_Occurrence = 0
	While 1
		$i_Occurrence += 1
		$i_Search = StringInStr($s_Txt, $s_Search, 1, $i_Occurrence)
		If $i_Search Then
			$i_Pos = $i_Search + $i_OffSet + $i_Count * $i_ByteRead
			If $i_Pos + $i_LenReplace - 1 < $i_Size Then
				FileSetPos($h_FileWrite, $i_Pos, 0);$FILE_BEGIN = 0
				FileWrite($h_FileWrite, $s_Replace)
				$i_CountReplace += 1
			EndIf
		Else
			ExitLoop
		EndIf
	WEnd
	$i_Count += 1
WEnd

FileClose($h_FileRead)
FileClose($h_FileWrite)
ConsoleWrite('Replace: ' & $i_CountReplace & @LF)
:laugh: Все работает, спасибо огромное! А не подскажите возможно ли в данный скрипт добавить, что ни будь вроде прогресбара, что бы было видно на какой стадии процесс? Просто фаил объемом 3,5 Гб сканируется примерно 1 минуту и было бы удобно если бы виден был прогресс работы скрипта.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
ma:rofl:2007 [?]
было бы удобно если бы виден был прогресс
Код:
Opt('MustDeclareVars', 1)

Local $s_Dir = @ScriptDir & '\', $s_File = 'test.txt', $s_Search = 'global hex', $i_OffSet = 229, _
		$s_Replace = Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0)

Local $h_FileRead, $h_FileWrite, $i_Size, $s_Txt, $i_LenReplace, $i_Occurrence, $i_Search, $i_Pos, $i_ByteRead = 1024 * 1024, $i_Count = 0, _
		$i_CountReplace = 0, $i_Percent = 0, $i_ReadNow = 0

$i_Size = FileGetSize($s_Dir & $s_File)
$h_FileRead = FileOpen($s_File, 0)
If $h_FileRead = -1 Then Exit ConsoleWrite('Error open file' & @LF)
$h_FileWrite = FileOpen($s_File, 1)
If $h_FileWrite = -1 Then Exit ConsoleWrite('Error open file' & @LF)
$i_LenReplace = StringLen($s_Replace)
$i_OffSet += StringLen($s_Search) - 1
ProgressOn('File patching', $s_File & ' (' & _WinAPI_StrFormatByteSize($i_Size) & ')', StringFormat('Read:  %s, Percent: %.2f%, Replace: %d', _
		_WinAPI_StrFormatByteSize($i_ReadNow), $i_Percent, $i_CountReplace), -1, -1, 16)
While 1
	$s_Txt = FileRead($h_FileRead, $i_ByteRead)
	If @error Then ExitLoop
	$i_ReadNow += @extended
	$i_Occurrence = 0
	While 1
		$i_Occurrence += 1
		$i_Search = StringInStr($s_Txt, $s_Search, 1, $i_Occurrence)
		If $i_Search Then
			$i_Pos = $i_Search + $i_OffSet + $i_Count * $i_ByteRead
			If $i_Pos + $i_LenReplace - 1 < $i_Size Then
				FileSetPos($h_FileWrite, $i_Pos, 0);$FILE_BEGIN = 0
				FileWrite($h_FileWrite, $s_Replace)
				$i_CountReplace += 1
			EndIf
		Else
			ExitLoop
		EndIf
	WEnd
	$i_Count += 1
	$i_Percent = 100 * $i_ReadNow / $i_Size
	ProgressSet($i_Percent, StringFormat('Read:  %s, Percent: %.2f%, Replace: %d', _WinAPI_StrFormatByteSize($i_ReadNow), $i_Percent, $i_CountReplace))
WEnd
FileClose($h_FileRead)
FileClose($h_FileWrite)
HotKeySet('{Esc}', '_Exit')
ProgressSet($i_Percent, StringFormat('Read:  %s, Percent: %.2f%, Replace: %d', _WinAPI_StrFormatByteSize($i_ReadNow), $i_Percent, $i_CountReplace), _
		'Ready! ' & $s_File & ' (' & _WinAPI_StrFormatByteSize($i_Size) & '), Esc - exit.')
While Sleep(100)
WEnd

Func _Exit()
	ProgressOff()
	Exit
EndFunc   ;==>_Exit

Func _WinAPI_StrFormatByteSize($i_Size)
;~ from WinAPIEx.au3
	Local $a_Ret = DllCall('shlwapi.dll', 'ptr', 'StrFormatByteSizeW', 'uint64', $i_Size, 'wstr', '', 'uint', 1024)

	If (@error) Or (Not $a_Ret[0]) Then Return $i_Size & ' byte'
	Return $a_Ret[2]
EndFunc   ;==>_WinAPI_StrFormatByteSize
 
Автор
M

maxd2007

Новичок
Сообщения
89
Репутация
0
Все отлично заработало :laugh: , огромное спасибо!
 
Верх