[d3d9 hook, ImGui] eject dll

totalag

Новичок
Сообщения
8
Реакции
0
Здравствуйте.
Имеется код библиотеки для инжекта с дефолтной менюшкой на ImGui. Никак не получается выгрузить dll без крашей. Без ImGui dll выгружается.
Подскажите пожалуйста где ошибка.

dllmain.cpp

C++:
#include "includes.h"

// data
void* d3d9Device[119];
BYTE EndSceneBytes[7]{ 0 };
tEndScene oEndScene = nullptr;
extern LPDIRECT3DDEVICE9 pDevice = nullptr;

WNDPROC oWndProc;
static HWND windoww = NULL;

extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

void InitImGui(LPDIRECT3DDEVICE9 pDevice) {
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO();
    io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\Arial.ttf", 25, NULL, io.Fonts->GetGlyphRangesCyrillic());
    io.ConfigFlags = ImGuiConfigFlags_NoMouseCursorChange;
    ImGui_ImplWin32_Init(windoww);
    ImGui_ImplDX9_Init(pDevice);

}

//hook function

bool openmenu = false;
bool init = false;
bool crosshair = false;

void APIENTRY hkEndScene(LPDIRECT3DDEVICE9 o_pDevice) {
    if (!pDevice)
        pDevice = o_pDevice;

    if (!init) {

        InitImGui(o_pDevice);
        init = true;

    }


    //DrawFilledRect(25, 25, 100, 100, D3DCOLOR_ARGB(255, 255, 255, 255));

        // unHook
    if (GetAsyncKeyState(VK_END)) {

    //    kiero::shutdown();
        
    }

    // open menu
    if (GetAsyncKeyState(VK_NUMPAD1) & 1) {
        openmenu = !openmenu;
    }
    if (openmenu) {
        ImGui_ImplDX9_NewFrame();
        ImGui_ImplWin32_NewFrame();
        ImGui::NewFrame();

        ImGui::Begin("Hello");
        ImGui::Checkbox(u8"Рисуем crosshair", &crosshair);
        ImGui::End();

        ImGui::EndFrame();
        ImGui::Render();
        ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
    }
    // drawing stuff

        // Function

    if (crosshair) {
        //DrawFilledRect(screenX / 2 - 2, screenY / 2 - 2, 4, 4, D3DCOLOR_ARGB(255, 255, 255, 255));
        
        DrawFilledRect(windowWidth / 2 - 2, windowHeight / 2 - 2, 4, 4, D3DCOLOR_ARGB(255, 255, 255, 255));
    }
    

    //DrawFilledRect(windowWidth / 2 - 2, windowHeight / 2 - 2, 4, 4, D3DCOLOR_ARGB(255, 255, 255, 255));

    oEndScene(pDevice);
}

LRESULT _stdcall WndProc(const HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    if (true && ImGui_ImplWin32_WndProcHandler(hwnd, uMsg, wParam, lParam))
        return true;

    return CallWindowProc(oWndProc, hwnd, uMsg, wParam, lParam);
}




DWORD WINAPI HackThread(HMODULE hModule) {

    // hook
    if (GetD3D9Device(d3d9Device, sizeof(d3d9Device))) {
        memcpy(EndSceneBytes, (char*)d3d9Device[42], 7);

        oEndScene = (tEndScene)TrampHook((char*)d3d9Device[42], (char*)hkEndScene, 7);
        windoww = GetProcessWindow();
        oWndProc = (WNDPROC)SetWindowLongPtr(windoww, GWL_WNDPROC, (LONG_PTR)WndProc);

    }

    while (!GetAsyncKeyState(VK_END)) {
        Sleep(1);
    }

    openmenu = false;
    Beep(300, 100);
    pDevice->Release();
    ImGui_ImplDX9_Shutdown();
    ImGui_ImplWin32_Shutdown();
    //if (ImGui::GetCurrentContext()) ImGui::DestroyContext();

    //FreeLibraryAndExitThread(G.mod, 0);

    // unhook
    Patch((BYTE*)d3d9Device[42], EndSceneBytes, 7);

    //    ImGui_ImplDX9_Shutdown();

    //if (ImGui::GetCurrentContext()) ImGui::DestroyContext();

    // uninject
    FreeLibraryAndExitThread(hModule, 0);
}

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        CloseHandle(CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)HackThread, hModule, 0, nullptr));
    }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
 

Darwin

Команда форума
Администратор
Сообщения
815
Реакции
385
C++:
// unHook
    if (GetAsyncKeyState(VK_END)) {

    //    kiero::shutdown();
        
    }
 

Darwin

Команда форума
Администратор
Сообщения
815
Реакции
385
Кинь в пресент код
C++:
if (GetAsyncKeyState(VK_END) & 0x8000)
    {
        pDevice->Release();
        pSwapChain->Release();
        kiero::shutdown();
        Beep(300, 100);
     
        FreeLibraryAndExitThread(hModule, 0);
    }

Либо замени unhook
 

totalag

Новичок
Сообщения
8
Реакции
0
В проекте не используется kiero, он закоменчен из старого кода, чтобы для себя было наглядно, где происходила раньше остановка. Если я кидаю в hkEndScene, то он не успевает выполняться, т.к. HackThread первее обрабатывается и происходят Patch и FreeLibraryAndExitThread
В коде с kiero кстати не получается выгрузить dll, хотя анхук работает.
 

Darwin

Команда форума
Администратор
Сообщения
815
Реакции
385
В проекте не используется kiero, он закоменчен из старого кода, чтобы для себя было наглядно, где происходила раньше остановка. Если я кидаю в hkEndScene, то он не успевает выполняться, т.к. HackThread первее обрабатывается и происходят Patch и FreeLibraryAndExitThread
В коде с kiero кстати не получается выгрузить dll, хотя анхук работает.
какой хук в общем используешь?
от него и начинай
 

totalag

Новичок
Сообщения
8
Реакции
0
hook.h

C++:
void Patch(BYTE* dst, BYTE* src, unsigned int size);


bool Hook(char* src, char* dst, int len);


char* TrampHook(char* src, char* dst, unsigned int len);

hook.cpp

C++:
#include "includes.h"


void Patch(BYTE* dst, BYTE* src, unsigned int size) {
    DWORD oProc;
    VirtualProtect(dst, size, PAGE_EXECUTE_READWRITE, &oProc);
    memcpy(dst, src, size);
    VirtualProtect(dst, size, oProc,&oProc);
}


bool Hook(char* src, char* dst, int len) {
    if (len < 5) return false;
    DWORD oProc;
    VirtualProtect(src, len, PAGE_EXECUTE_READWRITE, &oProc);
    memset(src, 0x90, len);
    uintptr_t relAddy = (uintptr_t)(dst - src - 5);
    *src = (char)0xE9;
    *(uintptr_t*)(src + 1) = (uintptr_t)relAddy;
    VirtualProtect(src, len, oProc, &oProc);
}


char* TrampHook(char* src, char* dst, unsigned int len) {
    if (len < 5) return 0;
    char* gateway = (char*)VirtualAlloc(0, len + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    memcpy(gateway, src, len);
    uintptr_t jumpAddy = (uintptr_t)(src - gateway - 5);
    *(gateway + len) = (char)0xE9;
    *(uintptr_t*)(gateway + len + 1) = jumpAddy;
    if (Hook(src, dst, len)) {
        return gateway;
    }
    else return nullptr;
}
 

totalag

Новичок
Сообщения
8
Реакции
0
По сути, все работает, если выпилить ImGui

#include "includes.h"

C++:
#include "includes.h"

// data
void* d3d9Device[119];
BYTE EndSceneBytes[7]{ 0 };
tEndScene oEndScene = nullptr;
extern LPDIRECT3DDEVICE9 pDevice = nullptr;



/*
*
* WNDPROC oWndProc;
static HWND windoww = NULL;
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

void InitImGui(LPDIRECT3DDEVICE9 pDevice) {
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO();
    io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\Arial.ttf", 25, NULL, io.Fonts->GetGlyphRangesCyrillic());
    io.ConfigFlags = ImGuiConfigFlags_NoMouseCursorChange;
    ImGui_ImplWin32_Init(windoww);
    ImGui_ImplDX9_Init(pDevice);

}
*/



//hook function

bool openmenu = false;
bool init = false;
bool crosshair = false;

void APIENTRY hkEndScene(LPDIRECT3DDEVICE9 o_pDevice) {
    if (!pDevice)
        pDevice = o_pDevice;


    DrawFilledRect(25, 25, 100, 100, D3DCOLOR_ARGB(255, 255, 255, 255));
    DrawFilledRect(windowWidth / 2 - 2, windowHeight / 2 - 2, 4, 4, D3DCOLOR_ARGB(255, 255, 255, 255));

    /*

    if (!init) {

        InitImGui(o_pDevice);
        init = true;

    }


    

        // unHook
    if (GetAsyncKeyState(VK_END)) {

    //    kiero::shutdown();
        
    }

    // open menu
    if (GetAsyncKeyState(VK_NUMPAD1) & 1) {
        openmenu = !openmenu;
    }
    if (openmenu) {
        ImGui_ImplDX9_NewFrame();
        ImGui_ImplWin32_NewFrame();
        ImGui::NewFrame();

        ImGui::Begin("Hello");
        ImGui::Checkbox(u8"Рисуем crosshair", &crosshair);
        ImGui::End();

        ImGui::EndFrame();
        ImGui::Render();
        ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
    }
    // drawing stuff

        // Function

    if (crosshair) {
        //DrawFilledRect(screenX / 2 - 2, screenY / 2 - 2, 4, 4, D3DCOLOR_ARGB(255, 255, 255, 255));
        
        DrawFilledRect(windowWidth / 2 - 2, windowHeight / 2 - 2, 4, 4, D3DCOLOR_ARGB(255, 255, 255, 255));
    }
    

    //DrawFilledRect(windowWidth / 2 - 2, windowHeight / 2 - 2, 4, 4, D3DCOLOR_ARGB(255, 255, 255, 255));
    */
    oEndScene(pDevice);
}

// ImGui
/*
LRESULT _stdcall WndProc(const HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    if (true && ImGui_ImplWin32_WndProcHandler(hwnd, uMsg, wParam, lParam))
        return true;

    return CallWindowProc(oWndProc, hwnd, uMsg, wParam, lParam);
}
*/





DWORD WINAPI HackThread(HMODULE hModule) {

    // hook
    if (GetD3D9Device(d3d9Device, sizeof(d3d9Device))) {
        memcpy(EndSceneBytes, (char*)d3d9Device[42], 7);

        oEndScene = (tEndScene)TrampHook((char*)d3d9Device[42], (char*)hkEndScene, 7);
        //ImGui
        /*
                windoww = GetProcessWindow();
        oWndProc = (WNDPROC)SetWindowLongPtr(windoww, GWL_WNDPROC, (LONG_PTR)WndProc);
        */


    }

    while (!GetAsyncKeyState(VK_END)) {
        Sleep(1);
    }

    /*
    
        pDevice->Release();
    ImGui_ImplDX9_Shutdown();
    ImGui_ImplWin32_Shutdown();
    
    */

    openmenu = false;
    Beep(300, 100);

    //if (ImGui::GetCurrentContext()) ImGui::DestroyContext();

    //FreeLibraryAndExitThread(G.mod, 0);

    // unhook
    Patch((BYTE*)d3d9Device[42], EndSceneBytes, 7);

    //    ImGui_ImplDX9_Shutdown();

    //if (ImGui::GetCurrentContext()) ImGui::DestroyContext();

    // uninject
    FreeLibraryAndExitThread(hModule, 0);
}

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        CloseHandle(CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)HackThread, hModule, 0, nullptr));
    }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

не хватает видимо знаний в этой области, для того чтобы понять, где и как правильно вызвать прерывание для ImGui
 

totalag

Новичок
Сообщения
8
Реакции
0
В общем, сейчас вопроса два:
1. как не используя kiero сделать эджект либы, если при этом используется ImGui? в этом методе можно снова инжектиться в процесс после эджекта, без крашей если не использовать ImGui
2. как при использовании kiero делать повторные инжекты без закрытия процесса? FreeLibraryAndExitThread(hModule, 0); не эджектит библиотеку почему то (проверил попытавшись заменить билд библиотеки после манипуляций с процессом)
 
Последнее редактирование:
Верх Низ