Обход функции Windows API GetDeviceCaps предотвращает запуск программC++

Программы на C++. Форум разработчиков
Anonymous
 Обход функции Windows API GetDeviceCaps предотвращает запуск программ

Сообщение Anonymous »

У меня есть следующий базовый код DLL, который обходит функцию Windows API WindowsEnumDisplaySettingsA:

Код: Выделить всё

static BOOL(WINAPI* WindowsEnumDisplaySettingsA)(LPCSTR lpszDeviceName, DWORD iModeNum,
DEVMODEA* lpDevMode) = EnumDisplaySettingsA;

BOOL WINAPI DetouredEnumDisplaySettingsA(LPCSTR lpszDeviceName, DWORD iModeNum,
DEVMODEA* lpDevMode)
{
// Call the real GetDeviceCaps function
return WindowsEnumDisplaySettingsA(lpszDeviceName, iModeNum, lpDevMode);
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
// Restore the in memory import table after we are loaded by withdll.exe
DetourRestoreAfterWith();

// Switch based on the reason for this function call
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:

// Attach the function detours
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)WindowsEnumDisplaySettingsA, DetouredEnumDisplaySettingsA);
DetourTransactionCommit();

break;
case DLL_PROCESS_DETACH:
// Detach the function detours
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)WindowsEnumDisplaySettingsA, DetouredEnumDisplaySettingsA);
DetourTransactionCommit();

break;
}

return TRUE;
}
который отлично работает при запуске программы следующей командой:

Код: Выделить всё

withdll.exe /d:test.dll program.exe
Однако, если я изменю объездную функцию на GetDeviceCaps и получу следующий код (единственные изменения — это имя и подпись функции):

Код: Выделить всё

static int (WINAPI* WindowsGetDeviceCaps)(HDC hdc, int index) = GetDeviceCaps;

int DetouredGetDeviceCaps(HDC hdc, int index)
{
// Call the real GetDeviceCaps function
return WindowsGetDeviceCaps(hdc, index);
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
// Restore the in memory import table after we are loaded by withdll.exe
DetourRestoreAfterWith();

// Switch based on the reason for this function call
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:

// Attach the function detours
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)WindowsGetDeviceCaps, DetouredGetDeviceCaps);
DetourTransactionCommit();

break;
case DLL_PROCESS_DETACH:
// Detach the function detours
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)WindowsGetDeviceCaps, DetouredGetDeviceCaps);
DetourTransactionCommit();

break;
}

return TRUE;
}
и запустите приложение с помощью той же команды, оно просто выйдет из строя без каких-либо ошибок. В средстве просмотра событий я обнаружил следующую ошибку:

Код: Выделить всё

Faulting application name: program.exe, version: 0.0.0.0, time stamp: 0x5432e000
Faulting module name: TEST.dll, version: 0.0.0.0, time stamp: 0x66ff615a
Exception code: 0xc0000005
Fault offset: 0x62010b0b
Faulting process id: 0x15c0
Faulting application start time: 0x01db1611a56f2db4
Faulting application path: C:\Path\To\Program\program.exe
Faulting module path: C:\Path\To\Program\TEST.dll
Report Id: 79a05641-2f2a-48d3-b2b2-ae9b96d7f60f
Faulting package full name:
Faulting package-relative application ID:
Код исключения, похоже, соответствует STATUS_ACCESS_VIOLATION согласно https://learn.microsoft.com/en-us/opens ... a1078-e883 -4972-9bbc-49e60bebca55.
Я пробовал это с несколькими различными приложениями, и все они молча терпят неудачу при обходе функции GetDeviceCaps, но работают нормально, если я обхожу другую функцию. Кто-нибудь знает, как я могу обойти функцию GetDeviceCaps в приложении, не препятствуя запуску приложения?

Подробнее здесь: https://stackoverflow.com/questions/790 ... m-starting

Вернуться в «C++»