Download YUNOHook

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

c5

Kim Kong Trasher
Dank Tier VIP
Dank Tier Donator
Jul 19, 2012
1,187
12,638
76
My small all-in-one general hooking library. Some subclasses/methods were removed for this release, if you want you can implement them on your own.

It features: Code breakpoints, Page breakpoints, Hardware breakpoints, Code detouring/hooking, VMT hooking, IAT hooking. Most stuff is x86/x64 compatible.

Credits/Thanks: @c5, Kamshak, Spock, Kokole

You can keep all of your hooks managed by YUNOHook, or just access them directly. YUNOHook adds the comfort of removed specific or all hooks quickly. Eg. if you need to unload your module, you can quickly unattach all the hooks and the program won't likely (lol) crash.

C++:
#pragma once

// This file is part of YUNOHook
//
// Author: c5
// Thanks/Credits:  Kamshak, Spock, Kokole
//
// 2015



#include <Windows.h>
#include <utility>
#include <vector>
#include <TlHelp32.h>

// Each class handles 1 hook (except BP classes due to static handlers. Also bare in mind they are NOT THREAD SAFE and might cause some issues)
// YUNOHook handles all of your hooks
// I know it employs some bad coding practises eg. all classes being in one header and source file but its easily portable :)
// I also havent tested its functionality extensively as a whole. You might run into some issues, consider it your anti copypasta

namespace YUNO
{
	class YUNOHook;

	class CodeBP  // stripped for release
	{
	public:
		void Detach();
	};

	class PageBP
	{
	public:
		typedef void(*PageBP_Callback)(PCONTEXT pContext);
	private:
		static std::vector<std::pair<PageBP_Callback, void*>>m_Callbacks;
		static void* m_pLastUnhooked;
		static bool m_bAttachedHandler;
		static LONG CALLBACK ExceptionFilter(PEXCEPTION_POINTERS pException);
		static void* m_pExcHandler;

		void* m_pAddress; 
		DWORD m_dwOldProtection;	
	public:
		PageBP() { m_pAddress = 0; }

		static void AttachHandler();
		static void DetachHandler();

		bool IsHandlerAttached() { return m_bAttachedHandler; }
		void* GetHandler() { return m_pExcHandler; }
		void Attach(BYTE* pAddress, PageBP_Callback pHook);
		void Detach();
	};

	class HardwareBP
	{
	public:
		enum EHWBP_TYPE	{
			HWBP_TYPE_EXECUTE,
			HWBP_TYPE_WRITE,
			HWBP_TYPE_READWRITE
		};
		enum EHWBP_SIZE	{
			HWBP_SIZE_1,
			HWBP_SIZE_2,
			HWBP_SIZE_4,
			HWBP_SIZE_8
		};
		typedef void(*HWBP_Callback)(PCONTEXT pContext);
	private:
		static std::vector<std::pair<HWBP_Callback, void*>>m_Callbacks;
		static bool m_bAttachedHandler;
		static LONG CALLBACK ExceptionFilter(PEXCEPTION_POINTERS pException);
		static void* m_pExcHandler;

		bool AddHWBP(HANDLE hThread, EHWBP_TYPE type, EHWBP_SIZE size, void* ptr, PCONTEXT optionalContext);
		bool RemoveHWBP(HANDLE hThread, void* ptr, PCONTEXT optionalContext);

		std::vector<DWORD>m_ThreadsAttachedTo;
		void* m_pAddress;
	public:
		HardwareBP() { m_pAddress = 0; }

		static void AttachHandler();
		static void DetachHandler();

		bool IsHandlerAttached() { return m_bAttachedHandler; }
		void* GetHandler() { return m_pExcHandler; }

		bool Attach(DWORD dwThreadId, EHWBP_TYPE type, EHWBP_SIZE size, void* pAddress, PCONTEXT optionalContext, HWBP_Callback pHook);
		bool AttachAllThreads(EHWBP_TYPE type, EHWBP_SIZE size, void* pAddress, HWBP_Callback pHook);
		void Detach();
	};

	class CodeDetour  // stripped for release
	{
	public:
		void Detach();
	};

	class VMTHook
	{
	private:
		void* m_pOldVtable;
		void* m_pOriginalFunc;
		unsigned m_uFuncIndex;
		int m_iBitCount;

		bool m_bHooked;
	public:
		VMTHook() { m_bHooked = false; }

		// attach 32 bit vtable hook, returns old func pointer
		void* Attach32(PULONG ppVTable, PBYTE pHook, unsigned index, bool bFlushCache);
		// attach 64 bit vtable hook, returns old func pointer
		void* Attach64(PULONGLONG ppVTable, PBYTE pHook, unsigned index, bool bFlushCache);
		// detach the hook, restore old func pointer, do cleanup
		void Detach();
	};

	class IATHook
	{
	private:
		PIMAGE_DOS_HEADER m_pImage;
		PIMAGE_NT_HEADERS m_pNtHeaders;
		PIMAGE_IMPORT_DESCRIPTOR m_pImportDesc;
		PIMAGE_THUNK_DATA m_pThunk;
		PIMAGE_THUNK_DATA m_pOrigThunk;
		PIMAGE_IMPORT_BY_NAME m_pName;
		void* m_pOldPtr;
		void* m_pRegionBase;
		SIZE_T m_uRegionSize;

		bool m_bHooked;
	public:
		IATHook() { m_bHooked = false; }

		// attach hook, returns old func pointer
		void* Attach(HMODULE hModule, char* szModule, char* szProc, void *pHook);
		// detach the hook, restore old func pointer, do cleanup
		void Detach();
	};

	class YUNOHook
	{
	private:
		enum EReturnStatus {
			HOOK_FAILED = 0,
			HOOK_SUCCESS
		};

		std::vector<std::pair<CodeBP*, char*>>CodeBPHooks;
		std::vector<std::pair<PageBP*, char*>>PageBPHooks;
		std::vector<std::pair<HardwareBP*, char*>>HardwareBPHooks;
		std::vector<std::pair<CodeDetour*, char*>>CodeDetourHooks;
		std::vector<std::pair<VMTHook*, char*>>VMTHooks;
		std::vector<std::pair<IATHook*, char*>>IATHooks;

		char* CreateName(char* szHookName);
	public:
		YUNOHook();
		~YUNOHook();

		// szHookName is optional, used to track hooks by hook name, pass 0 if you dont want to track the hook
		// returns HOOK_FAILED if failed to hook
		// returns HOOK_SUCESS if successfully hooked

		EReturnStatus AddHWBP(char* szHookName, DWORD dwThreadId, HardwareBP::EHWBP_TYPE type, HardwareBP::EHWBP_SIZE size, void* pAddress, PCONTEXT optionalContext, HardwareBP::HWBP_Callback pHook);
		EReturnStatus AddHWBPAllThreads(char* szHookName, HardwareBP::EHWBP_TYPE type, HardwareBP::EHWBP_SIZE size, void* pAddress, HardwareBP::HWBP_Callback pHook);
		EReturnStatus AddPageBP(char* szHookName, BYTE* pAddress, PageBP::PageBP_Callback pHook);
		EReturnStatus AddIATHook(char* szHookName, HMODULE hModule, char* szModule, char* szProc, void* pHook);
		EReturnStatus AddVtableHook32(char* szHookName, PULONG ppVTable, PBYTE pHook, unsigned index, bool bFlushCache, PULONG pOriginalFunc /*for calling original func*/);
		EReturnStatus AddVtableHook64(char* szHookName, PULONGLONG ppVTable, PBYTE pHook, unsigned index, bool bFlushCache, PULONGLONG pOriginalFunc /*for calling original func*/);
		//

		// detach all hooks
		void DetachAll();
		// detach hook by hook name
		bool Detach(char* szName);
		// get hook by name
		template <typename hookType> hookType* GetHook(char* szName)
		{
			for (auto& i : CodeBPHooks)
			{
				if (!strcmp(szName, i.second))
					return (hookType*)i.first;
			}
			for (auto& i : PageBPHooks)
			{
				if (!strcmp(szName, i.second))
					return (hookType*)i.first;
			}
			for (auto& i : HardwareBPHooks)
			{
				if (!strcmp(szName, i.second))
					return (hookType*)i.first;
			}
			for (auto& i : CodeDetourHooks)
			{
				if (!strcmp(szName, i.second))
					return (hookType*)i.first;
			}
			for (auto& i : VMTHooks)
			{
				if (!strcmp(szName, i.second))
					return (hookType*)i.first;
			}
			for (auto& i : IATHooks)
			{
				if (!strcmp(szName, i.second))
					return (hookType*)i.first;
			}
			return 0;
		}
	};
}

Feel free to use it in your project. I'd respect you if you'd credit me and the people named above if you plan to release any stuff that uses this. Thanks :)
 

Attachments

Solaire

Respected Hacker
Dank Tier VIP
Dec 15, 2013
1,051
16,353
62
This is awesome, much appreciated for the release! Going to learn a LOT from this! :D
 

Syperus

RTFM
Meme Tier VIP
Dank Tier Donator
Oct 29, 2012
432
2,638
7
Thanks for this! I'm currently working on a couple hack projects atm. Gonna see if i can use this in one of them.
 

GAFO666

Hacker
Meme Tier VIP
Aug 19, 2012
520
3,188
23
actually useless.
actually usefull in many cases together with memcrawl basements..
but the removed part would have been there most exiting one to read through since manualy code detour takes a while, at least for me
 

c5

Kim Kong Trasher
Dank Tier VIP
Dank Tier Donator
Jul 19, 2012
1,187
12,638
76
actually usefull in many cases together with memcrawl basements..
but the removed part would have been there most exiting one to read through since manualy code detour takes a while, at least for me
I removed it because it had a lengthy disassembler in it from another source. Besides it had different polymorphic and sneaky functionality that I'd rather keep on my own for the time being :)

Building a code detour is nothing hard. Just find how many bytes you need to overwrite/skip/restore, allocate them to a buffer (assuming you want to hook with a trampoline) and make it jump back to where the code left off, then make the function jump to your code and when you return, call the trampoline.
 

masteraimer1

Newbie
Full Member
Nobleman
Aug 27, 2014
95
1,768
6
for all the guys who watched this thread cuz they search a vmt hook manager.
C++:
namespace VMTManager
{
	namespace Hooks
	{
		uint CountFuncs(void** vmt)
		{

			MEMORY_BASIC_INFORMATION mem;
			int i = -1;
			do { i++; VirtualQuery(vmt[i], &mem, sizeof(MEMORY_BASIC_INFORMATION)); } while (mem.Protect == PAGE_EXECUTE_READ || mem.Protect == PAGE_EXECUTE_READWRITE);
			return i;
		}

		uint CountFuncs(void* begin, void* end, void** vmt)
		{
			int i = -1;
			do i++; while (begin < vmt[i] && vmt[i] < end);
			return i;
		}
		int FindFunc(void** vmt, void* func, uint vfuncs)
		{
			if (!vfuncs) vfuncs = CountFuncs(vmt);
			for (uint i = 0; i < vfuncs; i++)
			{
				if (vmt[i] == func) return i;
			}
			return -1;
		}

		// VMTManager
		VMTManager::VMTManager(void* inst, size_t offset, uint vfuncs)
		{
			_vftable = make_ptr<void***>(inst, offset);
			_oldvmt = *_vftable;
			// Count vfuncs ourself if needed
			if (!vfuncs) vfuncs = CountFuncs(_oldvmt);
			_vcount = vfuncs;
			// Allocate room for the new vtable
			_array = (void**)malloc((vfuncs + 3)*sizeof(void*));
			// Initialize RTTI pointer (should there be one)
			_array[2] = _oldvmt[-1];
			// Copy over the other vfuncs
			for (uint i = 0; i < vfuncs; ++i) _array[i + 3] = _oldvmt[i];
			// Hook it
			*_vftable = _array + 3;
		}
		VMTManager::~VMTManager()
		{
			if (_vftable) Unhook();
			free(_array);
		}
	}
}
C++:
#include <cassert>
namespace VMTManager
{
	namespace Hooks
	{
		// Pasted here to make it a standalone lib
		typedef unsigned int uint;
		typedef int int_ptr;
		template< typename T > inline T make_ptr(void* ptr, int_ptr offset) { return reinterpret_cast<T>((size_t)ptr + offset); }
		inline void**& getvtable(void* inst, int_ptr offset = 0) { return *reinterpret_cast<void***>((size_t)inst + offset); }


		// Find the number of vfuncs in a vtable
		uint CountFuncs(void** pVMT);
		uint CountFuncs(void* begin, void* end, void** pVMT);

		// Find the index for a vfunc, result is negative if not found
		int FindFunc(void** pVMT, void* pFunc, uint vfuncs = 0);


		// ----------------------------------------------------------------
		// Class: VMTManager
		// ----------------------------------------------------------------
		// Hooks virtual functions by replacing the vtable pointer from an instance.
		//
		// Purpose:
		//  Manages the virtual table of an object.
		//
		class VMTManager
		{
			// Forbid copy constructing and assignment.
			VMTManager(const VMTManager&);
			VMTManager& operator= (const VMTManager&);

		public:
			VMTManager(void* inst, size_t offset = 0, uint vfuncs = 0);
			~VMTManager();

			// Hooks a function by index.
			inline void HookMethod(void* newfunc, size_t index)
			{
				assert(index < _vcount);
				_array[index + 3] = newfunc;
			}
			// Unhooks a function by index.
			inline void UnhookMethod(size_t index)
			{
				assert(index < _vcount);
				_array[index + 3] = _oldvmt[index];
			}

			// Manage the hooks.
			inline void Unhook() { *_vftable = _oldvmt; }
			inline void Rehook() { *_vftable = _array + 3; }
			inline bool Hooked() const { return *_vftable != _oldvmt; }
			inline void EraseHooks() { for (uint i = 0; i < _vcount; ++i) _array[i + 3] = _vftable[i]; }
			inline uint NumFuncs() const { return _vcount; }

			// If the instance is somehow destroyed before you get a chance to unhook it or destruct this hook object, call this.
			// It'll prevent the destructor from crashing.
			inline void Poof() { _vftable = 0; }

			// Get the original function.
			// Use a function prototype for the template argument to make it very easy to call this function.
			// Example syntax: hook.GetMethod<bool (__thiscall*)( void*, int )>( 12 )( inst, arg );
			template< typename Fn >
			inline Fn GetMethod(size_t index) const
			{
				assert(index < _vcount);
				return (Fn)_oldvmt[index];
			}

		protected:
			inline void _set_guard(size_t S) { _array[1] = (void*)S; }
			inline size_t _get_guard() const { return (size_t)_array[1]; }
			inline void _set_backptr(void* ptr) { _array[0] = ptr; }
			inline void* _get_backptr() const { return _array[0]; }

		private:
			void***	_vftable;
			void**	_oldvmt;
			void**	_array;
			uint	_vcount;
		};
	};
}
P.S i dont know why u just post the header thats why i say useless.
i could post my misc header from my csgo hack.
example: "void Teleport( ValveSDK::CInput::CUserCmd* pUserCmd );" and u still dont know how to do it.
 
Last edited:

GAFO666

Hacker
Meme Tier VIP
Aug 19, 2012
520
3,188
23
Building a code detour is nothing hard. Just find how many bytes you need to overwrite/skip/restore, allocate them to a buffer (assuming you want to hook with a trampoline) and make it jump back to where the code left off, then make the function jump to your code and when you return, call the trampoline.
ye, but you know if you have a certain function and you want to rewrite it or whatever .. you take the starting adress and num of bytes to go for that function .. or a jump yeh.
But in case of not using a jump .. there are so many cases how a function could end, so i dont get how to make that automatic if you know what i mean.
Like functions which are not inside of a vtable or rewrite structs.
Lets say there is a struct xy in a game z and it holds something like position etc etc and you want to add a new member to that existing struct instead of making your own, point with a member of your own onto the existing one and add in the new more ya know :b
 

Broihon

edgy 12 y/o
Escobar Tier VIP
Fleep Tier Donator
Dec 22, 2013
1,746
40,528
316
masteraimer1 You just went full Broihon. And this thread contains much more then lame-ass vmt hooks.
 
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