Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: 6310
Последний выпуск: 19.06.2015

Получение скриншота DirectX через внедренную dll

26K
07 апреля 2012 года
3D-GRAF
41 / / 28.06.2008
Здравствуйте!
Необходимо реализовать снятие скриншота в DirectX приложениях (играх).
Поискав информацию в сети, пришёл к выводу, что для этого мне надо внедрять dll в приложение и перехватывать функцию D3DEndScene.
Нашёл несколько примеров, но не удалось ни один из них заставить работать.

С внедрерением проблем нет. DLL внедряется, DllMain выполняется. А вот сделать хук D3DEndScene не выходит.
Важно, чтобы я мог внедрить эту DLL уже непосредственно в работающую программу, а не при запуске.
Может кто-то помочь в решении данной проблемы?

Текущий код DLL:

Код:
#include <d3d9.h>
#include <d3dx9.h>

#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")

#pragma once

typedef HRESULT (WINAPI *CreateDevice_t)(IDirect3D9* Direct3D_Object, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
                    DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
                    IDirect3DDevice9** ppReturnedDeviceInterface);
typedef HRESULT (WINAPI *EndScene_t)(IDirect3DDevice9* surface);


CreateDevice_t D3DCreateDevice_orig;
EndScene_t D3DEndScene_orig;

HRESULT WINAPI D3DCreateDevice_hook(IDirect3D9* Direct3D_Object, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
                    DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
                    IDirect3DDevice9** ppReturnedDeviceInterface);
HRESULT WINAPI D3DEndScene_hook(IDirect3DDevice9* device);

PDWORD IDirect3D9_vtable = NULL;

#define CREATEDEVICE_VTI 16
#define ENDSCENE_VTI 42

HRESULT WINAPI HookCreateDevice();
DWORD WINAPI VTablePatchThread(LPVOID threadParam);


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    HMODULE d3dmodule;
    PBYTE funcAddress;
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        MessageBoxA(NULL, "DLL Injected", "DLL Injected", MB_ICONEXCLAMATION);
        if (HookCreateDevice() == D3D_OK)
        {
            return TRUE;
        } else {
            return FALSE;
        }

        break;
    case DLL_THREAD_ATTACH:
        MessageBoxA(NULL, "DLL_THREAD_ATTACH", "DLL", MB_ICONEXCLAMATION);
        break;
    case DLL_THREAD_DETACH:
        MessageBoxA(NULL, "DLL_THREAD_DETACH", "DLL", MB_ICONEXCLAMATION);
        break;
    case DLL_PROCESS_DETACH:
        MessageBoxA(NULL, "DLL_PROCESS_DETACH", "DLL", MB_ICONEXCLAMATION);
        break;
    }
    return TRUE;
}

HRESULT WINAPI HookCreateDevice()
{
    IDirect3D9* device = Direct3DCreate9(D3D_SDK_VERSION);
    if (!device)
    {
        return D3DERR_INVALIDCALL;
    }
    IDirect3D9_vtable = (DWORD*)*(DWORD*)device;
    device->Release();

    DWORD protectFlag;
    if (VirtualProtect(&IDirect3D9_vtable[CREATEDEVICE_VTI], sizeof(DWORD), PAGE_READWRITE, &protectFlag))
    {
        *(DWORD*)&D3DCreateDevice_orig = IDirect3D9_vtable[CREATEDEVICE_VTI];
        *(DWORD*)&IDirect3D9_vtable[CREATEDEVICE_VTI] = (DWORD)D3DCreateDevice_hook;

        if (!VirtualProtect(&IDirect3D9_vtable[CREATEDEVICE_VTI], sizeof(DWORD), protectFlag, &protectFlag))
        {
            return D3DERR_INVALIDCALL;
        }
    } else {
        return D3DERR_INVALIDCALL;
    }
    return D3D_OK;
}

HRESULT WINAPI D3DCreateDevice_hook(IDirect3D9* Direct3D_Object, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
                    DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
                    IDirect3DDevice9** ppReturnedDeviceInterface)
{
    HRESULT result = D3DCreateDevice_orig(Direct3D_Object, Adapter, DeviceType, hFocusWindow, BehaviorFlags | D3DCREATE_MULTITHREADED, pPresentationParameters, ppReturnedDeviceInterface);

    DWORD protectFlag;
    if (VirtualProtect(&IDirect3D9_vtable[CREATEDEVICE_VTI], sizeof(DWORD), PAGE_READWRITE, &protectFlag))
    {
        *(DWORD*)&IDirect3D9_vtable[CREATEDEVICE_VTI] = (DWORD)D3DCreateDevice_orig;

        if (!VirtualProtect(&IDirect3D9_vtable[CREATEDEVICE_VTI], sizeof(DWORD), protectFlag, &protectFlag))
        {
            return D3DERR_INVALIDCALL;
        }
    } else {
        return D3DERR_INVALIDCALL;
    }

    if (result == D3D_OK)
    {
        IDirect3D9_vtable = (DWORD*)*(DWORD*)*ppReturnedDeviceInterface;
        *(PDWORD)&D3DEndScene_orig = (DWORD)IDirect3D9_vtable[ENDSCENE_VTI];

        if (!CreateThread(NULL, 0, VTablePatchThread, NULL, NULL, NULL))
        {
            return D3DERR_INVALIDCALL;
        }
    }

    return result;
}

DWORD WINAPI VTablePatchThread(LPVOID threadParam)
{
    while (true)
    {
        Sleep(100);

        *(DWORD*)&IDirect3D9_vtable[ENDSCENE_VTI] = (DWORD)D3DEndScene_hook;
    }
}


HRESULT WINAPI D3DEndScene_hook(IDirect3DDevice9* device)
{
    MessageBoxA(NULL, "Endscene", "4", MB_ICONEXCLAMATION);
    HRESULT result = NULL;

    return result;
}
26K
14 апреля 2012 года
3D-GRAF
41 / / 28.06.2008
Проблема решена.
84K
04 августа 2012 года
g68h50
2 / / 04.08.2012
если не сложно скажите как проблема решилась, буду очень признателен!
84K
23 августа 2012 года
g68h50
2 / / 04.08.2012
всем спасибо что откликнулись... проблема решена.

Знаете кого-то, кто может ответить? Поделитесь с ним ссылкой.

Ваш ответ

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог