Вверх ↑
Этот топик читают: Гость
Ответов: 286
Рейтинг: 5
#1: 2021-10-11 13:37:41 ЛС | профиль | цитата
Добрый всем вечер.Пользуюсь Patch Makerом для русификации программ Вот задумался как работает патчер файлов.Понятно что сравниваются два файла новый и старый.А вот где сравниваются?Как?и как заменяются?На хиасме даже не знаю с какой стороны начать.Может кто чем поможет для начала.
карма: 0

0
vip
#1.1контекстная реклама от партнеров
Ответов: 4612
Рейтинг: 746
#2: 2021-10-11 14:05:58 ЛС | профиль | цитата
Вариантов вижу 2.

Первый самый простой - файлы сравниваются во время создания патчера. Затем все остальные разы патчер просто берет конечный файл и заменяет указанные значения в указанных местах файла. Тогда он должен проверить что конечный файл является в точности тем, для которого патчер создавался (например по контрольной сумме). Иначе если файл отличается, то применение патчера нарушит его структуру.

Второй - в файле ищутся фрагменты, которые, надо заменить или перед/после которых надо вставить новые данные. Тогда конечный файл может немного отличаться от оригинального (например, новая версия), но это все равно чревато нарушениями работы пропатченого файла.
карма: 26

0
Ответов: 286
Рейтинг: 5
#3: 2021-10-11 14:25:28 ЛС | профиль | цитата
В случае с русификацией,конечный файл увеличивается и файл работает.Если менять ресурсы и картинки.Смысл как он их сравнивает и заменяет
карма: 0

0
Ответов: 4612
Рейтинг: 746
#4: 2021-10-11 15:02:29 ЛС | профиль | цитата
Ресурсы в файле имеют имена. Ресурсы можно заменять, не нарушая работы файла. Тогда патчер только заменяет ресурсы. Файл может иметь другую версию.
Вопрос в том заменяет ли он ресурс полностью, либо выполняет какое-то слияние. Например, в окне новой версии файла была добавлена кнопка, то при замене ресурса окна на старый она пропадет. А чтобы этого не произошло - патчеру надо знать какие ресурсы отвечают за окно и выполнять умное слияние.

Со строками в ресурсах проще - они заменяются целиком, новые строки просто не затрагиваются (если в новой версии все строки не были перенумерованы).
карма: 26

0
Ответов: 286
Рейтинг: 5
#5: 2021-10-11 15:10:04 ЛС | профиль | цитата
Мне все же кается что замена идет по номерам строк.Так проще.Значит нужно перебрать строки в старом и новом файле и как то зафиксировать изменения
карма: 0

0
Ответов: 4612
Рейтинг: 746
#6: 2021-10-11 18:02:38 ЛС | профиль | цитата
Строки в ресурсах - да, по номерам. Но есть ресурсы, в которых содержится описание окон (интерфейса) программы, например, тип ресурса "RCData" или "Dialog". Их можно заменять целиком, либо пытаться выполнить слияние.
Но ресурсы нельзя заменить простой заменой, если размер оригинального и нового не совпадают. Нужно подвинуть последующие ресурсы и переписать их размеры-расположение в соответствующих местах исполняемого файла.

Редактировалось 1 раз(а), последний 2021-10-11 18:03:45
карма: 26

0
Ответов: 286
Рейтинг: 5
#7: 2021-10-12 14:02:07 ЛС | профиль | цитата
Чет я совсем запутался.Не могу EXE открыть
Add(FileStream,5579189,448,245)
{
Point(doPosition)
link(onLoad,14482734:doConvert,[])
}
Add(Button,6901598,238,245)
{
Left=15
Top=45
link(onClick,10644980:doExecute,[])
}
Add(ODialog,10644980,294,245)
{
link(onExecute,5579189:doOpen,[])
}
Add(Str_Enum,1709012,651,91)
{
link(String,8528982:Text,[(657,79)(629,79)(629,135)(601,135)])
}
Add(Memo,8413688,714,245)
{
Left=120
Top=320
Width=735
Height=195
}
Add(StrList,8528982,595,91)
{
link(onChange,1709012:doEnum,[])
}
Add(MemoryStream,3760439,518,336)
{
}
Add(StreamConvertor,14482734,511,245)
{
link(onResult,8413688:doAdd,[])
}


карма: 0

0
Ответов: 4612
Рейтинг: 746
#8: 2021-10-12 14:43:19 ЛС | профиль | цитата
У компонента StreamConvertor включи верхнюю точку Data и соедини её с точкой Stream компонента FileStream.
Событие onLoad ничего не выдаёт в поток (а описание точки стоило бы поправить).
карма: 26

0
Ответов: 286
Рейтинг: 5
#9: 2021-10-12 14:50:49 ЛС | профиль | цитата
Я так делал.Небольшие екзешники открывает.А если 3-4 мб то виснет
карма: 0

0
Ответов: 4612
Рейтинг: 746
#10: 2021-10-12 15:09:26 ЛС | профиль | цитата
Ну и зачем тогда выложил поломанную схему и сказал что "не могу EXE открыть"?
В Memo по умолчанию буфер 32 Кб. Данные в HEX-представлении занимают в два раза больше исходных.
Не выводи в Memo - не будет виснуть.

Чтение/запись данных в файл происходит с помощью компонента DataToFileEx.

Редактировалось 1 раз(а), последний 2021-10-12 15:34:16
карма: 26

0
Ответов: 286
Рейтинг: 5
#11: 2021-10-13 12:46:59 ЛС | профиль | цитата
С поиском и заменой худо бедно разобрался.
Add(MainForm,160807,168,105){
Width=390
Height=133
Font=[Courier,12,1,0,204]
link(onCreate,9650407:doWork2,[])
}
Add(FileStream,3591058,168,56)
{
link(onLoad,2796801:doCopy,[])
}
Add(Hub,7672151,112,161)
{
OutCount=4
link(onEvent1,3591058:doOpen,[(137,167)(137,62)])
link(onEvent2,3591058:doClose,[(144,174)(144,69)])
link(onEvent3,10431564:doInit,[(137,181)(137,293)])
link(onEvent4,7228710:doFor,[])
}
Add(DropFile,7368331,56,161)
{
link(onDropFile,7672151:doEvent1,[])
}
Add(DataToFileEx,15470337,441,196)
{
DataSize=4
BigEndian=0
Point(Size)
Point(doPosition)
link(Stream,1402459:Var2,[])
}
Add(Hub,15386543,238,182)
{
OutCount=3
link(onEvent1,8850323:doWork1,[(424,188)])
link(onEvent2,5772768:doCompare,[])
link(onEvent3,10431564:doPosition,[(263,202)(263,279)])
}
Add(For,7228710,168,182)
{
IncludeEnd=1
link(onEvent,15386543:doEvent1,[])
link(onStop,10431564:doFinish,[(214,195)(214,286)])
link(End,1272363:Var1,[(181,173)(223,173)(223,250)])
}
Add(ProgressBar,10016673,378,280)
{
Left=26
Top=56
Width=317
Color=15780518
Smooth=1
ProgressColor=-16777203
}
Add(MultiElementEx,10431564,315,273)
{
@Hint=#79:Сервис визуализаци (doPosition) и окончания (doFinish - с сохранением, или без)|
link(onTerminate,3548599:doWork3,[(361,279)])
link(Size,1272363:Var2,[])
link(onPosition,10016673:doPosition,[])
link(onSave,13402507:doAdd,[])
}
BEGIN_SDK
Add(EditMultiEx,5196661,35,63)
{
WorkCount=#44:doPosition=На ходе - текущая позиция в файле|43:doFinish=На входе - позиция окончания цикла|44:doInit=На входе - полное имя входного файла |
EventCount=#56:onTerminate=Преждевременный Close должен остановить цикл|56:onPosition=Установка позиции ProgressBar (по doPosition)|84:onSave=На выходе - полное имя файла для сохранения (если позиция по doFinish < Size)|
DataCount=#17:Size=Размер файла|0:|
Width=370
Height=235
VOffset=35
HOffset=70
link(doPosition,1263160:doOperation,[])
link(doFinish,7671533:doCompare,[(60,111)(60,153)])
link(doInit,15140580:doEvent1,[(53,118)(53,237)])
}
Add(Application,6264518,280,98)
{
Wait=1
Point(onTerminate)
link(onTerminate,5196661:onTerminate,[])
}
Add(Hub,15140580,70,231)
{
OutCount=3
link(onEvent1,16536539:doPart,[])
link(onEvent2,11800802:doPart,[])
link(onEvent3,15798031:doOperation,[])
}
Add(Message,5707167,280,189)
{
Caption="ОК"
Type=2
Icon=3
Point(onYES)
link(onYES,11874295:doExecute,[(326,202)(326,230)])
}
Add(SDialog,11874295,336,224)
{
Point(doFileName)
Point(doStartDir)
link(onExecute,5196661:onSave,[(382,230)(382,118)])
}
Add(FilePartElm,16536539,245,231)
{
link(onPart,11874295:doFileName,[])
}
Add(FilePartElm,11800802,196,238)
{
Mode=0
link(onPart,11874295:doStartDir,[])
}
Add(If_else,7671533,70,147)
{
Type=4
link(onTrue,5887358:doMessage,[])
link(onFalse,3646533:doConvert,[(137,160)(137,188)])
link(Op2,9503147:Var1,[(83,124)])
}
Add(Message,5887358,280,147)
{
Message="Не найдено!"
Caption="Error"
Icon=1
Point(onOK)
link(onOK,6090869:doWork2,[])
}
Add(HubEx,3213293,322,105)
{
link(onEvent,5196661:onPosition,[])
}
Add(ConvertorEx,3646533,147,182)
{
Mode=6
Digits=8
link(onResult,16191573:doStrCatDlm,[])
}
Add(Hub,14634257,245,182)
{
link(onEvent1,6090869:doWork3,[(326,188)])
link(onEvent2,5707167:doMessage,[])
}
Add(HubEx,6090869,322,154)
{
Angle=3
link(onEvent,3213293:doWork3,[])
}
Add(StrCatDelim,16191573,196,182)
{
Str1="Произведена замена по смещению: 0x"
Str2="\r\nСохранить результат ???"
link(onStrCatDlm,14634257:doEvent1,[])
}
Add(Math,1263160,147,98)
{
OpType=3
ResultType=0
link(onResult,3605704:doData,[])
link(Op2,15798031:Result,[(160,89)(125,89)(125,285)(111,285)])
}
Add(GetDataEx,9503147,105,119)
{
link(Data,5196661:Size,[])
}
Add(ChangeMon,3605704,196,98)
{
link(onData,6734111:doEvent1,[])
}
Add(Hub,6734111,245,98)
{
link(onEvent1,6264518:doProcessMessages,[])
link(onEvent2,3213293:doWork2,[])
}
Add(Math,15798031,105,245)
{
OpType=3
Op2=100
link(Op1,9503147:Var2,[])
}
END_SDK
Add(MemoryStream,2796801,441,56)
{
}
Add(Edit,9617539,378,70)
{
Left=245
Top=14
Width=99
Height=30
Font=[Lucida Sans,12,1,0,0]
Hint="Заменить"
Text="000D0AF6"
Alignment=1
DataType=3
ClearAfterEnter=1
AddHint(-21,-38,66,13,Text)
}
Add(If_else,5772768,280,189)
{
link(onTrue,11101815:doEvent1,[])
link(Op1,11534555:Value,[])
link(Op2,15470337:Data,[(293,180)(321,180)(321,243)(447,243)])
}
Add(Hub,11101815,336,189)
{
OutCount=3
link(onEvent1,3548599:doWork2,[])
link(onEvent2,8850323:doWork2,[])
link(onEvent3,8353080:doData,[])
}
Add(DoData,8353080,378,203)
{
link(onEventData,15470337:doPut,[])
link(Data,9617539:Text,[])
}
Add(Memory,11534555,280,119)
{
Point(Data)
link(Data,6642366:Text,[])
}
Add(Edit,6642366,280,70)
{
Left=28
Top=14
Width=99
Height=30
Font=[Lucida Sans,12,1,0,0]
Hint="Найти"
Text="003D0BF6"
Alignment=1
DataType=3
ClearAfterEnter=1
link(onChange,9650407:doWork1,[(326,76)(326,111)(263,111)])
AddHint(-22,-38,66,13,Text)
}
Add(HubEx,9650407,259,119)
{
link(onEvent,11534555:doValue,[])
}
Add(FileStream,10792587,504,273)
{
Mode=1
AutoCopy=0
Point(doCopyFromStream)
}
Add(GetDataEx,1272363,315,245)
{
Angle=1
link(Data,15470337:Size,[(454,250)])
}
Add(MT_Add,13402507,455,287)
{
link(onAdd,10792587:doCopyFromStream,[])
link(Data,1402459:Var3,[(461,180)])
}
Add(GetDataEx,1402459,441,175)
{
link(Data,2796801:Stream,[])
}
Add(HubEx,8850323,420,196)
{
Angle=1
link(onEvent,15470337:doPosition,[(424,216)])
}
Add(HubEx,3548599,357,189)
{
Angle=3
link(onEvent,7228710:doStop,[(361,167)(158,167)(158,195)])
}

А вот как сделать сравнение двух файлов и из первого файла переписать во второй измененные данные

Редактировалось 1 раз(а), последний 2021-10-13 12:49:47
карма: 0

0
Ответов: 4612
Рейтинг: 746
#12: 2021-10-13 13:51:21 ЛС | профиль | цитата
Реализовать алгоритм поиска и сравнения. Файлы читать в память как текст и работать как с текстом, либо работать как с потоками с помощью DataToFileEx.
Алгоритм прикинуть на бумаге/в голове, потом подумать как реализовать. Читаешь фрагмент исходного файла определенной длины, затем в цикле читаешь из другого файла фрагмент такой же длины и сравниваешь. На следующей итерации цикла возвращаешь позицию чтения другого файла на следующий байт, с которого читал предыдущий фрагмент и опять сравниваешь.
Типа:
1) Прочитал строку длиной 5 символов из позиции 0 первого файла
2) Прочитал строку длиной 5 символов из позиции 0 второго файла
3) Сравнил
4) Вернул позицию во втором файла в номер 1 (на второй байт, "предыдущая позиция + 1")
Пункты 2-4 выполняются в цикле, пока весь второй файл не будет прочитан
Пункты 1-4 выполняются в цикле, пока весь первый файл не будет прочитан

Можно читать и сравнивать по 1 байту, если размеры файлов одинаковые. Если размеры разные и в файлах были добавления-перемещения фрагментов - надо думать как это должно работать.


Для записи новых данных в файл - с помощью модицированного DataToFile (оригинальный не умеет писать в файл строку без дополнительных окончаний). Также можно использовать для чтения указанного количества байт (стандартный не умеет).

Редактировалось 2 раз(а), последний 2021-10-13 13:59:34
карма: 26

0
Ответов: 286
Рейтинг: 5
#13: 2021-10-13 15:08:49 ЛС | профиль | цитата
С циклом понятно,разберусь.Получается оба файла нужно читать одновременно?И не могу понять как сделать сравнение.А почему 5 а не 4 или больше символов?
карма: 0

0
Ответов: 4612
Рейтинг: 746
#14: 2021-10-13 15:33:37 ЛС | профиль | цитата
Нужно сформулировать задачу, а затем придумать алгоритм сравнения. Для двоичных файлов это не такая простая задача, поэтому программ для сравнения текстовых файлов есть много, а двоичных - не очень и не всегда они подходят. Да и сравнение текстовых файлов на HiAsm, вероятно, достаточно сложная задача.
Например, можно сравнивать по одному байту и просто выдавать адреса отличающихся байт. Но это не будет работать, если в файле была вставка данных.
Пример:
- исходный файл: 123456789
- новый файл: 123356789
Отличается 1 байт в позиции 4
- исходный файл: 123456789
- новый файл: 1233456789
Что здесь произошло? Отличаются 6 байтов, начиная с позиции 4 и добавлен 1 байт в конце (1233456789) или добавлен 1 байт в позицию 4, а остальные сдвинулись вперед (1233456789)? А как это отличить?

Редактировалось 2 раз(а), последний 2021-10-13 15:37:39
карма: 26

0
Ответов: 286
Рейтинг: 5
#15: 2021-10-13 15:50:43 ЛС | профиль | цитата
Да-а по моему не видать мне своего патчера

--- Добавлено в 2021-10-13 16:12:39

А почему не так
Исходный файл 1234567899876543219800000
Новый файл 1235467899907543219876654
берем по 5 байт
12345 67899 87654 32198 00000
12354 67899 90754 32198 76654
замена------- замена------- замена

Редактировалось 6 раз(а), последний 2021-10-13 16:15:17
карма: 0

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)