Имеется консольное приложение, которое было скомпилировано на компиляторе от Майкрософта ( с использованием WINAPI функций, разумеется), С++. Исходного кода и аналогов этой программы тоже нет. Дизассемблирование показывает около 3500 функций, так что полная обратная разработка займет очень много времени.
Я поставил перед собой задачу - написать универсальный загрузчик, поддерживающий несколько операционных систем (код выбирается на этапе компиляции). Пока веду работу только на Windows.
Загрузка выполняется по принципу "размести оригинальные сегменты в нужных местах, обработай таблицу импорта, вызови entry point". Для рeализации был выбран gcc (MinGW), так как он поддерживает модифицированные скрипты компоновщика, язык С.
Сегменты были расположены корректно, таблица импорта обработана корректно, точка входа вызывается, аргументы обрабатываются корректно.
Проблема заключается в том, что рано или поздно возникает ошибка R6002 (как побочный эффект), но я уверен, что проблема именно в компоновке программы (несовместимы библиотеки времени выполнения и где-то что-то проинициализировалось, а где-то нет?), а не в каких-то конкретных ошибках. Отладка произодится с помощью Qt creator, но она затруднительна, так как есть только ассемблерный листинг.
Вопрос такой: придется патчить вызовы стандартных функций, чтобы заставить загрузчик работать или можно что-нибудь придумать?
Ответ
Поскольку программа печатала
runtime error R6002
- floating point support not loaded
я решил выяснить, из-за чего появляется эта ошибка. И нашёл вот что ("стек вызовов"):
__NMSG_WRITE
_amsg_exit(2) <= 2 - код ошибки (соответствует R6002)
_fptrap
Функция _fptrap использовалась действительно как заглушка аж 10 раз в массиве из 10 функторов. Интересным является то, что вызваться эта функция не могла, т.к. до такого вызова происходила безусловная перезапись этих функторов на другие:
void __cdecl _cfltcvt_init_0()
{
off_519200 = _cfltcvt; // Все эти off_* были инициализированы
off_519204 = sub_4B91DF; // функтором _fptrap.
off_519208 = _fassign;
off_51920C = _forcdecpt;
off_519210 = _positive;
off_519214 = _cfltcvt;
off_519218 = _cfltcvt_l;
off_51921C = _fassign_l;
off_519220 = _cropzeros_l;
off_519224 = _forcdecpt_l;
}
Я изменил эту заглушку на обычный nullsub, полёт нормальный. Однако остаётся чувство, что где-то меня обманывают.
Комментариев нет:
Отправить комментарий