Вопрос [CLOSED] После вызова ID3DXSprite::Begin не работают DirectX хуки

Статус
В этой теме нельзя размещать новые ответы.
Пользователь
Статус
Оффлайн
Регистрация
22 Июн 2020
Сообщения
185
Реакции[?]
69
Поинты[?]
41K
К такому выводу я пришел поочередно убирая код, убрал весь код кроме sprite->Begin() после вызова которого хуки hkEndScene, hkPresent уже больше никогда не вызываются. Убрал sprite->Begin() оставил все остальное - все работает. Спрайт мне нужен чтобы нормально рисовать текст и картинки, весь код рендера я сделал отдельно (
Пожалуйста, авторизуйтесь для просмотра ссылки.
, осторожно, может быть передоз кринжа), все работает. Перенес в чит, проблема выше. Я подумал что возможно меняется указатель не DirectXDevice, но это не так. Попробовал вызвать font->DrawTextA(NULL, ...) проблема та же самая, видимо потому что тогда DrawTextA создает свой спрайт и вызывает Begin.

Hooks:
HRESULT __stdcall hkEndScene(IDirect3DDevice9* thisptr) {
    static tEndScene oEndScene = (tEndScene)Hooks::DirectXDeviceVMT->GetOriginal(42);


    return oEndScene(thisptr);
}

HRESULT __stdcall hkReset(IDirect3DDevice9* thisptr, D3DPRESENT_PARAMETERS* params) {
    static tReset oReset = (tReset)Hooks::DirectXDeviceVMT->GetOriginal(16);

    Render->Reset();

    return oReset(thisptr, params);
}

HRESULT __stdcall hkPresent(IDirect3DDevice9* thisptr, const RECT* src, const RECT* dest, HWND window, const RGNDATA* dirtyRegion) {
    static tPresent oPresent = (tPresent)Hooks::DirectXDeviceVMT->GetOriginal(17);
    static bool bD3D9Init = false;
    if (!bD3D9Init) {
        bD3D9Init = true;
        Render->Init(thisptr);
        return oPresent(thisptr, src, dest, window, dirtyRegion);
    }

    if (Cheat.Unloaded)
        return oPresent(thisptr, src, dest, window, dirtyRegion);

    static auto movups_14a781e4 = Utils::PatternScan("client.dll", "0F 10 05 ? ? ? ? 8D 85 ? ? ? ? B9", 3);

    Cheat.InGame = EngineClient->IsConnected() && EngineClient->IsInGame();

    if (Cheat.InGame && !PlayerResource)
        PlayerResource = **(CCSPlayerResource***)(Utils::PatternScan("client.dll", "8B 3D ? ? ? ? 85 FF 0F 84 ? ? ? ? 81 C7", 0x2));
    else if (!Cheat.InGame)
        PlayerResource = nullptr;

    if (thisptr->BeginScene() == D3D_OK) {
        Render->EndScene();
        thisptr->EndScene();
    }
    return oPresent(thisptr, src, dest, window, dirtyRegion);
}
Код, что сейчас в Present, раньше был в EndScene но и так и так проблема остается.

Render:
void CRender::Init(IDirect3DDevice9* dev) {
    device = dev;
    D3DXCreateSprite(device, &sprite);

    auto creationParams = D3DDEVICE_CREATION_PARAMETERS();
    device->GetCreationParameters(&creationParams);
    g_HWND = creationParams.hFocusWindow;

    D3DVIEWPORT9 vp;
    device->GetViewport(&vp);
    Cheat.ScreenSize.x = vp.Width;
    Cheat.ScreenSize.y = vp.Height;

    DWORD nfonts;

    Verdana = InitFont("Verdana", 12, 400, CLEARTYPE_NATURAL_QUALITY);
    MenuFont = InitFont("at\\MuseoSansCyrl.ttf", 18);
    MenuBigFont = InitFont("at\\MuseoSansCyrl.ttf", 20);
    MuseoSansCyrlLarge = InitFont("at\\MuseoSansCyrl.ttf", 32);
    SmallFont = InitFont("at\\Smallest Pixel-7.ttf", 10, 400, 0);
    Museo = InitFont("at\\MuseoSansCyrl.ttf", 14);

    renderInitialized = true;
}

void CRender::BeginFrame() {
    if (!vecDrawData.empty())
        vecDrawData.clear();
}

void CRender::EndScene() {
    if (!renderInitialized)
        return;

    if (vecSafeDrawData.empty())
        return;

    device->GetRenderState(D3DRS_COLORWRITEENABLE, &colorwrite);
    device->GetRenderState(D3DRS_SRGBWRITEENABLE, &srgbwrite);
    device->SetRenderState(D3DRS_COLORWRITEENABLE, 0xffffffff);
    device->SetRenderState(D3DRS_SRGBWRITEENABLE, false);
    device->GetRenderState(D3DRS_COLORWRITEENABLE, &dwOld_D3DRS_COLORWRITEENABLE);
    device->GetVertexDeclaration(&vert_dec);
    device->GetVertexShader(&vert_shader);
    //device->SetVertexShader(nullptr);
    //device->SetPixelShader(nullptr);
    //device->SetTexture(0, nullptr);
    //device->SetRenderState(D3DRS_COLORWRITEENABLE, 0xffffffff);
    //device->SetRenderState(D3DRS_SRGBWRITEENABLE, false);
    //device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
    //device->SetRenderState(D3DRS_ZENABLE, false);
    //device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    //device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    //device->SetSamplerState(NULL, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
    //device->SetSamplerState(NULL, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
    //device->SetSamplerState(NULL, D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP);
    //device->SetSamplerState(NULL, D3DSAMP_SRGBTEXTURE, NULL);

    device->SetPixelShader(nullptr);
    device->SetVertexShader(nullptr);
    device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
    device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
    device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
    device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
    device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
    device->SetRenderState(D3DRS_ZENABLE, FALSE);
    device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    device->SetRenderState(D3DRS_FOGENABLE, FALSE);
    device->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
    device->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
    device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
    device->SetRenderState(D3DRS_CLIPPING, TRUE);
    device->SetRenderState(D3DRS_LIGHTING, FALSE);
    device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
    device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
    device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
    device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
    device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
    device->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
    device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);

    if (sprite->Begin(D3DXSPRITE_ALPHABLEND) != S_OK)
        return;
    device->GetFVF(&oldFVF);
    device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);

    std::unique_lock<std::shared_mutex> lock(drawMutex);

    for (const auto& data : vecSafeDrawData) {
        if (!data.object.has_value())
            continue;

        switch (data.type)
        {
        case EDrawType::PRIMITIVE: {
            const auto& object = std::any_cast<d3d9primitive_t>(data.object);
            device->DrawPrimitiveUP(object.primitiveType, object.primitiveCount, object.pVertexData, sizeof(Vertex));
            delete[] object.pVertexData;
            break;
        }
        case EDrawType::TEXT: {
            const auto& object = std::any_cast<text_command_t>(data.object);
            object.font->DrawTextA(sprite, object.text, -1, object.pRect, object.clipType, object.color);
            break;
        }
        case EDrawType::IMAGE: {
            const auto& object = std::any_cast<image_command_t>(data.object);
            sprite->Draw(object.texture, object.pSrcRect, NULL, object.pos, object.color);
            break;
        }
        case EDrawType::CLIP: {
            const auto& object = std::any_cast<clip_command_t>(data.object);
            if (object.remove) {
                device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
            }
            else {
                device->SetScissorRect(object.rect);
                device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
            }
            break;
        }
        case EDrawType::SETANTIALIAS: {
            const auto& object = std::any_cast<bool>(data.object);
            device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, object);
            device->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, object);
            break;
        }
        case EDrawType::TEXTURE_APPLY: {
            sprite->Flush();
            device->SetTexture(0, 0);
        }
        }
    };

    device->SetFVF(oldFVF);
    if (sprite->End() != S_OK)
        return;

    DirectXDevice->SetRenderState(D3DRS_COLORWRITEENABLE, colorwrite);
    DirectXDevice->SetRenderState(D3DRS_SRGBWRITEENABLE, srgbwrite);
    DirectXDevice->SetRenderState(D3DRS_COLORWRITEENABLE, dwOld_D3DRS_COLORWRITEENABLE);
    DirectXDevice->SetRenderState(D3DRS_SRGBWRITEENABLE, true);
    DirectXDevice->SetVertexDeclaration(vert_dec);
    DirectXDevice->SetVertexShader(vert_shader);
}

void CRender::EndFrame() {
    std::unique_lock<std::shared_mutex> lock(drawMutex);
    vecDrawData.swap(vecSafeDrawData);
}

void CRender::Reset() {
    if (sprite)
        sprite->OnResetDevice();
}
Помогите, в чем может быть проблема?
 
Пользователь
Статус
Оффлайн
Регистрация
22 Июн 2020
Сообщения
185
Реакции[?]
69
Поинты[?]
41K
Дебаггинг через x32dbg показал, что до точки вызова EndScene игра доходит и вызывает, но хук почему то не вызывается, может ли он "слететь"?
 
Пользователь
Статус
Оффлайн
Регистрация
22 Июн 2020
Сообщения
185
Реакции[?]
69
Поинты[?]
41K
Закрыто, проблему решил хукнув EndScene по паттерну а не вмт, а мучался 3 дня...
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху Снизу