Source Code Hooking Externally

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

Solaire

Respected Hacker
Dank Tier VIP
Dec 15, 2013
1,051
16,353
62
This one took a bit of work to get running, but it does the job! If you find any memory leaks, overdone segments, things I could have done better, tell me! I'll do my best to fix it :)

You have to disable incremental linking to grab the hooking function.
You also have to pad the end of the hook function with two int 3's.

extHook.h
C++:
#include <Windows.h>
#include <vector>

using std::vector;

class extHook
{
protected:
    virtual void insertFunction();
    virtual int grabBytes();
    virtual bool Restore();
    virtual bool CreateDetour();
    vector<BYTE> m_ourFunctBytes;
    DWORD m_toHook;
    DWORD m_ourFunct;
    DWORD m_ourCave;
    BYTE * m_restoreBytes;
    DWORD m_len;
    HANDLE m_handle;
    bool m_isHooked;

public:
    extHook(HANDLE handle, DWORD ourFunction, DWORD toHook, int len) :
        m_handle(handle),
        m_ourFunct(ourFunction),
        m_toHook(toHook),
        m_len(len),
        m_isHooked(false),
        m_restoreBytes(new BYTE[500])
    { }
    ~extHook() { delete[] m_restoreBytes; }

    virtual void ToggleHook();
};

extHook.cpp
C++:
#include <Windows.h>
#include <vector>
#include "extHook.h"

using std::vector;

int extHook::grabBytes()
{
    for (int i = 0;; i++)
    {
        if ((*(BYTE*)(m_ourFunct + i)) == 0xCC && (*(BYTE*)(m_ourFunct + i - 1)) == 0xC3 || (*(BYTE*)(m_ourFunct + i + 1)) == 0xCC && (*(BYTE*)(m_ourFunct + i)) == 0xCC)
        {
            return i; // Returns the number of bytes found
        }

        //Add the byte to the vector
        m_ourFunctBytes.push_back(*(BYTE*)(m_ourFunct + i));
    }
}

void extHook::insertFunction()
{
    DWORD oldProtect, Bkup;

    //Grab the bytes of our hook function
    int numOfBytes = grabBytes();
    BYTE * tempBytes = new BYTE[m_ourFunctBytes.size()];

    //Move all of the bytes into an array
    int it = 0;
    for (auto i : m_ourFunctBytes)
    {
        tempBytes[it] = (BYTE)i;
        it++;
    }
   
    //Allocate memory in the other process to place our hook function in
    BYTE jump = 0xE9;
    LPVOID arg = (LPVOID)VirtualAllocEx(m_handle, NULL, numOfBytes + 0x5, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

    //This is so that the program can run our function, and so that we can write our bytes there.
    //We leave it at PAGE_EXECUTE_READWRITE so the program can run it.
    VirtualProtectEx(m_handle, (LPVOID)arg, numOfBytes + 0x5, PAGE_EXECUTE_READWRITE, &oldProtect);
    //Calculate the jump back to the original function
    DWORD relAddy = (m_toHook - (DWORD)arg) - 5;
    //Put our function into the allocated memory
    WriteProcessMemory(m_handle, arg, tempBytes, numOfBytes, NULL);
    //At the end of it, add a jump
    WriteProcessMemory(m_handle, (LPVOID)((DWORD)arg + numOfBytes), &jump, sizeof(jump), NULL);
    WriteProcessMemory(m_handle, (LPVOID)((DWORD)arg + numOfBytes + 0x1), &relAddy, sizeof(relAddy), NULL);

    //Used in the CreateDetour function
    m_ourCave = (DWORD)arg;
    //Prevent mem leaks
    delete[] tempBytes;
}

bool extHook::CreateDetour()
{
    DWORD oldProtect, Bkup, relativeAddy;

    //The hook jmp takes 5 bytes
    if (m_len < 5)
    {
        return false;
    }

    //Make sure we can even write to the section of memory
    if (!VirtualProtectEx(m_handle, (LPVOID)m_toHook, m_len, PAGE_EXECUTE_READWRITE, &oldProtect))
    {
        return false;
    }

    //Just some variables needed to apply the hook
    BYTE jump = 0xE9;
    BYTE NOP = 0x90;
    BYTE NOPS[] = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };

    //Put the original function bytes into m_restoreBytes for when we want to undo the hook
    ReadProcessMemory(m_handle, (LPVOID)(m_toHook), m_restoreBytes, m_len, NULL);

    //Calculate the jump to the hook function
    relativeAddy = (m_ourCave - m_toHook) - 5;
    //Write the jump
    WriteProcessMemory(m_handle, (LPVOID)m_toHook, &jump, sizeof(jump), NULL);
    WriteProcessMemory(m_handle, (LPVOID)(m_toHook + 0x1), &relativeAddy, sizeof(relativeAddy), NULL);

    //Write all of the nops at once, instead of making multiple calls
    int new_len = m_len - 5;
    if (new_len > 0)
    {
        WriteProcessMemory(m_handle, (LPVOID)(m_toHook + 0x5), NOPS, new_len, NULL);
    }

    //Restore the previous protection
    if (!VirtualProtectEx(m_handle, (LPVOID)m_toHook, m_len, oldProtect, &Bkup))
    {
        return false;
    }

    return true;
}

bool extHook::Restore()
{
    DWORD oldProtect, Bkup;

    //So we can restore the bytes
    if (!VirtualProtectEx(m_handle, (LPVOID)m_toHook, m_len, PAGE_EXECUTE_READWRITE, &oldProtect))
    {
        return false;
    }

    //Write the original bytes back into the function
    WriteProcessMemory(m_handle, (LPVOID)m_toHook, m_restoreBytes, m_len, NULL);
   
    if (!VirtualProtectEx(m_handle, (LPVOID)m_toHook, m_len, oldProtect, &Bkup))
    {
        return false;
    }

    //Free the memory we allocated for our hook
    VirtualFreeEx(m_handle, (LPVOID)m_ourCave, 0, MEM_RELEASE);

    return true;
}

//This ones pretty self explanatory.
void extHook::ToggleHook()
{
    if (m_isHooked == false)
    {
        insertFunction();
        CreateDetour();
        m_isHooked = true;
    }

    else if (m_isHooked == true)
    {
        Restore();
        m_isHooked = false;
    }
}

Using it:
C++:
//The hook function for the top of the TakeDamage funct in AssaultCube.
//You have to pad the end of it with two int 3s
__declspec(naked) void ourFunction()
{
    __asm
    {
        push ebp
        mov ebp,esp
        and esp,-08h
        int 3
        int 3
    }
}

void Engine(Wisrd obj);

int main()
{
    //This just grabs the handle for me
    Wisrd obj("AssaultCube");
    //Because I can
    Engine(obj);

    return 0;
}

void Engine(Wisrd obj)
{
    //First parameter is the handle
    //Second is our hook function
    //Third is the address of the spot we're hooking
    //Last is the length of the hook
    extHook hook(obj.procHandle(), (DWORD)ourFunction, (DWORD)0x429C20, 6);

    while (1)
    {
        if (GetAsyncKeyState(VK_NUMPAD1) & 1)
        {
            hook.ToggleHook();
        }

        if (GetAsyncKeyState(VK_NUMPAD9) & 1)
        {
            break;
        }
    }
}
https://guidedhacking.com/threads/code-detouring-hooking-guide.14185/
 
Last edited by a moderator:

Solaire

Respected Hacker
Dank Tier VIP
Dec 15, 2013
1,051
16,353
62
Thanks guys! I'll add an update later today that includes a few new things:

1. Automatically copies the bytes from the hook spot, and places it after your functions code so you don't have to
2. (This one might happen, don't know yet) Allow the user to decide whether the overwritten bytes get put before your code, or after, or ultimately whether they do get copied or not.
 

c5

Kim Kong Trasher
Dank Tier VIP
Dank Tier Donator
Jul 19, 2012
1,187
12,638
76
This grabBytes implementation is going to stab you in your back at some point.

Fun project but I don't see why all the trouble, I mean you are still limiting yourself by staying external. Just go internal then.

You cant do much in the hook, only basic stuff. For example any API call (that needs to be resolved) and you'll crash
 

Solaire

Respected Hacker
Dank Tier VIP
Dec 15, 2013
1,051
16,353
62
This grabBytes implementation is going to stab you in your back at some point.

Fun project but I don't see why all the trouble, I mean you are still limiting yourself by staying external. Just go internal then.

You cant do much in the hook, only basic stuff. For example any API call (that needs to be resolved) and you'll crash
I know heh. It was mostly for the fun and knowledge :p. Once I have more knowledge and am better at coding, I'll definitely replace the grabBytes function with a real interpreter so that I don't have the issue of possible opcode conflicts. Currently I just cba to set it all up :p. Though for more advanced hooks, yeah, internal is the way to go.
 
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods