Blog. Just Blog

Как установить английскую раскладку при запуске HiEW

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Software | Автор: ManHunter
Как установить английскую раскладку при запуске HiEW
Как установить английскую раскладку при запуске HiEW

Несмотря на почтенный возраст, hex-редактор HiEW до сих пор пользуется заслуженной популярностью среди исследователей программного обеспечения. Да, он не лишен недостатков, да, к настоящему времени имеется огромное количество альтернатив, но лично для меня HiEW остается одним из самых востребованных инструментов. К большому сожалению, автор практически прекратил развитие программы и крайне неохотно реагирует на предложения пользователей, ограничиваясь парой-тройкой незначительных исправлений в год. Теперь к основной проблеме, которую я вынес в заголовок этой статьи. У меня Windows c русским интерфейсом, соответственно, все стартующие программы запускаются с русской раскладкой по умолчанию. Это меня вполне устраивает, но только не в случае с HiEW, для которого в 99,99% случаев требуется вводить символы в английской раскладке. Конечно, можно просто переключить раскладку и не напрягаться, но мне хочется какого-то абсолютного решения задачи. Этим сегодня и займемся. А заодно потренируемся в ручной распаковке ASPack и всевозможной работе непосредственно с самим HiEW.

HiEW - коммерческий продукт, с офсайта можно скачать только обрезанную демо-версию, а ретайловые версии собираются индивидуально под каждого покупателя. Из-за этого приватные версии никто палить, естественно, не собирается, а работать мы будем с общедоступным релизом HiEW 8.43 от команды DVT. Он спокойно находится в этих ваших интернетах, но если с поиском проблемы, то скачать его можно тут.

Основной исполняемый файл традиционно накрыт ASPack. Хоть это и не протектор, некоторые защитные функции в нем все равно присутствуют. Есть автоматические распаковщики для разных версий ASPack, но сегодня давайте сделаем это вручную.

Точка входа упаковщика
Точка входа упаковщика

Отправляем файл в отладчик, смотрим. Код распаковки начинается с команды PUSHAD, но дальше все зашифровано. Логично предположить, что после распаковки и расшифровки должна появиться команда POPAD и переход на оригинальную точку входа. Запускаем программу на выполнение, код распаковщика при этом будет расшифрован. Посмотрим его внимательнее.

Код перехода на OEP
Код перехода на OEP

Прокрутив пару экранов, обнаруживаем вот такую конструкцию. Регистры восстанавливаются, в стек заносится адрес точки входа и с помощью команды RET выполняется переход на него. Проследуем в листинге на этот адрес, убедимся, что это действительно похоже на точку входа, после чего поставим по этому адресу hardware breakpoint на выполнение.

Ставим точку останова
Ставим точку останова

Перезапускаем программу, отладчик остановится на точке входа. Делаем дамп при помощи плагина OllyDump, но галочку для восстановления импорта не ставим.

Делаем дамп процесса
Делаем дамп процесса

Теперь, не выходя из отладчика, запускаем вашу любимую программу для восстановления импорта, у меня сегодня это будет The Cheap Imports Reconstructor. Выбираем процесс, заполняем адрес точки входа и получаем таблицу импорта.

Восстанавливаем импорт
Восстанавливаем импорт

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

Импорт успешно восстановлен
Импорт успешно восстановлен

Закрываем отладчик и прочие сопутствующие программы. Запускаем исправленный дамп и убеждаемся, что программа работает без ошибок. Значит распаковка прошла успешно и первая часть работы сделана.

Файл работоспособен
Файл работоспособен

Теперь немного теории. Чтобы установить английскую раскладку в консольном приложении, требуется выполнить следующий код:
  1.         pusha
  2.         invoke  GetConsoleWindow
  3.         invoke  PostMessage,eax,WM_INPUTLANGCHANGEREQUEST,\
  4.                 INPUTLANGCHANGE_SYSCHARSET,0x04090409
  5.         popa
Код должен быть запущен в контексте процесса, для которого надо переключить раскладку. Это достигается или инжектом dll в процесс, или добавлением нужного функционала прямо в программу. Внедрение в процесс я считаю слишком рискованным, так как это может не понравиться антивирусам и для этого придется таскать дополнительную dll. А вот добавление кода напрямую в исполняемый файл мне нравится гораздо больше.

Чтобы успешно выполняться, код "заплатки" должен использовать как минимум две функции API - GetConsoleWindow и PostMessage. Увы, ни одной из них в импорте HiEW нет, зато есть такие замечательные функции, как LoadLibrary и GetProcAddress.

Нужные функции в импорте программы
Нужные функции в импорте программы

С их помощью можно загрузить нужные библиотеки и получить адреса нужных функций. В этом случае код будет следующим.
  1.         pusha
  2.  
  3.         ; Получить адрес GetConsoleWindow
  4.         call    @f
  5.         db      'kernel32',0
  6. @@:
  7.         invoke  LoadLibrary
  8.  
  9.         call    @f
  10.         db      'GetConsoleWindow',0
  11. @@:
  12.         push    eax
  13.         invoke  GetProcAddress
  14.  
  15.         ; Вызвать GetConsoleWindow
  16.         stdcall eax
  17.         ; Сохранить результат
  18.         mov     ebx,eax
  19.  
  20.         ; Получить адрес PostMessage
  21.         call    @f
  22.         db      'user32',0
  23. @@:
  24.         invoke  LoadLibrary
  25.  
  26.         call    @f
  27.         db      'PostMessageA',0
  28. @@:
  29.         push    eax
  30.         invoke  GetProcAddress
  31.  
  32.         ; Раскладка EN
  33.         push    0x04090409
  34.         ; INPUTLANGCHANGE_SYSCHARSET
  35.         push    1
  36.         ; WM_INPUTLANGCHANGEREQUEST
  37.         push    0x50
  38.         ; Результат GetConsoleWindow
  39.         push    ebx
  40.         ; Вызвать PostMessage
  41.         stdcall eax
  42.  
  43.         popa
Трюк с call и строками используется для того, чтобы обеспечить базонезависимый код. После вызова инструкции call на стек фактически кладется не адрес возврата, а адрес строки, так что не надо дополнительно его вычислять или где-то хранить. Саму же строку также нет необходимости отдельно куда-то выносить, она хранится прямо в коде.

Сохраняем "заплатку"
Сохраняем "заплатку"

Компилируем это все в исполняемый файл, затем при помощи того же HiEW сохраняем "заплатку" в виде бинарных данных. У меня получилось 110 байт.

Возвращаемся к дампу. С ним надо выполнить некоторые предварительные действия. Во-первых, подготовим место для записи заплатки. Лучше всего для этого подходит оставшаяся не при делах секция от ASPack.

Секция от ASPack
Секция от ASPack

Как видно из данных заголовка, ее физический размер составляет 2000h байт, что более чем достаточно для наших задач. Переходим на начало секции, выделяем целиком все 2000h байт и заполняем их командами NOP, что соответствует байту 90h.

Заполняем секцию
Заполняем секцию

Вторым шагом надо перенацелить точку входа на начало секции ASPack, а из самой секции предусмотреть возврат на оригинальную точку входа. Делается это все там же в HiEW.

Меняем точку входа
Меняем точку входа

Запоминаем адрес оригинальной точки входа, он нам еще понадобится. Новый адрес равен RVA секции ASPack из заголовка, то есть 00078000h. Сохраняем изменения, убеждаемся, что HiEW при переходе на Entry Point действительно переходит на начало секции.

Следующим шагом надо обеспечить возврат из секции ASPack на OEP. Для этого последние 5 байт секции заменяем на команду безусловного перехода на адрес 004492EDh. Обратите внимание на точку в команде перед адресом.

Прописываем возврат на OEP
Прописываем возврат на OEP

Сохраняем изменения, проверяем. Если все сделано правильно, то файл будет запускаться как ни в чем не бывало. Можете запустить программу под отладчиком и удостовериться, что выполняется пачка NOP'ов и затем выполняется переход на OEP.

Записываем "заплатку"
Записываем "заплатку"

Теперь переходим на начало секции ASPack, выделяем 110 байт и загружаем в этот блок двоичные данные "заплатки" из файла. Большая часть работы сделана. Осталось исправить вызовы функций LoadLibrary и GetProcAddress, так как их адреса взяты из другого файла.

Вызовы функций в оригинальном HiEW
Вызовы функций в оригинальном HiEW

Через список функций в таблице импорта находим нужные нам LoadLibrary и GetProcAddress и переходим на место их вызова. А там, открыв команду на редактирование, получаем нужный опкод. Для LoadLibrary это будет call d,[00044f078], а для GetProcAddress - call d,[00044f074].

Вызовы исправлены
Вызовы исправлены

Возвращаемся к "заплатке" и заменяем в ней все четыре кривых вызова на правильные. После сохранения изменений убеждаемся, что в вызовах отображаются правильные функции. Момент истины. Запускаем HiEW и проверяем, что программа не только успешно стартует, но и раскладка при ее запуске автоматически выставляется на английскую. Цель достигнута. Для более новых версий HiEW процесс будет точно такой же.

Поделиться ссылкой ВКонтакте
Просмотров: 1138 | Комментариев: 16

Комментарии

Отзывы посетителей сайта о статье
ManHunter (22.01.2024 в 17:37):
Отличная работа, спасибо
user (22.01.2024 в 15:21):
Ну, нашлась ещё заморочка.  Работает.
user (22.01.2024 в 12:31):
По приколу с шифтом.
При запаковке обратно aspack'ом shift снова работает.
В коде есть проверка фрагмента перед PE-заголовком,
но она за shift не отвечает, а видимо за какую-то другую пакость.
ManHunter (06.01.2024 в 01:40):
Стандартные приколы hiew. То вставка после распаковки не работает, то еще что-то подобное.
Илья (06.01.2024 в 01:39):
Печально. Там, насколько я помню, было одно предупреждение в сцилле, что один импорт подозрительный. Может в этом дело?
ManHunter (06.01.2024 в 01:35):
На 8.80 работает, на 8.43 нет.
Илья (06.01.2024 в 01:26):
А у Вас после hiew распаковки клавиша shift работает?
У меня нет. Пробовал и каспером распаковывать - то же самое.
ManHunter (04.01.2024 в 13:58):
Remove VMProtect and send me unpacked file.
8.66 (03.01.2024 в 23:15):
What about apply it to version 8.66 from OnlyOne? ;)
Илья (28.12.2023 в 10:49):
Статья - чистый мёд, спасибо!

Кстати, функцию, для преобразования 80-битных чисел с плавающей запятой в строку я так и не нашел - написал сам, с нормализацией.
user (25.12.2023 в 23:25):
Трудно сказать, почему плаги не грузятся при запуске HIEW -
то ли чтобы не тормозить запуск, то ли чтобы HIEW не падал при запуске, подтянув некорректный плагин, то ли чтобы не было соблазна делать рантайм патчеры самого HIEW, то ли учитывая всё перечисленное.
А может, просто не додумался, кто знает
ManHunter (25.12.2023 в 22:55):
Печально. Ну да ладно, раз в год можно и поковыряться :) А сабж чаще обновлять и не получается.
user (25.12.2023 в 22:54):
Тоже столкнулся когда-то с єтой постановкой вопроса.

Модули грузятся только после нажатия F11.
Был плагинчик CBD_CYR.HEM, который добавляет функционал переключения раскладок, так вот работать он начинал только после нажатия F11.
А не при старте самого HIEW.
Причём в том плагине функционал таков, что должен бы включаться автоматом при старте HIEW, но нет - приходится нажимать F11, чтобы позагружались все плагины, а заодно и этот CBD_CYR.HEM.

Если бы плаги загружались вместе с запуском HIEW, то можно было бы делать прозрачно работающие патчеры HIEW в виде этих самых HEM-плагинов, но нет.
Может быть, это сделано специально так.
(тот CBD_CYR.HEM это и есть по сути патчер самого HIEW)
С другой стороны, это поведение тоже можно подковырять и грузить плаги самостоятельно, но это надо задаться такой целью

Выложу сейчас рабочий 8.43 c добавленным кэшированием GOTO (есть CRK-файл этого патча) и с набором часто используемых плагинов
ManHunter (25.12.2023 в 22:34):
user, вот, кстати, вопрос к тебе, как к разработчику разных hem'ов. Модули грузятся сразу при загрузке HiEW или только по запросу по F11? А то можно было бы вынести этот фикс с английской раскладкой универсально для всех версий, раз уж к автору не достучаться.
user (25.12.2023 в 22:07):
Вставлял таким методом заплаток давным-давно в DOS и WIN32 версии кэширование введённого адреса перехода в окошке GOTO, предлагад SEN'у добавить этот функционал стационарно, показывал патченные готовые версии, - но нет, не захотел он такое делать. Потом глядь, в одной из новых версий уже оно так и заработало, как надо. Таки добавил, через пару-тройку лет.
Предлагал ему сделать выделение цветом всей текущей строки в листинге дизасм'а - но что-то без результата. Хотя, может, в новых версиях это уже и сделано, не видел ничего моложе 8.63 (8.66 не в счёт, она покорёжена вмпротектором, та что ходит по сети).
Сунулся было самостоятельно добавлять то выделение строки, но заглохла та затея за неимением времени.. А вот это было бы крайне то, что нужно
iocore (25.12.2023 в 19:52):
Спасибо =) Hiew - незаменим и любим, со времён "Софтпанорамы" =) Женя, в отличие от Ильфака (а имею опыт общения с обоими), очень комфортный собеседник. Правда, до сих пор не хочет "принять" факт существование особо широких мониторов, и "Unsupported videomode" приходится также патчить =)

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0038 сек.) / Память: 4.5 Mb
Наверх