Сейчас на форуме: zds (+5 невидимых)

 [email protected] —› Программирование —› Патчинг ехе
Посл.ответ Сообщение

Ранг: 1.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 10 марта 2014 13:49
· Личное сообщение · #1

Здравствуйте! Появилась необходимость отредактировать некий ехе файл, тобиш открыть его, найти необходимую мне строку ( в программе она используется в чистом виде в функции MessageBox ) и заменить эту строку на свою. Делаю я это так:

Code:
  1. var BCount, Address, PAddress: Integer;
  2.     i: Integer;
  3.     Success: Boolean;
  4. begin
  5.    i := 0;
  6.    Address := 0;
  7.    PAddress := 0;
  8.    B := AsciiToBin(Edit1.Text);
  9.  
  10.    FileStrm := TFileStream.Create(MFileName,fmOpenReadWrite);
  11.    try
  12.      while true do begin
  13.        BCount:=FileStrm.Read(Buffer,66532);
  14.        Address := Address+BCount;
  15.        PAddress := PAddress+BCount;
  16.        if QSearch(Buffer, B) = Length(B)-1 then begin
  17.          Address := Address-(BCount-i);
  18.          FileStrm.Seek(Address,soBeginning);
  19.          FileStrm.Write(Pointer(B2),Length(B2));
  20.          FileStrm.Seek(PAddress,soBeginning);
  21.          Success := True;
  22.        end;
  23.        if BCount = 0 then
  24.           Break;
  25.      end;
  26.    finally
  27.      FileStrm.Free;
  28.      if Success then begin
  29.        MessageBox(Handle,'Пропатчил ага!','',MB_ICONINFORMATION)
  30.      end else
  31.      MessageBox(Handle,'Ошибка патча!','Ошибка',MB_ICONERROR);
  32.    end;


Заменяет все безупречно, проблема не в этом, а в том что заменять можно строкой не длиньше оригинальной, если сделать длиньше то она перейдет уже на следующий параметр функции MessageBox. Думал я думал что же с этим можно сделать, придумал разделять файл на 2 части и собирать в 1, тобиш копируем память от начала файла до конечного байта того чем мы заменили, дальше копируем от конечного байта оригинальной строки и сохраняем в конце концов, ну что то в этом роде:

Code:
  1. StringStream := TMemoryStream.Create;
  2.  
  3.              StringStream.SetSize(Length(B2));
  4.              StringStream.Position := 0;
  5.              StringStream.Write(Pointer(B2),Length(B2));
  6.              StringStream.Position := 0;
  7.  
  8.              FileStrm.Position := 0;
  9.              NewFile.CopyFrom(FileStrm,Address);
  10.              NewFile.CopyFrom(StringStream,Length(B2));
  11.  
  12.              FileStrm.Position := Address+Length(B);
  13.              FileStrm.Seek(Address+Length(B), soFromBeginning);
  14.  
  15.              NewFile.CopyFrom(FileStrm,FileStrm.Size-FileStrm.Position);


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

Подскажите пожалуйста что можно с этим сделать, может можно как то создать переменную, в нее записать строку и MessageBox-у втюхать ее?




Ранг: 60.7 (постоянный), 12thx
Активность: 0.040
Статус: Участник
KpTeaM

Создано: 10 марта 2014 14:45 · Поправил: Runtime_err0r
· Личное сообщение · #2

А строка не в ресурсах хранится? Может, проще редактором ресурсов воспользоваться?
А так - находишь свободное место в файле, пишешь туда свой текст и передаешь смещение в качестве параметра функции MessageBox



Ранг: 1.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 10 марта 2014 15:00
· Личное сообщение · #3

Да он есть в ресурсах в секции CODE. Ага так, нашел свободное место в файле, записал туда строку, но как передать параметр MessageBox что бы он не считал его за строку?



Ранг: 42.2 (посетитель), 42thx
Активность: 0.040
Статус: Участник

Создано: 10 марта 2014 15:16 · Поправил: kid
· Личное сообщение · #4

DarkSmile пишет:
но как передать параметр MessageBox что бы он не считал его за строку?

взорвало мозг

--> MSDN:MessageBox function <--

Code:
  1. int WINAPI MessageBox(
  2.   _In_opt_  HWND hWnd,
  3.   _In_opt_  LPCTSTR lpText,
  4.   _In_opt_  LPCTSTR lpCaption,
  5.   _In_      UINT uType
  6. );


Вы передаете указатель , а что будет находиться по данному указателю - решать вам



Ранг: 1.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 10 марта 2014 16:02
· Личное сообщение · #5

Дак указатель то куда передавать???




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 10 марта 2014 16:05
· Личное сообщение · #6

Почитал бы ты основы, мсдн, как функции на асме вызываются, как параметры передаются.



Ранг: 42.2 (посетитель), 42thx
Активность: 0.040
Статус: Участник

Создано: 10 марта 2014 16:21
· Личное сообщение · #7

DarkSmile пишет:
Дак указатель то куда передавать???


код вызова будет таким (или почти таким)

Code:
  1. push 0x40  //MB_ICONINFORMATION flag
  2. push 0x00123456 //offset caprion text
  3. push 0x00654321 //offset message text  - тут вам надо заменить указатель на свой 
  4. push 0x00 //hwnd
  5. call MessageBox


| Сообщение посчитали полезным: DarkSmile

Ранг: 4.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 30 марта 2014 12:06
· Личное сообщение · #8

Привет!
Решил не создавать новую тему, так как название этой идеально подходит.
У меня вопрос чуть посложнее. Вот такой:

<<Я модифицирую одну старую игру начала 90х, и в общем-то основная цель уже выполнена, но я перфекционист и захотел изменить начальное интро таким образом, чтобы в нем отразить все изменения в программе, которые были сделаны с ее создания. Изначально там есть строка о том, что она "Programmed in 1992 on AT .286 12MHz", я хотел добавить строку "Cracked in 1993 on some old junk" и "Unpassworded in 2014 on PB DOTS 1.5GHz", а также явно указать имя начального разработчика, взломщика и себя.
Так вот, первая строка уже содержится в секции данных в файле. Я нашел очевидно неиспользуемую функцию вывода еще нескольких строк с именами разработчиков, которая почему-то в игре нигде не используется. Изменил функцию интро, добавив в нее прыжок на неиспользуемую, там изменил смещения на строки и прыжок на первую функцию. В самом конце файла, там, где, в общем-то, на первый взгляд одни данные, добавил новые строки. Изменил заголовок: Pages in file: B2, Bytes on last page: 1A0 -> Pages in file: B3, Bytes on last page: 0 соответственно новому размеру. Смещения на новые строки я вычислил теоретически верно: выяснил базу, отняв от адреса одной из старых строк в файле смещение, по которому к ней обращались и отняв эту базу от адреса новой строки. Все инструкции работают, но вместо строк рисуются непечатные блоки, то есть очевидно что программа не видит новых строк. Вопрос: чего я не учел?>>



Ранг: 33.9 (посетитель), 22thx
Активность: 0.030
Статус: Участник

Создано: 30 марта 2014 12:37
· Личное сообщение · #9

senyuki пишет:
чего я не учел?

наверное то, что нужно бинарник прикладывать к сообщению



Ранг: 4.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 30 марта 2014 12:53
· Личное сообщение · #10

Sou ka. Это верно.

Функция, рисующая интро, начинается по адресу 2808. Новые строки в конце файла.

fc03_30.03.2014_EXELAB.rU.tgz - prel.exe




Ранг: 337.6 (мудрец), 224thx
Активность: 0.210.1
Статус: Участник
born to be evil

Создано: 30 марта 2014 16:34 · Поправил: ajax
· Личное сообщение · #11

senyuki
это MZ-файл --> Link <--, есть сегменты и оффсеты
Pages in file: B2, Bytes on last page: 1A0 -> Pages in file: B3, Bytes on last page: 0
как пример корректного размера:
Bytes on last page: 01A0
Pages in file: 0015
14*512t+1a0 = 10656 (размер файла)

и там оверлей щас "нарисовался" из-за корявого исправления
два - 0А03
похоже на сегмент данных, вроде как он всегда в коде с релоками. без оффсета в файле, где и что правилось - я хз, как угадать

-----
От многой мудрости много скорби, и умножающий знание умножает печаль




Ранг: 4.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 30 марта 2014 16:40 · Поправил: senyuki
· Личное сообщение · #12

Эм, ну так я и правил из
Pages in file: B2, Bytes on last page: 000001A0
в
Pages in file: B3, Bytes on last page: 00000000

Разве что мискликнул случайно?

"надо нулями добивать, или еще что."
А... в этом плане.

Знаю, что .ЕХЕ, знаю, что сегменты, но с таблицей релокации так и не разобрался пока за этот день, пока пытаюсь понять ее практическую суть. Она везде упоминается, но нигде толково не ясно наглядно. Теоретически что-то везде сказано, перебазирование сегментов и смещений, бла-бла-бла, все такое, но как это действует реально - неясно. Вот у меня в программе несколько раз в ds заносится А03. Это значение несколько раз содержится в таблице настройки, четырехбайтный формат. Два байта - какие-то величины, два - 0А03. Глубинный смысл этого я ухватить никак не могу, как ни пытаюсь. Медитация не помогает.
Все, с таблицей вроде суть ухватил

Короче в сторону чего мне снова копать? Дело в таблице настройки?

Что-то странное, редактирую заголовок, и при нажатии F3 на поле Bytes on last page автоматически изменяется поле Pages in file с В3 на В2... Проверил физ. размер файла... посчитал на калькуляторе... ты гляди... и правда В2, а не В3. Неужели где-то раньше я накосячил с размером... Исправил - оверлей убрался. Но строки по прежнему не рисуются (и судя чисто по поведению, что блоки рисуются как бы на протяжении пары секунд, то явно программа пытается их рисовать откуда-то из code segment c непечатными символами, которых нет в используемом шрифте, до первого 00, который встречается далеко не скоро... однако почему? ведь буквально за несколько инструкций до того берутся имеющиеся строки, ds не меняется... придется медитировать дальше)



Ранг: 4.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 03 апреля 2014 00:25
· Личное сообщение · #13

Мда... выяснилось, что просто в конце файла, после сегмента данных шел еще крохотный сегмент кода, какой-то странный... И новые строки я пытался лепить в его конец. Размазал их по пустотам сегмента данных - все работает.



Ранг: 488.1 (мудрец), 272thx
Активность: 0.350
Статус: Участник

Создано: 03 апреля 2014 05:50
· Личное сообщение · #14

senyuki пишет:
после сегмента данных шел еще крохотный сегмент кода, какой-то странный...

бро а не вирусня ли это?

-----
Наша работа во тьме, Мы делаем, что умеем. Мы отдаем, что имеем, Наша работа во тьме....




Ранг: 4.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 04 апреля 2014 02:41 · Поправил: senyuki
· Личное сообщение · #15

Я тоже так думал, но скорее это остатки какой-то хитрой защиты господина Змиро. В cracktro от 93 года Гибриды жаловались на хитроболтовость защиты конкретно этой игры. Конечно, по тем временам...
Вообще хитро как-то, по крайней мере, пока что это выходит за пределы ясного понимания.
http://cs540106.vk.me/c616125/v616125788/8fdc/yMKf8MBj2NY.jpg

Скопировал этот блок в отдельный файл. Вот его заголовок:
http://cs540106.vk.me/c616125/v616125788/8fcc/QOD-Ivj-hkg.jpg

Для сравнения заголовок основного:
http://cs540106.vk.me/c616125/v616125788/8fd4/r6Z-R1T42PI.jpg

В этом блоке встречаются искаженные строки из основного файла.
http://cs540106.vk.me/c616125/v616125788/8fe4/VTBT_K8366Y.jpg

BEGINN - BEGINNER, EXP - EXPERT, COD - CODE, [[ - [[[[, служебная строка... Даже то, что выглядит как ONT, это, похоже, остаток от ENTER.
Проверил дамп - ничем не запакован, хоть и все указывает на то...

Соль в том, что если каким-либо образом нарушить целостность этого блока или вовсе убрать его - в некоторых ситуациях игра вместо того, чтобы выдать экран Game over или выйти в главное меню - выдает Uknown error. Reboot requested и Dosbox на этом вылетает. Собственно, думаю, что это Dosbox и выдает.
Мыслей пока нет, в чем же тут суть, буду пока думать


 [email protected] —› Программирование —› Патчинг ехе
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати