Можно ли переписать функции Windows API и вызывать их после? - PullRequest
0 голосов
/ 14 октября 2011

Я хочу изменить собственные функции, доступные в Windows API, такие как CreateWindowEx или ShowWindow таким образом, чтобы, когда приложение компилируется с включенными этими функциями, оно вместо этого вызывало мои функции, выполняло там задачи,и затем вызовите оригинальную встроенную функцию.

Другими словами, я хочу каким-то образом проксировать функции, все еще используя те же имена (поэтому, если программа была написана для компиляции с собственным API, простодобавление этих функций изменило бы способ обработки этих собственных функций)

HWND WINAPI CreateWindowEx(
  __in      DWORD dwExStyle,
  __in_opt  LPCTSTR lpClassName,
  __in_opt  LPCTSTR lpWindowName,
  __in      DWORD dwStyle,
  __in      int x,
  __in      int y,
  __in      int nWidth,
  __in      int nHeight,
  __in_opt  HWND hWndParent,
  __in_opt  HMENU hMenu,
  __in_opt  HINSTANCE hInstance,
  __in_opt  LPVOID lpParam
) {

    //my custom code here....

    // done with my custom code... so now I want to run the native function
    return CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
}

Это (по очевидным причинам) приводит к переполнению стека, так как он продолжает вызывать себя снова и снова.Я хотел бы, чтобы при вызове он выполнял созданную мной пользовательскую функцию, а затем запускал встроенные функции, доступные в Windows API.

Я довольно новичок в c ++, нонапример, во многих других языках я мог хранить ссылку на нативную функцию под другим именем, которое затем мог вызывать внутри своей пользовательской функции.Есть ли что-нибудь подобное в c ++?

Ответы [ 3 ]

3 голосов
/ 14 октября 2011

Как я уже писал в комментарии, прародителем многих библиотек перехвата был, вероятно, Microsoft Detours

Теперь, когда он больше не является бесплатным, существуют различные альтернативы.Здесь приведено сравнение некоторых из них (ссылка удалена. Я не уверен, что это было безопасно. Попробуйте поискать в Google «Microsoft Detours - это библиотека, используемая для конкретного перехвата») и выберите источник или, проще говоря, для альтернатив Detours.

М-м-м, кажется, единственной бесплатной альтернативой на данный момент являются http://easyhook.codeplex.com/ и http://www.codeproject.com/KB/system/mini_hook_engine.aspx

Существует вопрос SO: Альтернативная альтернатива перехвату реестра если вы заинтересованы.

1 голос
/ 14 октября 2011

Одна из интерпретаций вашего вопроса состоит в том, что у вас есть проект с исходным кодом, и вы хотите изменить этот проект, чтобы он использовал ваши собственные версии определенных функций winapi.

Вот решение, которое вы можете реализовать для каждой импортированной функции API. Пример здесь для ShowWindow:

#define ShowWindow Deleted_Winapi_ShowWindow // prevent windows.h from defining ShowWindow
#include <windows.h>
#undef ShowWindow

namespace HiddenWinapi
{
    extern "C"
    {
        // Do what windows.h does, but hide it inside a namespace.
        WINUSERAPI BOOL WINAPI ShowWindow( __in HWND hWnd, __in int nCmdShow);
    }
}

// make your own function to be called instead of the API, and delegate to the actual API in the namespace.
BOOL WINAPI ShowWindow(HWND hwnd, int nCmdShow)
{
    // ... do stuff ...
    // call the original API
    return HiddenWinapi::ShowWindow(hwnd, nCmdShow);
}

Чтобы использовать это решение для CreateWindowEx, вам необходимо указать фактическое имя импортированной функции (например, CreateWindowExW), поскольку CreateWindowEx - это просто макрос, который расширяется до CreateWindowExW или CreateWindowExA.

Вот решение, которое заменяет макрос вашим собственным, но я думаю, что во всех случаях было бы лучше использовать вышеуказанное решение.

#include <windows.h>

#undef CreateWindowEx

// Note that this is a unicode-only version. If your app mixes A and W versions, see 
// the solution below for non-macro APIs.
HWND WINAPI CreateWindowEx(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
{
    // ... do stuff ...
    // call the REAL function.
    return CreateWindowExW(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
}
0 голосов
/ 14 октября 2011

Если вы хотите сделать это самостоятельно, проще всего изменить таблицу адресов импорта в заголовке PE (переносимого исполняемого файла). Это не тривиально, хотя.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...