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

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

  • CreateFile,
  • ReadFile,
  • SetFilePointer,
  • CloseHandle

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

Что лучше всего подходит для такой задачи?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
1 613
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

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

#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, где вы можете решить, хотите ли вы использовать свою собственную реализацию или исходную.

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

Спасибо! Как вы думаете, лучше будет написать какой-нибудь класс, где будет определен метод MyCreateFile (), а затем Ctrl-H Все вызовы CreateFile в коде?

Svetlana 13.09.2008 20:41

Да, я предлагаю вам это сделать.

Maximilian 13.09.2008 22:14

В основном просто делайте то, что предложил ChrisN.

Maximilian 13.09.2008 22:15

На самом деле, вы можете получить выгоду, написав такой класс, особенно если ваши функции должны поддерживать какое-либо дополнительное состояние / данные во время чтения или записи файла.

ChrisN 15.09.2008 01:05

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

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

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

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

да, все дело в изменении кода, а не во взломе таблиц импорта :) спасибо.

Svetlana 13.09.2008 20:42
Ответ принят как подходящий

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

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

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

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

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

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

Тогда в вашем коде вам нужно будет изменить только следующее:

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

к

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

Легко! :)

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

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