 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Viloresi Expert Cheater
Reputation: 0
Joined: 02 Feb 2017 Posts: 149
|
Posted: Tue Aug 06, 2019 4:08 pm Post subject: How to set a VEH hook with an Hardware breakpoint C++ ? |
|
|
I'm trying to hook a function of a game by using VEH hooking , I've taken this code from another forum (not sure if I can post the name) the problem is that it crashes and the exception never gets raised, I'm using Visual studio 2019 and I'm injecting through a dll in 64 bit. :
this is the dllmain.cpp
Code: |
#include "CContextHook.h"
#include <stdlib.h>
CContextHook GContextHook;
LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS* e)
{
if (e->ExceptionRecord->ExceptionCode != EXCEPTION_SINGLE_STEP)
{
return EXCEPTION_CONTINUE_SEARCH;
}
Context_t* Context = GContextHook.GetContextInfo();
if (Context)
{
if (e->ExceptionRecord->ExceptionAddress == (PVOID)Context->Hook1 ||
e->ExceptionRecord->ExceptionAddress == (PVOID)Context->Hook2 ||
e->ExceptionRecord->ExceptionAddress == (PVOID)Context->Hook3 ||
e->ExceptionRecord->ExceptionAddress == (PVOID)Context->Hook4)
{
Handler_t Handler = GContextHook.GetHandlerInfo();
if (Handler)
{
Handler(Context, e);
}
return EXCEPTION_CONTINUE_EXECUTION;
}
}
return EXCEPTION_CONTINUE_SEARCH;
}
bool CContextHook::InitiateContext(Handler_t ContextHandler, Context_t* C)
{
if (C == NULL || ContextHandler == NULL)
return false;
m_Handler = ContextHandler;
memcpy(&m_Context, C, sizeof(Context_t));
if (IsReady(&C->Hook1) == false)
return false;
HANDLE hMainThread = GetMainThread();
if (hMainThread == INVALID_HANDLE_VALUE)
return false;
srand(GetTickCount());
PVOID pHandler = AddVectoredExceptionHandler(rand() % 0xFFFFFF, ExceptionHandler);
if (pHandler == NULL)
return false;
m_pHandler = pHandler;
CONTEXT c;
c.ContextFlags = CONTEXT_DEBUG_REGISTERS;
SuspendThread(hMainThread);
GetThreadContext(hMainThread, &c);
c.Dr0 = C->Hook1;
int SevenFlags = (1 << 0);
if (IsReady(&C->Hook2))
{
SevenFlags |= (1 << 2);
c.Dr1 = C->Hook2;
}
if (IsReady(&C->Hook3))
{
SevenFlags |= (1 << 4);
c.Dr2 = C->Hook3;
}
if (IsReady(&C->Hook4))
{
SevenFlags |= (1 << 6);
c.Dr3 = C->Hook4;
}
c.Dr6 = 0x00000000;
c.Dr7 = SevenFlags;
SetThreadContext(hMainThread, &c);
ResumeThread(hMainThread);
return true;
}
Context_t* CContextHook::GetContextInfo(void)
{
return &m_Context;
}
Handler_t CContextHook::GetHandlerInfo(void)
{
return m_Handler;
}
bool CContextHook::ClearContext(void)
{
HANDLE hMainThread = GetMainThread();
if (hMainThread == INVALID_HANDLE_VALUE)
return false;
CONTEXT c;
c.ContextFlags = CONTEXT_DEBUG_REGISTERS;
SuspendThread(hMainThread);
GetThreadContext(hMainThread, &c);
c.Dr0 = 0;
c.Dr1 = 0;
c.Dr2 = 0;
c.Dr3 = 0;
c.Dr6 = 0;
c.Dr7 = 0;
SetThreadContext(hMainThread, &c);
ResumeThread(hMainThread);
return true;
}
bool CContextHook::IsReady(unsigned long* H)
{
if (!H)
return false;
return (*H != NULL);
}
DWORD CContextHook::GetProcessThreadId(unsigned long ProcessId)
{
HANDLE hSnapThread = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, ProcessId);
if (hSnapThread == INVALID_HANDLE_VALUE)
{
return NULL;
}
THREADENTRY32 te;
te.dwSize = sizeof(THREADENTRY32);
if (Thread32First(hSnapThread, &te))
{
do
{
if (te.th32OwnerProcessID == ProcessId)
{
CloseHandle(hSnapThread);
return te.th32ThreadID;
}
} while (Thread32Next(hSnapThread, &te));
}
CloseHandle(hSnapThread);
return 0;
}
#define ADDRESSTOHOOK 0x7FFDF899FD90
void ContextHandler(Context_t* C, EXCEPTION_POINTERS* E)
{
MessageBoxA(0, "BPHIT", "BPHIT BPHIT", 0);
if (!C || !E)
return;
switch (E->ContextRecord->Rip)
{
case ADDRESSTOHOOK:
{
MessageBoxA(0, "BPHIT", "BPHIT BPHIT", 0);
E->ContextRecord->Rax = 1;
//GLogging.AddToLogFileA("hook.log", "BP HIT");
break;
}
}
}
void Initialize3Context()
{
Context_t C;
C.Hook1 = ADDRESSTOHOOK;
if (GContextHook.InitiateContext(ContextHandler, &C))
{
MessageBoxA(0, "", "HOOKED SUCCESS", 0);
}
else
{
MessageBoxA(0, "", "FAILURE ", 0);
}
}
HANDLE CContextHook::GetMainThread(void)
{
DWORD ProcessId = GetCurrentProcessId();
DWORD ProcessThreadId = GetProcessThreadId(ProcessId);
return OpenThread(THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME, TRUE, ProcessThreadId);
}
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved) {
switch (dwReason) {
case DLL_PROCESS_ATTACH:
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)Initialize3Context, 0, 0, 0);
break;
}
return TRUE;
}
|
this is the CContextHook.h
Code: |
#include <Windows.h>
#include <Psapi.h>
#include <Tlhelp32.h>
#pragma comment( lib, "Psapi" )
#ifndef _CCONTEXTHOOK_H_
#define _CCONTEXTHOOK_H_
typedef struct {
unsigned long Hook1;
unsigned long Hook2;
unsigned long Hook3;
unsigned long Hook4;
} Context_t;
typedef void(__cdecl* Handler_t)(Context_t* C, EXCEPTION_POINTERS* E);
class CContextHook
{
public:
bool InitiateContext(Handler_t ContextHandler, Context_t* C);
bool ClearContext(void);
Context_t* GetContextInfo(void);
Handler_t GetHandlerInfo(void);
private:
bool IsReady(unsigned long* H);
DWORD GetProcessThreadId(unsigned long ProcessId);
HANDLE GetMainThread(void);
private:
Context_t m_Context;
Handler_t m_Handler;
PVOID m_pHandler;
};
extern CContextHook GContextHook;
#endif
|
I've seen that in some applications this doesn't crash, meanwhile in others it crashes when I change the db7 to some other value other than 0
P.s.: basically the only changes I've made are that I've converted this to 64 bit from 32 bit , instead of EIP register I've put RIP in this line :
Code: |
switch (E->ContextRecord->Rip)
|
|
|
Back to top |
|
 |
Dark Byte Site Admin
Reputation: 467
Joined: 09 May 2003 Posts: 25704 Location: The netherlands
|
Posted: Tue Aug 06, 2019 4:15 pm Post subject: |
|
|
first of change to AddVectoredExceptionHandler(1, ExceptionHandler) as it just needs a non 0 value
but not really sure where it goes wrong. Try more messageboxes is my idea (don't do outputdebugstring as that will infinite loop you)
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
 |
Viloresi Expert Cheater
Reputation: 0
Joined: 02 Feb 2017 Posts: 149
|
Posted: Tue Aug 06, 2019 4:36 pm Post subject: |
|
|
Dark Byte wrote: | first of change to AddVectoredExceptionHandler(1, ExceptionHandler) as it just needs a non 0 value
but not really sure where it goes wrong. Try more messageboxes is my idea (don't do outputdebugstring as that will infinite loop you) |
ok I've changed that to 1 but still the breakpoint doesn't get hit, so:
I've compiled an application which is the standard one if you do in visual studio New>Project>Windows Desktop Application , to test this VEH hook I've chosen the address of ntdll.KiUserCallbackDispatcher I've chosen this function to test because it's the first one that gets called when i move the mouse over the window of the application (I've found it by using the debugger of cheat engine by pressing Debug and break a random thread).
Also mind that I've made sure that the debugger of cheatengine is unattached since I know that could be a problem.
Anyway darkbyte if you don't have any other solution at the moment, could it be that I've compiled this code in 64bit? (because I guess this was made originally for 32 bit) maybe that :
switch (E->ContextRecord->Rip) // could be the problem?
Just wondering..ty tho!
|
|
Back to top |
|
 |
Dark Byte Site Admin
Reputation: 467
Joined: 09 May 2003 Posts: 25704 Location: The netherlands
|
Posted: Tue Aug 06, 2019 4:54 pm Post subject: |
|
|
KiUserCallbackDispatcher might not be the best function to test with, as it might also be responsible for calling the exception handler (it is a usermode callback after all)
(Try PeekMessageW or something)
What kind of crash are you experiencing? Freeze?
Because I think I see what might be wrong.
Because you never change RIP, and do not set the RF flag in the eflags register, when you continue execution, the breakpoint hits again.
Try setting bit 16 (the Resume Flag (RF)) of E->ContextRecord->EFlags to 1
Code: |
E->ContextRecord->EFlags|=(1<<16)
|
(Note that this won't work in windows XP, but no one uses that anymore anyhow)
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
 |
Viloresi Expert Cheater
Reputation: 0
Joined: 02 Feb 2017 Posts: 149
|
Posted: Tue Aug 06, 2019 5:30 pm Post subject: |
|
|
Dark Byte wrote: | KiUserCallbackDispatcher might not be the best function to test with, as it might also be responsible for calling the exception handler (it is a usermode callback after all)
(Try PeekMessageW or something)
What kind of crash are you experiencing? Freeze?
Because I think I see what might be wrong.
Because you never change RIP, and do not set the RF flag in the eflags register, when you continue execution, the breakpoint hits again.
Try setting bit 16 (the Resume Flag (RF)) of E->ContextRecord->EFlags to 1
Code: |
E->ContextRecord->EFlags|=(1<<16)
|
(Note that this won't work in windows XP, but no one uses that anymore anyhow) |
so inside the "ContextHandler" function I've added this line at the beginning:
Code: |
E->ContextRecord->EFlags |= (1 << 16);
|
but still doesn't work, because the ContextHandler function never gets called (atleast the messagebox I've put in it never appears).
so I've tried to look onto PeekMessageW but it never gets called , so I've decided to hook MessageBoxW (I've checked it shouldn't interfere with MessageBoxA I'm using in my dll anyway)
but anyway basically the problem is with my dummy application, only the first messagebox appears. (sorry that I didn't say this before)
messagebox => MessageBoxA(0, "", "HOOKED SUCCESS", 0);
no other messagebox are shown so that's why i guess ContextHandler never gets called.
(P.s. : the problem of crashes or freezing were happening with the game I was trying to cheat)
thank you btw
|
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|