summaryrefslogtreecommitdiff
path: root/csgo_wh/src/Hook.cpp
blob: 61dc1ca3e3adbed2bb2efd4290d12524be1a18d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <cstdio>
#include <d3d9.h>
#include <d3dx9.h>
#include <stdarg.h>
#include <windows.h>
#include <psapi.h>
#include <commctrl.h>

#include "Hook.h"
#include "Game.h"


bool Hook::hookEndScene(EndScene_t pHookFunc, EndScene_t *pEndScene, bool unhook)
{
    HMODULE hm_ddrw = GetModuleHandleA("d3d9.dll");
    MODULEINFO md_ddrw;
    LPVOID p_fEndScene;


    memset(&md_ddrw, '\0', sizeof(md_ddrw));
    if (hm_ddrw != NULL && GetModuleInformation(GetCurrentProcess(), hm_ddrw, &md_ddrw, sizeof(md_ddrw)) == TRUE)
    {
        DEBUG_LOG("MODINFO(d3d9.dll): 0x%p (%lu)", md_ddrw.lpBaseOfDll, md_ddrw.SizeOfImage);
        if ( (p_fEndScene = (LPVOID)( (PBYTE)md_ddrw.lpBaseOfDll + ENDSCENE_OFFSET )) != NULL )
        {
            DEBUG_LOG("ENDSCENE: 0x%p | HOOK: 0x%p | REL_OFF: %lu", p_fEndScene, pHookFunc, (DWORD)( (DWORD)pHookFunc - (DWORD)p_fEndScene));
            if (!unhook)
            {
                *pEndScene = (EndScene_t) Hook::Detour((PBYTE)p_fEndScene,(PBYTE)pHookFunc);
            }
            else
            {
                Hook::UnDetour((PBYTE)p_fEndScene);
            }
        }
        else return false;
    }
    else return false;
    return true;
}

BYTE* Hook::Detour(BYTE *src, const BYTE *dst)
{
    BYTE *jmp = (BYTE *) calloc(1, 0x5);
    DWORD dwback;
    VirtualProtect(src - 0x5, 0x7, PAGE_READWRITE, &dwback); // important for changing opcodes in the code section
    jmp[0] = 0xE9; // far jump (32bit offset signed)
    *(DWORD*)(jmp+1) = (DWORD)(dst - src);
    memcpy(src - 0x5, jmp, 0x5);
    src[0] = 0xEB; // short jump (8bit offset signed)
    src[1] = 0xF9; // two complement -> -0x7
    VirtualProtect(src - 0x5, 0x7, dwback, &dwback);
    free(jmp);
    return (src + 0x2); // return the REAL function addr -> MOV EDI,EDI = 2 bytes
}

void Hook::UnDetour(BYTE *src)
{
    BYTE *jmp = (BYTE *) calloc(1, 0x5);
    DWORD dwback;
    VirtualProtect(src - 0x5, 0x7, PAGE_READWRITE, &dwback);
    src[0] = 0x8B; // MOV opcode
    src[1] = 0xFF; // operand0: EDI, operand1: EDI
    jmp[0] = 0x90; // overwrite JMP with NOP-sled
    jmp[1] = 0x90;
    jmp[2] = 0x90;
    jmp[3] = 0x90;
    jmp[4] = 0x90;
    memcpy(src - 0x5, jmp, 0x5);
    VirtualProtect(src - 0x5, 0x7, dwback, &dwback);
    free(jmp);
}