Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


How to set a VEH hook with an Hardware breakpoint C++ ?

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
Viloresi
Expert Cheater
Reputation: 0

Joined: 02 Feb 2017
Posts: 149

PostPosted: Tue Aug 06, 2019 4:08 pm    Post subject: How to set a VEH hook with an Hardware breakpoint C++ ? Reply with quote

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
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 457

Joined: 09 May 2003
Posts: 25262
Location: The netherlands

PostPosted: Tue Aug 06, 2019 4:15 pm    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
Viloresi
Expert Cheater
Reputation: 0

Joined: 02 Feb 2017
Posts: 149

PostPosted: Tue Aug 06, 2019 4:36 pm    Post subject: Reply with quote

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
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 457

Joined: 09 May 2003
Posts: 25262
Location: The netherlands

PostPosted: Tue Aug 06, 2019 4:54 pm    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
Viloresi
Expert Cheater
Reputation: 0

Joined: 02 Feb 2017
Posts: 149

PostPosted: Tue Aug 06, 2019 5:30 pm    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites