Саша Ситников (shuffle_c) wrote,
Саша Ситников
shuffle_c

Category:

Как пропатчить Remote Debugger 2012 под Windows XP

Вторая на данный момент по популярности винда более не поддерживается официально. Под нее не будут выпускаться патчи, ну почти. Но что действительно заставляет меня переходить с нее на что-то более новое, так это невозможность работы на ней Visual Studio старше 2010-й версии. Конечно, я не нахожу в этом серьезной проблемы, но по ряду причин XP у меня прочно засела на виртуалке, и я продолжаю ее использовать в таком виде. VC++ 2012/2013, кстати, хотя не работает на XP, но позволяет собирать под нее программы. В противном случае было бы очень сложно заставить разработчиков переходить на новые студии, потому что еще очень много стороннего софта заявляет поддержку старых винд. Но чтобы все-таки усложнить людям жизнь, под XP кроме самой студии не работает также Remote Debugger. То есть писать что-то под эту ненавистную MS операционку пока можно, но вот отлаживать уже никак (по крайней мере, в удобной среде VS). Это доставило мне некоторые неудобства, и я решил исправить ситуацию. Просто взял этот ремоут дебаггер и пропатчил, чтобы работал. Собственно, вот он. Правда, он умеет только native код, т.к. мне этого более чем достаточно. Если вам тоже, можно брать и юзать. Ну а для тех, кому просто интересно, суть проделанных извращений под катом.


Первое, что мы узнаем, когда пытаемся запустить программу на XP, предназначенную для современной версии Windows, что она "не является приложением Win32". Это вранье. Формат PE не меняется от версии к версии винды. На самом деле, вся причина лишь в том, что линкер прописал в ехешнике минимальную версию подсистемы Win32 6.х, то есть Vista+. В любой программе редактирования PE файлов (я использовал PETools, в ней есть все, что нужно) меняем поля Subsystem version major и minor на 5 и 1, соответственно. Для dll этого делать не нужно, винда туда не смотрит. В самом тривиальном случае после такого простого изменения получается работающее приложение. Но чаще всего нам скажут "Точка входа в процедуру CancelSynchronousIo не найдена в библиотеке DLL KERNEL32.dll", ну, или как-то так.

В PE файлах есть таблица импорта, в которой прописываются названия тех API, которые в явном виде вызываются из кода программы. Загрузчик читает эту таблицу, ищет имена функций в указанной dll и записывает их адреса последовательно, один за другим. Если какой-то функции не удается найти, продолжать дальше работать не имеет смысла, т.к. приложение не ожидает такой подставы. Понятно, что каким-нибудь перехватом вызова функции здесь не обойтись, поскольку приложение вылетает еще до загрузки. Поэтому нужно править таблицу импорта. Самое простое, что я придумал, это заменить имена функций, которых нет в XP, любыми другими функциями, которые существуют. В этом случае винда, по крайней мере, позволит загрузить приложение. Но раз эти функции были в таблице импорта, значит они кому-то нужны — рано или поздно будут вызваны. А коль скоро там окажется адрес совсем другого API, ничего хорошего из этого не выйдет. Следовательно, необходимо также заменить адреса фиктивных API на реальные функции, делающие то, что от них ожидалось первоначально. Сделать такую подмену нужно до выполнения кода программы, то есть до ее точки входа. Для этого я написал маленькую dll с реализацией недостающих API. Прилинковал ее статически к msvsmon.exe (все это позволяет делать PETools), а в DllMain подменил адреса в таблице импорта на адреса функций в своей dll. RVA-адреса этих функций можно посмотреть в PE редакторе. Вот и все, мы получили ехешник, который вполне себе загружается под XP и работает. Ну, или не работает.

Что может не работать? Это уже зависит от того, что делает приложение и как. Remote debugger для коммуникации со студией использует WWS API, и если он не находит webservices.dll в %systemroot%, просто показывает диалог, поясняющий, что дальше работа невозможна. К слову сказать, WWS API, вся реализация которого расположена в одной вышеупомянутой библиотеке, первоначально появился только в Seven. Затем вышел патч для Vista. Где-то в блоге MS я прочитал, что под XP он тоже есть, но ссылки на него не было, а в комментах народ написал, что получить webservices.dll можно лишь по какой-то особой лицензии, стоимостью $37k. Сперва я взял кредит взялся за портирование Vista версии WWS API, но потом обнаружил XP вариант в дистрибутиве Win8 :)

В целом хватило всего двух маленьких правок в коде msvsmon.exe (обе делаются в рантайме из моей rdbg2xp.dll), первая из которых позволяет использовать webservices из рабочего каталога, а вторая отключает отложенный вызов WSDCreateDiscoveryPublisher, которой нет в XP, да и не нужно.

Более или менее только этим весь патч и ограничивается, т.к. приложение маленькое. Однако стало гораздо удобнее.
Subscribe

  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 0 comments