Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 6 273

/ вопрос решён /

Здравствуйте, уважаемые эксперты!
Извиняйте, если вдруг пишу не в ту тему.

Суть: имею старый EXE-файл (не Win32), в котором текст приходится постоянно менять HEX-редактором (поиск замена). Поскольку, это не совсем удобно, решил написать программу, которая будет это делать сама (как патч).

Порядок действий следующий:

- Программа загружает EXE-файл
- Выполняет поиск указанных слов внутри EXE
- Заменяет словами из Edit'ов (в Edit'ах поставлю ограничение, дабы не держать текст в "рамках" и не затереть другой код EXE)
- Сохраняет измененный EXE-файл с новым именем без искажений самого EXE (как HEX-редактор).

Мне очень нужен пример, поскольку я ни разу не писал программ такого рода (патчинг Exe-файлов).

Заранее благодарен. Очень надеюсь на ваш ответ :)

Слава Власов Вопрос решён, но можно продолжить его обсуждение в мини-форуме

Вопрос задал: Слава Власов (статус: Посетитель)
Вопрос отправлен: 29 сентября 2012, 19:10
Состояние вопроса: решён, ответов: 1.

Ответ #1. Отвечает эксперт: DNK

Здравствуйте, Слава Власов!
Функция патчинга файла (не проверял).

function ReplaceFile(const fileName, findString, newString: string): boolean;
var
  memStr: TMemoryStream;
  lengthPtr: Integer;
  i: Integer;
begin
  Result := False;
  lengthPtr := Length(findString);
  if lengthPtr <> Length(newString) then
    raise EInvalidOperation.CreateFmt('Сроки "%s" и "%s" имеют разную длину.',
        [findString, newString]);
  memStr := TMemoryStream.Create;
  try
    // загружаем файл в память
    memStr.LoadFromFile(fileName);
    for i := 0 to memStr.Size - lengthPtr do
      // если кусок в памяти совпал со строкой поиска
      if CompareMem(Pointer(integer(memStr.Memory) + i), PChar(findString),
          lengthPtr) then begin
        Result := True;
        // выставляем позицию на проверенный кусок памяти и пишем
        memStr.Seek(i, soFromBeginning);
        memStr.WriteBuffer(PChar(newString)^, lengthPtr);
        Break;
      end;
    // если нашли, сохраняем из памяти в файл
    if Result then
      memStr.SaveToFile(fileName);
  finally
    memStr.Free;
  end;
end;

Ответ отправил: DNK (статус: Студент)
Время отправки: 6 октября 2012, 15:10
Оценка за ответ: 5

Комментарий к оценке: Спасибо! Ваш вариант попробую тоже.

Мини-форум вопроса

Всего сообщений: 14; последнее сообщение — 18 октября 2012, 14:32; участников в обсуждении: 4.
min@y™

min@y™ (статус: Доктор наук), 30 сентября 2012, 09:56 [#1]:

Всё это делается легко и изящно через TFileStream. В принципе, могу написать тебе готовую программу или просто парочку функций (поиска и замены).

Ещё один способ - грузить файл в строку (string) и использовать функции работы со строками (PosEx() и пр.)
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Слава Власов

Слава Власов (статус: Посетитель), 30 сентября 2012, 11:46 [#2]:

Лучше написать готовую. Так мне будет проще понять код (что от чего зависит).
min@y™

min@y™ (статус: Доктор наук), 30 сентября 2012, 12:17 [#3]:

Цитата (Слава Власов):

Лучше написать готовую.

А пиво будет?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Слава Власов

Слава Власов (статус: Посетитель), 30 сентября 2012, 13:45 [#4]:

Могу на Яндекс-кошелек кинуть :)
eclipse

eclipse (статус: Посетитель), 4 октября 2012, 21:11 [#5]:

Ёпт! Яндекс сёдня не в фарте! Скидывай min@y™ на личку... А вообще в твоём варианте всё делается так же как и в обычном txt. Только разница в байтах!
min@y™

min@y™ (статус: Доктор наук), 5 октября 2012, 08:15 [#6]:

Цитата (Слава Власов):

Могу на Яндекс-кошелек кинуть

Какова цена вопроса?
Яндекс-баблом не пользуюсь. Могу принять на сим-карту, если ты в России.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Слава Власов

Слава Власов (статус: Посетитель), 5 октября 2012, 09:56 [#7]:

Да, в России. 200 руб. на пиво хватит ? :-)
min@y™

min@y™ (статус: Доктор наук), 5 октября 2012, 10:24 [#8]:

Когда был студентом, хватило бы.
А с моей зарплатой в 2000+ руб/день за 200 руб. я даже жопу от дивана не оторву.

Однако, тут на портале много студентов. Может они согласятся?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Слава Власов

Слава Власов (статус: Посетитель), 6 октября 2012, 12:07 [#9]:

Ну, во-первых (судя по подписи), речь изначально шла о пиве, а не коньяке. Но, поскольку я в другом городе, мне удобнее отослать деньги.
Во-вторых, мне не нужно программу с детально проработанным интерфейсом. Мне тупо нужен КОД программы, который сможет открыть EXE, найти указанный текст, заменить его на текст из Edit'а и сохранить изменения без повреждения EXE. Т.е. ничего придумывать особо не надо.

Казалось бы все просто, но иметь бы еще представление, каким кодом это сделать...
eclipse

eclipse (статус: Посетитель), 6 октября 2012, 14:19 [#10]:

Ох как все закрутилось! Ну раз тебе нужна прога, неплохо отшлифованная, тогда это тебе влетит в солидную копеечку. Готовься! Закажи у minay эту прошу, не пожалеешь. Нормально все сделает!
Слава Власов

Слава Власов (статус: Посетитель), 6 октября 2012, 14:33 [#11]:

В общем, уже нашел решение, которое более-менее удовлетворяет мои нужды:

procedure TForm1.Button1Click(Sender: TObject);
var
f: file;
l: Longint;
oldstring, newstring, s: string;
begin
oldstring := 'FILE.DAT'; // Что ищем
newstring := Edit1.Text; // На что меняем
 
s := oldstring;
AssignFile(f, 'C:\MY.EXE'); // С каким файлом работаем
Reset(f, 1);
for l := 0 to FileSize(f) - Length(oldstring) - 1 do
begin
Application.ProcessMessages;
Seek(f, l);
BlockRead(f, oldstring[1], Length(oldstring));
if oldstring = s then
begin
Seek(f, l);
BlockWrite(f, newstring[1], Length(newstring));
ShowMessage('String successfully replaced!');
end;
Application.ProcessMessages;
end;
CloseFile(f);
end;
DNK

DNK (статус: Студент), 6 октября 2012, 15:13 [#12]:

Да, немного затянул с отправкой ответа.
"Digital Networked Knight"
DNK

DNK (статус: Студент), 18 октября 2012, 14:18 [#13]:

Что в итоге вышло?
"Digital Networked Knight"
Слава Власов

Слава Власов (статус: Посетитель), 18 октября 2012, 14:32 [#14]:

Открывает EXE-шник, ищет определенный текст и заменяет его текстом из Edit1.

По сути чем-то похоже на функцию Replace Text в Hex редакторе. Только текст для поиска указан заранее. И никаких окон по поиску/замене не выводится. В общем, получилось то, что надо.

18 октября 2012, 21:18: Статус вопроса изменён на решённый (изменил модератор DNK)

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:47
Выполнено за 0.03 сек.