![]() |
Добро пожаловать, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
Siberian GRemlin |
![]() ![]()
Сообщение
#1
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 537 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
Уважаемые.
Добрался я до той ситуации, когда необходимо изменить длину строк в EXE, в частности под DOS. Как я понимаю, в бинарнике есть таблица с адресами и если мне нужно изменить длину первой строки (считаем от начала бинарника) на один символ (байт), то необходимо в таблице увеличить все значения адресов на единицу, кроме самого первого адреса (в смысле, адреса первой строки). Единственное, что мне пока неизвестно, где находится эта таблица в бинарнике и как там идёт индексация, а также адресация и есть ли где-то значение размера этой таблицы? Ещё в интернете ища информацию, натыкался на информацию о том, что существует прога для автоматического изменения текста с его длинной, ремаппингом и т.п., а также что люди сами писали подобные программы. Гипотетически это возможно, но как бы это выяснить... Может кто-от посоветует какие-нибудь статьи по данному вопросу (локализации текстовых констант в ЕХЕ) P.S.: Опытного человека, моё сообщение может показаться ламерским бредом... но хочется расти в творческом плане и в одиночку без глупых вопросов не обойтись. P.P.S.: Я доделываю русскую локализацию одной игры. |
-=CHE@TER=- |
![]()
Сообщение
#2
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
P.P.S.: Я доделываю русскую локализацию одной игры. Хех, я так понимаю Кирандию первую добиваешь? (*улыбается*)Тут, ИМХО, проблема такая, что без полной декомпиляции игры ты её не решишь. Понимаешь, строка, скажем так, вшита в .EXE файл. Ты можешь только: 1) уменьшить её (забить неиспользуемые символы в конце нулями, а лучше, пробелами) и 2) изменить её не меняя её длинны Всё. Увеличить длинну нельзя по одной простой причине: если ты увеличить строку на 1 байт - это значит, что ВСЕ конструкции-переходы (CALL, JMP, J*) в программе, которые ссылаются на адреса выше/ниже того места, где ты вставил байт, будут ссылаться на один байт раньше/позже того места, куда должны бы. Проблема в том, что все инструкции перехода записываются как инструкция и на_сколько_ ОТНОСИТЕЛЬНО_ТЕКУЩЕГО_АДРЕСА_перейти Например: jmp +5 // перейти на адрес на 5 байт после текущей инструкции call -60 // перейти на адрес на 60 байт выше данной инструкции Т.е. если ты всунул 1 байт между этими двумя командами, то: 1) jmp будет уже на +6 2) call будет уже -61 Я думаю, что писать дизассмеблер это муторно, да и отловить все такие ситуации очень и очень сложно. Это не просто изменить длинну строки - это, можно считать, переколбасить всю программу. Более того, я тут разобрал самый простой случий, без всяких структур (представь, что твоя строчка входила в структуру, или после неё стояла структура, адрес которой загружался при помощи команды lea). Моё скромное ИМХО: задача по удлинению строки, в общем случае, очень тяжёлая (если не сказать невыполнимая) и не факт, что после этого .EXE файл будет корректно работать. Если уж очень хочется, то можно сделать такой, малооправданный, трюк ушами (геммор, правда, чуть меньший, чем с правкой всех адресов в предыдущем способе): 1) Написать свой загрущик для оригинального .EXE-файла (типа виндового "запустить процесс спящим") 2) Выделить в загруженной программе дополнительную память, куда пихать свои, русские, строки 3) Перебить в памяти адреса, откуда берутся оригинальные строки, на те, где находятся загруженные соответствующие им русские 4) Дать оригинальной программе дальше работать (типа "ResumeThread") Хотя опять-таки, если строчка входила в структуру, то нужно менять и её размер... |
Siberian GRemlin |
![]()
Сообщение
#3
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 537 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
Да. Её родимую. =)
Сокращать строки не приемлимо - я лучше заплачу человеку, который в этом разбирается больше меня, чтобы он сделал. Если есть такие люди - пишите мне личное сообщение или на эл. почту, о цене договоримся. Есть её, кажется, более спортивный способ, который пришёл мне в голову: Сесть самому, но лучше с кем-нибудь и, открыв EXE в IDA, выписать все смещения до байт, которые нужно изменять при удлинении строк (смещения отностительно начала оригинального не исправленного ни кем ЕХЕ), потом написать программу, которая изменяет корректно строки в ЕХЕ по файлу инструкции, который мы создадим специально для неё (т.е. все адреса для изменения о которых я писал выше) и на выходе получаем новый ЕХЕ. Думаю будет проще сделать импорт строк из TXT, чем полноценный редактор, которому придётся ещё сохранять в какой-то отдельный файл на сколько в прошлый раз увеличили его размер и по каким адресам всякие условные и безусловные переходы и пр., иначе он корректно не откроет/изменит уже исправленный нами когда-то ЕХЕ. Ещё как вариант у меня есть исправленная версия ЕХЕ под итальянскую локализацию, сделанную моим знакомым - строки на итальянском длиннее чем на английском, но не факт что все и + он там добавил какую-то фигню, что запускать приходится с параметром: MAIN.EXE -L, но тогда я обломаюсь с другими частями этой игры. |
-=CHE@TER=- |
![]()
Сообщение
#4
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Siberian GRemlin!
А чем тебе не нравится SCUMM (там есть поддержка первой Кирандии)? Вряд ли, ИМХО, кто-то будет играть в Кирандию под чистый DOS... |
Siberian GRemlin |
![]()
Сообщение
#5
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 537 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
'Если хочешь, чтобы что-то было сделано хорошо - сделай это сам.' - древняя мудрость.
Не хочу зависеть от разработчиков какой-то непонятной проги, в которой поддержка 2 и 3 частей неизвестно в какой пятилетке будет... Не успел несколько дней назад отписаться - инет кончился: Отбой. Я придумал пару хитростей (просто повезло с тем что разработчики дублировали некоторые строки, а я указатели дубляжей перенаправил на первый встречающийся экземпляр, а оставшееся место использовал в свою усмотрение) + разобрался с IDA и даже умудрился научиться изменять размеры кнопок =) ![]() Пока есть только 1 проблемка, когда адрес на начало строки пихается в стэк - push именно это и делает если я понимаю, только непонятно где там адрес сам, чтобы его сменить. Можно мне подсказать, если я покажу кусок кода на асме с этим моментом? |
-=CHE@TER=- |
![]()
Сообщение
#6
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Пока есть только 1 проблемка, когда адрес на начало строки пихается в стэк - push именно это и делает если я понимаю, только непонятно где там адрес сам, чтобы его сменить. Можно мне подсказать, если я покажу кусок кода на асме с этим моментом? Пустил MAIN.EXE под IDA, что-то там куча строк, которые она даже не распознала - т.е. на них нет прямого указателя. Такое ощущение, что они там через базу+смещение до нужной строки, работают. На ту же строчку "Yes" я нигде явной ссылки не нашёл. Что-то я не там ищу что-ли?Можешь, конечно, выложить код, но там не должно быть ничего сложного: - если твоя новая строчка находится раньше старой, то просто считаешь между ними разницу и отнимаешь от того числа, которое суётся в стэк - если строчка находится позже оригинальной - проделываешь всё тоже самое, только прибавляешь к число разницу |
Siberian GRemlin |
![]()
Сообщение
#7
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 537 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
![]() Вот смотри, возьмём строчку "The poison..." её легко найти. Справа есть стрелочка, как я понял, ведущая туда где ?первый? раз обращаемся к ней. Как видно в подсказке, там как раз изврат, но думаю ты сам туда перейдёшь и посмотришь. Вот как там менять адрес, указывающий на начало строки? В большинстве же случаев всё гораздо проще, как чуть ниже на снимке, например строчки как "The flask is now filled.....", там смотрим и видим просто указатель на эту строку, который и меняем на новый, после изменения длин строк. P.S.: Ещё меня очень сильно угнетает, что в Hex View-A (16ричный режим просмотра) слева вместо стандартного смещения, какая-то хрень, типа dseg:####, ovr###:#### и т.п. Можно сделать отображение смещений привычное глазу моему? =) P.P.S.: Я завершил изменение размеров менюшек - всё вообще красиво теперь смотрится! 8 ) Никогда не думал, что я до такого дойду, но очень мечтал! Ура! =) P.P.P.S: Есть ещё одна задачка - выставить показ текста в CD версии по умолчанию как в Floppy версии, а то получается, что вступление без вывода текста... Придётся пинать одного хакера знакомого, который всегда занятой. |
-=CHE@TER=- |
![]()
Сообщение
#8
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Так, у тебя какая версия IDA? У меня IDA Pro Adv 4.8.0.847 и у меня эти строчки вообще как данные - т.е. там даже ссылок на их начало нет. Юзал на .EXE файле, который ты мне когда-то присылал, от оригинальной, английской версии. Сейчас ещё попробую IDA новую достать...
А "DATA HREF" - это тебе IDA подсказывает с какого места на эту константу ссылаются. Наведи курсор или щёлкни мышкой по "aThePoison___" и нажми X - появится список мест кода, где идёт ссылка на эту строку. Щёлкаешь два раза по любому - и тут же туда переходишь. Вот там тебе адрес и нужно менять. Насчёт смещений - не знаю. Никогда не требовалось, а если и требовалось, то по коду искал. (*улыбается*) BTW, dseg:#### - это данные (сегмент данных), ovr### - это оверлей (если заметил - странный кусок в хвосте .EXE). |
Siberian GRemlin |
![]()
Сообщение
#9
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 537 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
У меня такая же IDA, хотя вчера нашёл в локальной сети дистрибутив 5.0
Вот файл от той версии, что надо =) _http://upload.siberianet.ru/download.php?file=816KyraCDEng.rar |
-=CHE@TER=- |
![]()
Сообщение
#10
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
У меня такая же IDA, хотя вчера нашёл в локальной сети дистрибутив 5.0 Хе, а это другой .EXE. Он даже на 10 Кб толще. Видимо, тот что ты мне раньше высылал какой-нибудь заломанный был.Вот файл от той версии, что надо =) _http://upload.siberianet.ru/download.php?file=816KyraCDEng.rar В ближайшее время ещё раз гляну. |
Siberian GRemlin |
![]()
Сообщение
#11
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 537 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
Прошлый был от Floppy версии, я перевожу полную CD которая была улучшена и издана на год позже, вместе с озвучкой, которой в Floppy не было по определению. =)
|
-=CHE@TER=- |
![]()
Сообщение
#12
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Понятно. Хотя этот .EXE файл тоже не лучше - на строчку "Yes" я тоже ссылки не нашёл...
Ну, ладно. Так вот, насчёт строчки "aThePoison___" - щёлкаешь на ней мышкой, чтобы она подсветилась. Затем на клавиатуре жмёшь X (английская "икс"). В появившемся окне два раза кликаешь на смещение. Попадаешь примерно на такой вот код: CODE ovr136:002C add sp, 4 ovr136:002F push 0FFFEh ; int ovr136:0031 push 0 ; char ovr136:0033 push ds ovr136:0034 push offset aThePoison___; "The poison..." ovr136:0037 push 1B58h ; int ovr136:003A call sub_B6DA Теперь кликаешь по "offset aThePoison___" и, затем, сверху на вкладку "HEX-View A" - там выделится вся эта команда их трёх байт: 68 5A 0F. Так вот - 52 0F, вернее $0F5A - это как раз смещение до строки (68 - это, похоже, код команды PUSH WORD). Его и меняешь, на какое тебе нужно (заметь, что это смещение относительно начала ТЕКУЩЕГО оверлея - т.е. на строчку в другом оверлее ты просто не сможешь указатель сделать). Твоя строчка и находится там: CODE dseg:0F5A; char aThePoison___[] Видишь - 0F5A - вот этот адрес там и записан. Менять можно через любой HEX редактор. Я обычно ищу последовательность байт (например 00 1E 68 5A 0F), смотрю чтобы она находилась одна (чтобы не перепутать с другим кодом) и потом меняю что нужно. |
Siberian GRemlin |
![]()
Сообщение
#13
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 537 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
Понятно. Хотя этот .EXE файл тоже не лучше - на строчку "Yes" я тоже ссылки не нашёл... А мне почему-то думается, что IDA игнорирует короткие строчки и не вносит их в список. Я, например, эти строчки искал так: посмотрел в TotalCmd какие рядом есть подлиннее - кажись "Main menu", в списке перешёл к нему и в коде уже нормально копался с ней и с короткими возле неё. А можно определение Overlay'я? ![]() P.S.: Спасибо большое. Моя жизнь стала ещё прекраснее и я теперь смогу сделать перевод ещё лучше! |
Siberian GRemlin |
![]()
Сообщение
#14
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 537 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
Я тут колупался. В итоге удалось изменить длины строк, по указанному тобой способу, но не все. например, я изменил длины строк:
"Amazing!" "The effects of the poison are gone!" "It's a jewel, but why is it black?" и других из того куска кода. Но во втором куске кода, где лежат 4 строчки, которые мне надо изменить: "The poison..." "I can't breathe..." "I don't feel so good..." "That snake must be poisonous!" Делаю как в предыдущем блоке, т.е. как ты писал, но игре вообще пофиг на это. Я ещё случайно столкнулся с проблемой (точнее не с проблемой а так) - ну случайно по глупостью, когда ошибся смещением на 1 и вместо адреса сменил байт $68, т.е. команду push и после этого игра при попытки загрузить игру выдавала ошибку, что мол сохранёнка от другой игры, я свою оплошность ясень пень исправил... суть в том, что даже если поменять все байты в окрестности адреса до начала строчки "I don't feel so good...", то и даже так игре всё пофигу, она нормально загружает сохранёнки и отображает строки начиная с того адреса, как и было в оригинале. Где собака зарыта? Может есть подводные камни? P.S.: Я решил методом тыка перебрать где это может быть и нашёл все места где встречается $680F т.е. адрес до строчки "I can't breathe...", его я взял из того места где push, т.е. байты $68680F, изменение которых ни к чему не приводит. Но перебирать 30 мест в файле очень геморойно =( |
-=CHE@TER=- |
![]()
Сообщение
#15
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
А можно определение Overlay'я? Если с английским хорошо - вот тут есть описание/определение оверлея. Ещё могу такую цитату привести:![]() QUOTE Блоки модуля Overlay понадобятся при разработке громоздких программ с перекрытиями (позволяет хранить в памяти только нужные части программы, а не требующиеся на данный момент удалять из памяти, сохраняя на диск, либо возвращать в память при необходимости). Короче, это, по сути, кусок программы, который загружается в память, ему передаётся управление, он отрабатывает свою часть и, затем, завершает работу и выгружается из памяти (я так понимаю, это предтеча .DLL). В DOS это позволяет сильно съэкономить память, т.к. у тебя не вся программа в оперативке одновременно находится, а только её части. Насколько мне известно, в Windows оверлеи не применяются вообще (там даже такого механизма нет). Обычно оверлеи валяются в каталоге программы с расширением .OVR, но могу быть приделаны в хвост главного .EXE файла.Где собака зарыта? Может есть подводные камни? Не забывай, что ты изменяешь адрес начала строки. Строка, в свою очередь, кончается символом $00 на конце (ASCIIZ-строки). Т.е. длина строки считается как количество байт с адреса начала, до первого символа $00. Длина строки нигде не должа задаваться явно (если только где-нибудь временный буфер для пересылки жёстко не ограничен каким-нибудь значением). |
Siberian GRemlin |
![]()
Сообщение
#16
|
![]() Advanced Member ![]() ![]() ![]() Группа: CTPAX-X Сообщений: 537 Регистрация: 4-February 08 Пользователь №: 2 Спасибо сказали: 221 раз(а) ![]() |
Не забывай, что ты изменяешь адрес начала строки. Строка, в свою очередь, кончается символом $00 на конце (ASCIIZ-строки). Т.е. длина строки считается как количество байт с адреса начала, до первого символа $00. Длина строки нигде не должа задаваться явно (если только где-нибудь временный буфер для пересылки жёстко не ограничен каким-нибудь значением). Это как бы не ответ на мой вопрос. В моём patch'е в зависимости от новой длинны строки к адресу следующей прибавляется положительное либо отрицательное число. Суть проблемы в том, что именно в том месте какие-либо изменения почему-то игнорируются. Что выглядит неправдоподобно. P.S.: Либо я дурак, либо одно из двух. |
-=CHE@TER=- |
![]()
Сообщение
#17
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,360 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 313 раз(а) ![]() |
Это как бы не ответ на мой вопрос. Тогда ставь вопрос более корректно - чтобы тебя сразу поняли. (*улыбается*)В моём patch'е в зависимости от новой длинны строки к адресу следующей прибавляется положительное либо отрицательное число. Хорошо, а если поменять только это место и больше ничего не трогать - всё работает?Суть проблемы в том, что именно в том месте какие-либо изменения почему-то игнорируются. Что выглядит неправдоподобно. P.S.: Либо я дурак, либо одно из двух. |
Bourn |
![]()
Сообщение
#18
|
Незарегистрирован ![]() |
Все просто - находим пустой адрес(можно и конец ехе), хотя если место особождается от уменьшение одной текстовой константы - его можно использовать для другой, ну и конечно если ехе не юзает секции - тогда проще(если сплошной код, а в конце кода константы, асм компилеры так генерят...)
|
![]() ![]() |
Упрощённая версия | Сейчас: 9th September 2024 - 15:45 |