Thread: API Hooking

Results 1 to 6 of 6
  1. #1
    R3DDOT's Avatar
    Join Date
    Dec 2013
    Gender
    male
    Location
    C://Windows/system32
    Posts
    347
    Reputation
    38
    Thanks
    2,366
    My Mood
    Cheerful

    API Hooking

    I built a class for hooking API's, but it's not working as excepted.
    If you wanna look at it, here's the code (APIHook::HookFunction isn't working properly when called):


     

    Code:
    	template <class T> static bool MemoryTools::WriteMemory(void* pAddress, T tValue){
    
    		if (pAddress && IsReadableMemory(pAddress)){
    			DWORD dwOldProtect = 0;
    
    			if (VirtualProtect(pAddress, sizeof(T), PAGE_READWRITE, &dwOldProtect))
    			{
    				*(T*)pAddress = tValue;
    
    				if (dwOldProtect != PAGE_READWRITE)
    					VirtualProtect(pAddress, sizeof(T), dwOldProtect, &dwOldProtect);
    
    				return true;
    			}
    		}
    
    		return false;
    	}
    
    //struct for handling API hooks
    struct APIHookInfo{
    		unsigned long id;
    		PVOID pTarget;					//api to be hooked;
    		PVOID pTrampoline;				//trampoline for our API;
    		PVOID pDetour;					//detour function;
    		unsigned long dwBackupSize;		//size of overritten data;
    		BYTE  IPs[0x10];				//overritten data;
    
    		APIHookInfo(){
    			static unsigned long nextid = 0;
    
    			id = ++nextid;
    			pTarget = pTrampoline = pDetour = nullptr;
    			dwBackupSize = NULL;
    			memset(IPs, 0, 0x10);
    		}
    
    		bool operator == (APIHookInfo i){
    			return (this->id == i.id);
    		}
    	};
    #define MakePtr(ptr1, ptr2, type) (type)((DWORD_PTR)ptr1 + (DWORD_PTR)ptr2)
    #define MakeDelta(ptr1, ptr2, type) (type)((DWORD_PTR)ptr1 - (DWORD_PTR)ptr2)
    
    
    unsigned long APIHook::GetInstructionSize(PVOID lpInstruction){ //this function uses hde32 / hde64
    	if (lpInstruction && MemoryTools::IsReadableMemory(lpInstruction)){
    		hde_struct e = hde_struct();
    		return hde_disasm(lpInstruction, &e);
    	}
    	return 0;
    }
    
    PVOID APIHook::HookFunction(APIHook::APIHookInfo i){
    	PauseThreads();
    
    	DWORD dwOldProtect = 0;															//Used for virtual protection.
    
    	if (i.dwBackupSize == NULL){
    		while (i.dwBackupSize < 5){
    			i.dwBackupSize += GetInstructionSize(MakePtr(i.pTarget, i.dwBackupSize, PVOID));
    		}
    	}
    
    
    	i.pTrampoline = new BYTE[i.dwBackupSize + 6]; //backup + jmp size + retn
    
    
    	VirtualProtect(i.pTarget, i.dwBackupSize, PAGE_READWRITE, &dwOldProtect);
    	
    	memcpy(i.pTrampoline, i.pTarget,
    		i.dwBackupSize);
    
    	memcpy(i.IPs, i.pTarget,
    		i.dwBackupSize);
    
    	memset(i.pTarget, 0x90, i.dwBackupSize); //memset function
    
    	MemoryTools::WriteMemory<BYTE>(i.pTarget, 0xE9); //0xE9 (opcode for relative jmp)
    	MemoryTools::WriteMemory<DWORD>(MakePtr(i.pTarget, 1, PVOID), (unsigned long)i.pDetour - (unsigned long)i.pTarget - 5); //Sets the offset
    
    	VirtualProtect(i.pTarget, i.dwBackupSize, dwOldProtect, &dwOldProtect);
    
    	MemoryTools::WriteMemory<BYTE>(MakePtr(i.pTrampoline, i.dwBackupSize, PVOID), 0xE9);
    	MemoryTools::WriteMemory<DWORD>(MakePtr(i.pTrampoline, i.dwBackupSize + 1, PVOID), 
    (unsigned long)i.pTarget - (unsigned long)i.pTrampoline - 5);
    
    	MemoryTools::WriteMemory<BYTE>(MakePtr(i.pTrampoline, i.dwBackupSize + 5, PVOID), 0xC3);
    
    	FlushInstructionCache(GetCurrentProcess(), 0, 0);
    
    	hookList.push_back(i); //adds this hook to the "hook" list
    
    	ResumeThreads();
    	return i.pTrampoline;
    
    }
    PVOID APIHook::UnhookFunction(APIHook::APIHookInfo i){
    	PauseThreads();
    	DWORD dwOldProtect = 0;															//Used for virtual protection.
    
    	if (i.dwBackupSize == NULL){
    		while (i.dwBackupSize < 5){
    			i.dwBackupSize += GetInstructionSize(MakePtr(i.pTarget, i.dwBackupSize, PVOID));
    		}
    	}
    
    	VirtualProtect(i.pTarget, i.dwBackupSize, PAGE_READWRITE, &dwOldProtect);
    
    	memcpy(i.pTarget, i.IPs, i.dwBackupSize);
    
    	VirtualProtect(i.pTarget, i.dwBackupSize, dwOldProtect, &dwOldProtect);
    
    	delete i.pTrampoline;
    
    	FlushInstructionCache(GetCurrentProcess(), 0, 0);
    	ResumeThreads();
    
    	for (std::vector<APIHookInfo>::iterator a = hookList.begin(); a < hookList.end(); a++){
    		if (*a == i){
    			hookList.erase(a);
    			break;
    		}
    	}
    
    
    	return i.pTarget;
    }
    
    PVOID APIHook::HookFunction(PVOID lpFunction, PVOID lpDetourFunction){
    	APIHookInfo i = APIHookInfo();
    	i.pTarget = lpFunction;
    	i.pDetour = lpDetourFunction;
    	return HookFunction(i);
    }
    PVOID APIHook::UnhookFunction(PVOID lpFunction){
    	for (auto &i : hookList){
    		if (i.pTarget == lpFunction) return UnhookFunction(i);
    	}
    
    	return nullptr;
    }

    Last edited by R3DDOT; 08-19-2015 at 07:33 AM.

  2. The Following User Says Thank You to R3DDOT For This Useful Post:

    [MPGH]Mayion (08-19-2015)

  3. #2
    ♪~ ᕕ(ᐛ)ᕗ's Avatar
    Join Date
    Jun 2010
    Gender
    male
    Location
    Uterus
    Posts
    9,119
    Reputation
    1096
    Thanks
    1,970
    My Mood
    Doh
    I am pretty much asleep but your issue is mostly because of miscalucaltions in the addies (at least that's where I think most people might have lapsuses). Refer to this article in order to better understand how "manual" hooking should be done:
    https://www.codeprojec*****m/Articles/...ith-MS-Detours

    Pretty much you calculate the distance from your target function to the detour function minus 5. Additionally you simply build up a jump instruction which jumps from that point to your detour function. Needless to say this might totally replace the original function. So in order to truly hook the function every time that you install the hook after the function is called you gotta unhook it and call the original function again. This can be a pain in the butt.

    In addition (as the article explains) why don't you use detours? They're easy and pretty efficient. (A presumable answer would be "I love making my own algorithms", at least that's what I would say )
    Last edited by ♪~ ᕕ(ᐛ)ᕗ; 08-18-2015 at 03:58 PM.

  4. #3
    R3DDOT's Avatar
    Join Date
    Dec 2013
    Gender
    male
    Location
    C://Windows/system32
    Posts
    347
    Reputation
    38
    Thanks
    2,366
    My Mood
    Cheerful
    Quote Originally Posted by ლ(ಠ_ಠლ) View Post
    I am pretty much asleep but your issue is mostly because of miscalucaltions in the addies (at least that's where I think most people might have lapsuses). Refer to this article in order to better understand how "manual" hooking should be done:
    https://www.codeprojec*****m/Articles/...ith-MS-Detours

    Pretty much you calculate the distance from your target function to the detour function minus 5. Additionally you simply build up a jump instruction which jumps from that point to your detour function. Needless to say this might totally replace the original function. So in order to truly hook the function every time that you install the hook after the function is called you gotta unhook it and call the original function again. This can be a pain in the butt.

    In addition (as the article explains) why don't you use detours? They're easy and pretty efficient. (A presumable answer would be "I love making my own algorithms", at least that's what I would say )
    I love making my own algorithms.

    And I'm using this on a program that checks the calls to those functions, meaning I can either spoof the return address, or make my own algorithms. And the latter seems to be faster (at least that's what I initially thought).

  5. #4
    ♪~ ᕕ(ᐛ)ᕗ's Avatar
    Join Date
    Jun 2010
    Gender
    male
    Location
    Uterus
    Posts
    9,119
    Reputation
    1096
    Thanks
    1,970
    My Mood
    Doh
    Quote Originally Posted by R3DDOT View Post


    I love making my own algorithms.

    And I'm using this on a program that checks the calls to those functions, meaning I can either spoof the return address, or make my own algorithms. And the latter seems to be faster (at least that's what I initially thought).
    An answer would be save the backed up funcion somewhere in the memory and after calling the hooked jump back to the original.
    Another great help would be to specify what's going wrong

  6. #5
    R3DDOT's Avatar
    Join Date
    Dec 2013
    Gender
    male
    Location
    C://Windows/system32
    Posts
    347
    Reputation
    38
    Thanks
    2,366
    My Mood
    Cheerful
    Quote Originally Posted by ლ(ಠ_ಠლ) View Post


    An answer would be save the backed up funcion somewhere in the memory and after calling the hooked jump back to the original.
    Another great help would be to specify what's going wrong
    My bad, I thought I had commented the function.

    API Hooking functions like this:

    When hooking a API, we need 3 functions. We need the target function (API we want to hook), our detour function (our hook) and a "trampoline" (executes the original function by simulating the overritten opcodes then jumping back to the original function, skipping the hook).

    This causes an exception of std::bad_alloc, but I don't see where I might be allocating too much memory.


    - - - Updated - - -

    Fixed it. I modified the post above with the fixed version, feel free to use. @Camel

  7. #6
    Mayion's Avatar
    Join Date
    Oct 2012
    Gender
    male
    Location
    Bed
    Posts
    13,504
    Reputation
    4018
    Thanks
    8,372
    My Mood
    Twisted
    Great to know you fixed your problem by yourself, good job.
    I do not use any type of messenger outside of MPGH.
    Inactive but you can reach me through VM/PM.










     

    Donator - 30 August 2013
    Battlefield Minion - 26 October 2013

    Blackshot Minion - 14 January 2014/16 September 2014
    Minecraft Minion - 7 February 2014/16 September 2014
    WarRock Minion - 23 February 2014
    League of Legends Minion - 21 March 2014

    Minion+ - 15 May 2014
    Other Semi-Popular First Person Shooter Minion - 8 August 2014
    CrossFire Minion - 23 October 2014
    Programming Section Minion - 13 November 2014
    Marketplace Minion - 7 December 2014

    Official Middleman - 7 December 2014 - 27 June 2015
    Moderator - 29 December 2014
    Project Blackout Minion - 10 January 2015
    News Force Interviewer - January 2015
    Steam Games Minion - 21 March 2015
    Dragon Nest Minion - 31 March 2015
    Publicist - April 2015 - 21 September 2015
    Global Moderator - 25 August 2015
    Super User - 13 August 2016



Similar Threads

  1. How to PostMessage API or directinput hook?
    By easyGame in forum Dragon Nest Discussions
    Replies: 0
    Last Post: 03-21-2012, 01:11 AM
  2. [Tutorial] API’s that GameGuard hook
    By <<<[Curse One]>>> in forum WarRock Hack Source Code
    Replies: 0
    Last Post: 02-29-2012, 11:41 PM
  3. [Request] Source Code Speed Hack Api Hook
    By fadhillah in forum C++/C Programming
    Replies: 2
    Last Post: 07-19-2011, 08:08 AM
  4. [HELP] How to inject to hook api using VB
    By BLUE01299 in forum Visual Basic Programming
    Replies: 2
    Last Post: 11-07-2010, 01:29 AM
  5. [Delphi] Api Hooking problem
    By P4uLo in forum Programming Tutorial Requests
    Replies: 0
    Last Post: 05-31-2010, 11:44 PM