Как заменить вызовы функций WinAPI в проекте MS VC++ своей реализацией (имя и набор параметров совпадают)?

StackOverflow https://stackoverflow.com/questions/60641

  •  09-06-2019
  •  | 
  •  

Вопрос

Мне нужно заменить все вызовы WinAPI

  • СоздатьФайл,
  • ЧитатьФайл,
  • УстановитьFilePointer,
  • ЗакрытьРучка

с моей собственной реализацией (которая использует низкоуровневое чтение файлов через Bluetooth).Код, в котором будут заменены функции, — Video File Player и он уже работает с обычными hdd-файлами.Также необходимо, чтобы Video Player по-прежнему мог воспроизводить файлы с жесткого диска, если файл на входе VideoPlayer является обычным файлом жесткого диска.

Какова наилучшая практика для такой задачи?

Это было полезно?

Решение

Я предлагаю вам выполнить следующие шаги:

  1. Напишите набор функций-оболочек, например MyCreateFile, MyReadFile и т. д., которые изначально просто вызывают соответствующий API и передают те же аргументы без изменений.
  2. Используйте текстовый редактор для поиска всех вызовов исходных API и замените их вызовами новых функций-оболочек.
  3. Проверьте, что приложение по-прежнему работает правильно.
  4. Измените функции-оболочки в соответствии со своими целями.

Обратите внимание, что CreateFile — это макрос, который расширяется до CreateFileW или CreateFileA, в зависимости от того, определен ли UNICODE.Рассмотрите возможность использования LPCTSTR и ТЧАР-функции так что ваше приложение может быть построено как в формате ANSI, так и в формате Unicode.

Пожалуйста, не используйте #define, как предлагается в других ответах здесь, поскольку это просто приведет к проблемам с обслуживанием, и, как правильно отмечает Максимилиан, это не лучшая практика.

Другие советы

Вы можете просто написать свои новые функции в специальном пространстве имен.например

namespace Bluetooth
{
  void CreateFile(/*params*/);
  void etc...
}

Тогда в вашем коде единственное, что вам нужно будет изменить, это:

if (::CreateFile(...))
{
}

к

if (Bluetooth::CreateFile(...))
{
}

Легкий!:)

Если вы пытаетесь перехватить вызовы этих API из другого приложения, рассмотрите возможность Объезды.

Если вы можете редактировать код, вам следует просто переписать его, чтобы использовать собственный API, который делает то, что вы хотите.В противном случае используйте технику Максимилиана, но имейте в виду, что это ужасный ремонт.

Если вы не можете редактировать код, вы можете исправить таблицы импорта, чтобы перенаправлять вызовы на ваш собственный код.Описание этой техники можно найти в Эта статья - найдите раздел «Шпионаж путем изменения таблицы адресов импорта».

Это опасно, но если вы будете осторожны, у вас все получится.Также проверьте Microsoft: обходные пути, который делает то же самое, но не требует от вас возиться с самим исправлением.

Если вы действительно хотите перехватить API, посмотрите syringe.dll (L-GPL).

Я не думаю, что это лучшая практика, но она должна сработать, если вы поместите ее во включаемый файл, который включен везде, где вызывается функция, которую вы хотите изменить:

#define CreateFile MyCreateFile

HRESULT MyCreateFile(whatever the params are);

Реализация MyCreateFile выглядит примерно так:

#undef CreateFile
HRESULT MyCreateFile(NobodyCanRememberParamListsLikeThat params)
{
    if (InputIsNormalFile())
        CreateFile(params);
    else
        // do your thing
}

По сути, вы делаете каждый вызов CreateFile вызовом MyCreateFile, где вы можете решить, хотите ли вы использовать свою собственную реализацию или исходную.

Отказ от ответственности:Я считаю, что это некрасиво, и я бы этого не делал.Я бы предпочел найти и заменить все вхождения или что-то в этом роде.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top