Войти

Показать полную графическую версию : Замена текста с помощью VBScript при условии?!


Страниц : [1] 2 3

Hraniti
10-08-2018, 07:53
Здравствуйте, пытаюсь реализовать скрипт который будет находить нужное мне значение например 1134 и заменять на 1401 при условии что 1134 должно находится между dota_camera_pitch_max и dota_camera_distance.

Const ForReading = 1
Const ForWriting = 2

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\1111\client.dll", ForReading)

strText = objFile.ReadAll
objFile.Close
strNewText = Replace(strText, "1134", "1401")

Set objFile = objFSO.OpenTextFile("C:\1111\client.dll", ForWriting)
objFile.WriteLine strNewText
objFile.Close

На текущий момент есть первая версия скрипта, но не знаю как сделать условия? что бы значение менялось только в указанных рамках?

Iska
10-08-2018, 11:04
Hraniti, лучше не пытайтесь работать таким кодом с бинарными файлами, коими являются библиотеки.

Как надо:

берёте конкретную версию библиотеки;
берёте правильный hex-редактор;
открываете в нём библиотеку;
ищете потребное значение и находите;
делаете потребную замену;
на основе сделанной замены создаёте патч для исходной библиотеки.

megaloman
10-08-2018, 11:08
Hraniti, Если тупо решать задачу как поставлено (Iska наверняка прав!) то вместо Вашего реплэйса lstrText = LCase(strText)
marg1 = InStr(1, lstrText, "dota_camera_pitch_max")
marg2 = InStr(1, lstrText, "dota_camera_distance")
repstr = Mid(strText, marg1, marg2 - marg1)

strNewText = Replace(strText, repstr, Replace(repstr, "1134", "1401"))
Если 1134 между указанными строками встречается многократно, то заменятся все.

Hraniti
10-08-2018, 11:09
Iska, Я понимаю что не надо, но давайте попробуем реализовать как я прошу попробовать. Ну если есть возможность можете более детальней объяснить как сделать эту надобность.

Iska
10-08-2018, 11:14
Hraniti, упаковываете Вашу библиотеку в архив, каковой прикладываете к сообщению. Если сюда не помещается — выкладываете на DropMeFiles (https://dropmefiles.com/).

Hraniti
10-08-2018, 12:02
megaloman,

Const ForReading = 1
Const ForWriting = 2

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Program Files (x86)\Steam\steamapps\common\dota 2 beta\game\dota\bin\win64\client.dll", ForReading)

lstrText = LCase(strText)
marg1 = InStr(1, lstrText, "dota_camera_pitch_max")
marg2 = InStr(1, lstrText, "dota_camera_distance")
repstr = Mid(strText, marg1, marg2 - marg1)

strNewText = Replace(strText, repstr, Replace(repstr, "1134", "1401"))

Set objFile = objFSO.OpenTextFile("C:\Program Files (x86)\Steam\steamapps\common\dota 2 beta\game\dota\bin\win64\client.dll", ForWriting)
objFile.WriteLine strNewText
objFile.Close

Пишет ошибку

Iska
10-08-2018, 12:42
Option Explicit

Const strPath2Client = "C:\Мои проекты\0180\client.dll"

Dim strContent
Dim objRegExp


With WScript.CreateObject("Scripting.FileSystemObject")
If .FileExists(strPath2Client) Then

With .OpenTextFile(strPath2Client)
strContent = .ReadAll()
.Close
End With

Set objRegExp = WScript.CreateObject("VBScript.RegExp")

objRegExp.Pattern = "(dota_camera_pitch_max\x00{3})1134(\x00{4}dota_camera_distance)"

If objRegExp.Test(strContent) Then
With .CreateTextFile(strPath2Client, True)
.Write objRegExp.Replace(strContent, "$11401$2")
.Close
End With
Else
WScript.Echo "Can't find pattern [" & Replace(objRegExp.Pattern, Chr(0), " ") & "] in source file [" & strPath2Client & "]."
WScript.Quit 2
End If

Set objRegExp = Nothing
Else
WScript.Echo "Can't find source file [" & strPath2Client & "]."
WScript.Quit 1
End If
End With

WScript.Quit 0

Hraniti
13-08-2018, 11:29
Iska, Выдает ошибку и данные не меняются. скриншот прилагаю.

Hraniti
13-08-2018, 11:30
Вот собственно сам файл https://yadi.sk/d/q-nkzoD_3a692L

Iska
13-08-2018, 13:21
Вот собственно сам файл https://yadi.sk/d/q-nkzoD_3a692L »
Дружище, попробуйте, ради интереса, сами найти в нём dota_camera_pitch_max и dota_camera_distance. Или хотя бы одно из них.

Hraniti
13-08-2018, 14:28
Iska, Спасибо что помогаете. вот скриншот

Iska
13-08-2018, 14:54
Hraniti, не нахожу. Контрольные суммы выложенного client.dll приведите.
CRC32: 1453ECB7
MD5: 22A7A67509A454059CC83D58B0A6B0B5
SHA1: 07DA4D35F4CA0B3F2A1FAF95D9E76D210A38D919
SHA256: 4BD116EF090741FCF1CB08388BCDCB80859558E82826C4433BD7DB3616443B4B

Возьмите HxD - Freeware Hex Editor and Disk Editor | mh-nexus (https://mh-nexus.de/en/hxd/), откройте им client.dll, найдите и укажите точное значение смещения.

Hraniti
13-08-2018, 17:20
Iska, Откройте через Notepad++

Iska
13-08-2018, 18:04
Hraniti, я открывал и через Notepad++. Нету.

Мы можем долго играть в угадайку. Повторяю: приведите контрольные суммы для файла client.dll и укажите точное значение смещения, где находится 1134 (или dota_camera_pitch_max, или dota_camera_distance).

Hraniti
14-08-2018, 07:36
Iska, понял. на всякий случай перезалил файл https://yadi.sk/d/UnQmDTD43aCgLd
Вот данные контрольной суммы.
MD5: 4DD79EB8E0EB3DF55618C1145CED6AB8
SHA1: 24E680C045016DB05F291D8B9588275659BE6821
SHA256: A09E4A300F16AF502095CC0B9D8A3193D8499E4676BA5736BA94213FD334B446

Если открыть notepad без переноса строк, интересующая информация содержится на 290877 строчке.
dota_camera_pitch_max 1134 dota_camera_distance Скриншот notepad++ с данными с точным нахождением данных прилагаю.

Пустота вокруг 1134 это знак NUL.

Iska
14-08-2018, 09:28
Вот данные контрольной суммы.
MD5: 4DD79EB8E0EB3DF55618C1145CED6AB8
SHA1: 24E680C045016DB05F291D8B9588275659BE6821
SHA256: A09E4A300F16AF502095CC0B9D8A3193D8499E4676BA5736BA94213FD334B446 »
Как видите, контрольные суммы ранее выложенного файла и текущего не совпадают. Банально не совпадают и размеры файлов. Вот так.

На PowerShell это может выглядеть так:
$sPath2Client = 'C:\Мои проекты\0183\client.dll'

if([System.IO.File]::Exists($sPath2Client)) {
$sContent = Get-Content -Path $sPath2Client -Raw
$oRegExp = [System.Text.RegularExpressions.Regex]::new('(dota_camera_pitch_max\x00{3})1134(\x00{4}dota_camera_distance)')

if($oRegExp.IsMatch($sContent)) {
$oRegExp.Replace($sContent, '${1}1401${2}') | Set-Content -Path $sPath2Client -NoNewline
} else {
Write-Host "Can't find pattern [$oRegExp] in source file [$sPath2Client]." -ForegroundColor Red
}
} else {
Write-Host "Can't find source file [$sPath2Client]." -ForegroundColor Red
}
С WSH наблюдаются определённые проблемы при попытках работы с данным файлом как с текстом, возможно из-за большого количества символов 0x00, не работает не то что поиск по регулярному выражению, так и банальная функция InStr. Возможно, получится поиграться с классом ADODB.Stream, посмотрю, что можно будет сделать.

Iska
15-08-2018, 08:44
На WSH:
Option Explicit

Const strPath2Client = "C:\Мои проекты\0183\client.dll"

Const adTypeBinary = 1
Const adTypeText = 2

Const adSaveCreateOverWrite = 2

Const intBufferSize = 512

Const strFindString = "1134"
Const strReplaceString = "1401"


Dim strPattern
Dim strBlockSignature

Dim strContent
Dim lngFileSize

Dim i
Dim arrContent()

Dim lngFoundPosition


strPattern = "dota_camera_pitch_max" & String(3, Chr(0)) & strFindString & String(4, Chr(0)) & "dota_camera_distance"
strBlockSignature = ConvertByteArray2HexString(ConvertString2ByteArray(strPattern))

With WScript.CreateObject("Scripting.FileSystemObject")
If .FileExists(strPath2Client) Then
WScript.StdOut.WriteLine "Source file [" & strPath2Client & "] exists."

lngFileSize = .GetFile(strPath2Client).Size

With WScript.CreateObject("ADODB.Stream")
.Type = adTypeBinary
.Open

WScript.StdOut.WriteLine "Read content."
.LoadFromFile(strPath2Client)

ReDim arrContent(lngFileSize \ intBufferSize)

For i = 0 To lngFileSize - 1 Step intBufferSize
arrContent(i \ intBufferSize) = ConvertByteArray2HexString(.Read(intBufferSize))
WScript.StdOut.Write "Convert content into hex string: " & FormatNumber(i / (lngFileSize - 1) * 100, 2) & "%" & vbCr
Next

WScript.StdOut.WriteLine

strContent = Join(arrContent, "")

lngFoundPosition = InStr(strContent, strBlockSignature)

If lngFoundPosition > 0 Then
WScript.StdOut.WriteLine "Search pattern [" & strPattern & "] found."

.Position = lngFoundPosition \ 2

WScript.StdOut.WriteLine "Write new content [" & Replace(strPattern, strFindString, strReplaceString) & "] into source file [" & strPath2Client & "]."

.Write ConvertString2ByteArray(Replace(strPattern, strFindString, strReplaceString))
.SaveToFile strPath2Client, adSaveCreateOverWrite
.Close
Else
WScript.StdOut.WriteLine "Can't find search pattern [" & strPattern & "] in content of source file [" & strPath2Client & "]."
WScript.Quit 2
End If
End With
Else
WScript.StdOut.WriteLine "Can't find source file [" & strPath2Client & "]."
WScript.Quit 1
End If
End With

WScript.Quit 0
'=============================================================================

'=============================================================================
Function ConvertByteArray2HexString(arrByteArray)
Dim i
Dim strValue

strValue = ""

For i = 1 To LenB(arrByteArray)
strValue = strValue & Right("00" & Hex(AscB(MidB(arrByteArray, i, 1))), 2)
Next

ConvertByteArray2HexString = strValue
End Function
'=============================================================================

'=============================================================================
Function ConvertString2ByteArray(strValue)
With WScript.CreateObject("ADODB.Stream")
.Type = adTypeText
.CharSet = "windows-1251"
.Open
.WriteText strValue
.Position = 0
.Type = adTypeBinary
ConvertString2ByteArray = .Read()
.Close
End With
End Function
'=============================================================================

Придётся набраться терпения: перевод массива байт, c которыми VBScript напрямую работать не может, в строку — процесс весьма не быстрый (у меня занимает десять-пятнадцать секунд, ужас). Пробуйте.

Hraniti
15-08-2018, 09:06
Iska, Мне не хватает ума запустить этот код. я правильно понимаю, мне нужно создать файл с расширением .WSH? или мне нужно просто выполнить данный код через консоль?

Разобрался. у меня порядка минуты уходит что бы выполнился этот код. очень долго.

Iska
15-08-2018, 09:23
я правильно понимаю, мне нужно создать файл с расширением .WSH? »
Нет, создайте файл с расширением .vbs (это скрипт Windows Script Host со входным языком VBScript). .wsh — это файл настроек для скрипта, создавать такой файл Вам не нужно.

у меня порядка минуты уходит что бы выполнился этот код. очень долго. »
Ото ж. У меня заметно меньше, но всё равно это дико долго выходит. Увы и ах — WSH, в отличие от VB/VBA, не работает напрямую с байтовыми массивами (Byte()).

Hraniti
15-08-2018, 09:27
Iska, Понятно. Спасибо вам большое что помогли найти выход из ситуации. не буду писать хоть и такой долгий.. по времени быстрей самому открыть найти и заменить в ручную. думал об более быстром варианте. Ну в любом случае это работает.




© OSzone.net 2001-2012