MyLanViewer

Решение проблем по локализации программы.
  1. Оффлайн

    Автор темы

    Leserg

    Звание: Ветеран

    Команда сайта

    Сообщений: 929

    Создано тем: 79

    Рейтинг: 8

    Репа: (131|131|0)

    Баллы: 1596

    Был: 2024-04-28 00:36

    Лайков: 140

    MyLanViewer


    ВОПРОС:
    Как, например, найти ссылку на строку Apply (рис. 1)

    MyLanViewer

    Рис. 1

    Кто ищет, тот всегда найдет!

    30 марта 2024 - 23:14 / #1
  2. Оффлайн

    Автор темы

    Leserg

    Звание: Ветеран

    Команда сайта

    Сообщений: 929

    Создано тем: 79

    Рейтинг: 8

    Репа: (131|131|0)

    Баллы: 1596

    Был: 2024-04-28 00:36

    Лайков: 140

    ОТВЕТ:

    Инструменты:
    - отладчик x64dbg (в описании используется англоязычный интерфейс).

    Подготовка:
    - запустите отладчик и откройте настройки. На вкладке "Disasm" включите опцию "Permanent highlighting mode", если она еще у вас не включена. В данном случае она поможет ориентироваться в коде программы, подсвечивая выбранную инструкцию, регистр, адрес или значение.



    Решение:

    Загружаем файл программы MyLanViewer.exe в отладчик x64dbg. После загрузки мы находимся на точке входа программы. Будем искать строку, которая выводится в интересующем окне программы. Возможно вы уже знаете, где она находится, Тогда можете сразу переходить к ней в дапм программы. А пока для тех, кто еще не знает, продолжим. Находясь на вкладке "CPU" вызываем окно поиска паттернов (горячие клавиши [Ctrl+Shift+B] или команда контекстного меню "Search for -> Current module -> Pattern")


    Рис. 1


    Искать нужно именно в модуле (то есть по всему файлу), мы же не знаем, где конкретно она находится. В открывшемся окне в поле ASCII вводим строку "Apply" (объект поиска) и подтверждаем ввод.


    Рис. 2


    Будет найдено 6 паттернов, адреса которых будут показаны на вкладке "References" отладчика.


    Рис. 3


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


    Рис. 4


    Сейчас в окне дампа у нас выделен один первый байт паттерна (41h), т.е. первая буква строки "Aplly" - А. Нажмите комбинацию клавиш [Ctrl+E], чтобы открыть редактор НЕХ значений (или через команду контекстного меню "Binary -> Edit"). В поле НЕХ значений вместо 41 введите 31 (в десятичной системе счисления это единица - 1).


    Рис. 5


    Ну или в поле ASCII вместо символа "А" введите число "1", как вам удобнее. Подтвердите сделанное изменение, нажав "ОК". Получится вот так:


    Рис. 6


    Вернитесь на вкладку "References" отладчика и перейдите к следующей строке. Для неё аналогичным образом измените первый символ на 2 и т.д. по возрастающей для всех остальных строк. Таким образом каждая строка получит соответствующий индекс от 1 до 6.

    После изменения (нумерации) строк запустите программу на выполнение, нажав комбинацию клавиш [Shift+F9]. Можно использовать простой запуск по F9, но тогда отладчик будет останавливать выполнение программы на исключениях, которые будут сбивать вас с толку и отвлекать. Запуск же по [Shift+F9] позволяет их избежать. После запуска программы идем в настройки MyLanViewer (или открываем диалог), где находится интересующая нас строка. Смотри её индекс.


    Рис. 7


    Это строка с индексом 6. Закрываем это окно и возвращаемся в отладчик. Эта строка находится по адресу 007C3839.


    Рис. 8


    Можно тут же проверить, имеет ли эта строка ссылки. Для этого в окне дампа по адресу 007C3839 щелкните по байту 36 и нажмите комбинацию клавиш [Ctrl+R] (или воспользуйтесь командой контекстного меню "Find References"). Увы, действительно, строка не имеет прямых ссылок (на вкладке "References" для этого адреса ничего не будет найдено).

    Итак, адрес нужной строки определили - это 007C3839. Теперь нужно найти ссылку на этот адрес. Мы уже знаем, что прямой ссылки в коде нет, значит ссылка другого типа.

    Перезагружаем программу MyLanViewer в отладчике (кнопка на панели инструментов "Restart" или [Ctrl+F2]) и идем в окно дампа на адрес 007C3839 (для быстрого перехода можете воспользоваться предыдущим поиском на вкладке "References", если вы еще не закрыли этот результат).

    Я думаю вы понимаете, что для загрузки любой строки в окно, диалог, элемент управления программы, её предварительно нужно прочитать (скопировать в память, где с ней будут выполнены предусмотренные программистом действия). Вот и будем ловить отладчиком место в коде программы, где строка считывается в память. Это можно сделать посредством установки аппаратной точки прерывания на доступ к данным. Для этого в окне дампа по адресу 007C3839 вызываем контекстное меню и выбираем команду "Breakpoint -> Hardware, Access -> Byte". В данном случае достаточно доступа к одному байту строки, независимо от способа считывания данных.


    Рис. 9


    Готово. Запускаем программу MyLanViewer под отладчиком клавишами [Shift+F9] и вызываем диалог с интересующей строкой. Отладчик тут приостановит выполнение программы, сообщив нам, что сработала установленная нами точка прерывания, и на вкладке "CPU" покажет участок кода, где это произошло.


    Рис. 10


    В поле комментариев дизассемблера хорошо видно, что идет как раз чтение нашей строки. А в самом коде идет сравнение каждого символа строки с нулем. Очевидно, что идет определение размера строки. В регистре EDX находится уже известный адрес нашей строки - 007C3839. Нам следует узнать, как он сюда попал, поэтому необходимо выйти из этой подпрограммы. Признаком выхода служит инструкция RET (или её разновидности). До конца текущей подпрограммы можно пройти как пошаговом режиме (по клавише [F8]), так и автоматически по команде "Execute till return" (выполнить до возврата) или по клавишам [Ctrl+F9].

    Итак, сначала отключаем установленную нами точку прерывания (на вкладке "Breakpoints"), чтобы она больше нам не мешала. Затем на вкладке "CPU" проходим на конец текущей подпрограммы. Мы окажемся по адресу 00689FD9 на инструкции RET.


    Рис. 11


    Хорошо видно, что данная подпрограмма небольшая и здесь вряд ли может быть что-то интересное для нас, в частности определение адреса строки. Поэтому выйдем из неё, нажав [F8]. Мы окажемся в подпрограмме верхнего уровня по адресу 006FC3E2.
    Здесь тоже ничего интересного, т.к. код небольшой.


    Рис. 12


    Проходим до конца этой подпрограммы (по [F8] или [Ctrl+F9]) и затем, находясь на адресе 006FC3F2 с инструкцией RET, нажимаем [F8] и выходим из неё. Далее мы окажемся на адресе 00583421 в подпрограмме ещё более верхнего уровня, как раз сразу после инструкции CALL по адресу 0058341C, где происходило чтение нашей строки. Вот здесь следует остановиться и внимательно осмотреться, тем более, если вы пролистаете код вниз и вверх, то увидите, что он не маленький.


    Рис. 13


    Рассуждаем. Раз по адресу 0058341C с инструкцией CALL сработала наша точка прерывания, то адрес с нашей строкой в эту программу был сформирован ранее, выше по коду. Смотрим. Обращает на себя внимание инструкция LEA по адресу 00583416 с операндом [EDI+0D] (значение регистра EDI плюс смещение 0D). В комментарии к этой инструкции отладчик нам дает подсказку, что по адресу [EDI+0D] находится строка "Apply".


    Рис. 14


    Проверяем. В регистре EDI имеем значение 007C382C.

    007C382C + 0D = 007C3839 – это адрес нашей строки "Apply".

    Также непосредственно из кода можно перейти в дамп по значению [EDI+0D]. Для этого щелкните по строке с адресом 00583416, затем в контекстном меню выберите команду "Follow in Dump -> Address EDI+0D".


    Рис. 15


    Еще один момент можете для себя прояснить, почему к значению в регистре EDI нужно прибавлять именно значение 0Dh. В окне регистров (справа на вкладке "CPU") в контекстном меню регистра EDI выберите команду "Follow in Dump" (Перейти в дамп).


    Рис. 16


    В окне дампа отсчитайте количество байт до адреса с началом строки "Apply". Их будет 13 (0Dh).


    Рис. 17


    Таким образом ссылка на строку "Apply" является относительной (или регистровой). Базовым адресом является значение в регистре EDI, относительно которого с учётом определённого смещения находится сама строка. Осталось выяснить откуда берется значение в регистре EDI. В инструкции по адресу 00583416 (со ссылкой к строке "Apply") щелкните по регистру EDI и отладчик его подсветит (помните, в самом начале мы изменяли настройки отладчика). Теперь поднимайтесь по коду вверх (прокручивайте листинг вода вверх) на начало этой подпрограммы и обращайте внимание на все инструкции, где встречается обращение к регистру EDI (он подсвечен отладчиком). Вот, например, по адресу 0058338A идет ссылка на строку "Close".


    Рис. 18


    И далее по адресу 005832EB ссылка на строку "Ok".


    Рис. 19


    Наконец, почти в самом начале подпрограммы, по адресу 0058328E, в регистр EDI записывается базовый адрес.


    Рис. 20


    Итак, что мы имеем. Сначала в регистр EDI записывается значение базового адреса, который является прямым и ведет непосредственно во вторую секцию файла MyLanViewer.exe, к массиву строк. А далее по коду, относительно этого адреса, по определённым смещениям считываются строки. Если вы пройдете по коду этой подпрограммы вниз до самого конца (инструкции RET), то увидите, что здесь считываются все строки следующего массива:


    Рис. 21


    В результате, чтобы перенести строку "Apply" на новое место, для её нормального перевода, необходимо:

    1) Перевести все строки указанного массива, с сохранением его структуры.
    2) Изменить в коде базовый адрес на новый, который ведет к массиву строк.
    3) Скорректировать в коде значения смещений для каждой строки в массиве, относительно нового базового адреса.

    Важное примечание:
    Обратите внимание на пустое поле в массиве между строками "Apply" и "General"


    Рис. 22


    Наверняка у вас может возникнуть соблазн использовать это место для записи перевода строки "Apply" как "Применить". Тем более, что он туда как раз вмещается. Но спешите, а исследуйте код подпрограммы на предмет обращения к этому месту. После вызова строки "Apply" в коде по адресу 005834A2 идет считывание с адреса [EDI+13], т.е. нулевого байта:


    Рис. 23


    И далее для каждого последующего байта, соответственно с адресов [EDI+14], [EDI+15], [EDI+16]. А вот уже с адреса [EDI+17] считывается строка "General". Поэтому важно при переносе строк на новое место сохранить структуру массива, о чем и было сказано в первом пункте необходимых действий.

    Аналогично исследуйте другие подобные массивы строк, если прямые ссылки на них отсутствуют.
    NNK_RTR, 78Sergey, Смотрящий нравится это сообщение.

    Кто ищет, тот всегда найдет!

    30 марта 2024 - 23:54 / #2

Статистика форума, пользователей онлайн: 2 (за последние 20 минут)

Создано тем
1177
Всего сообщений
15349
Пользователей
17852
Новый участник
Astarot