Use AMTL instead of the stdlib in DynamicHooks
This commit is contained in:
		
							parent
							
								
									8ab9c14e93
								
							
						
					
					
						commit
						c70d3b9ee0
					
				| @ -53,6 +53,12 @@ CHook::CHook(void* pFunc, ICallingConvention* pConvention) | ||||
| 	m_pRegisters = new CRegisters(pConvention->GetRegisters()); | ||||
| 	m_pCallingConvention = pConvention; | ||||
| 
 | ||||
| 	if (!m_hookHandler.init()) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (!m_RetAddr.init()) | ||||
| 		return; | ||||
| 
 | ||||
| 	unsigned char* pTarget = (unsigned char *) pFunc; | ||||
| 
 | ||||
| 	// Determine the number of bytes we need to copy
 | ||||
| @ -103,37 +109,56 @@ void CHook::AddCallback(HookType_t eHookType, HookHandlerFn* pCallback) | ||||
| 	if (!pCallback) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (!IsCallbackRegistered(eHookType, pCallback)) | ||||
| 		m_hookHandler[eHookType].push_back(pCallback); | ||||
| 	HookTypeMap::Insert i = m_hookHandler.findForAdd(eHookType); | ||||
| 	if (!i.found()) { | ||||
| 		HookHandlerSet set; | ||||
| 		set.init(); | ||||
| 		m_hookHandler.add(i, eHookType, ke::Move(set)); | ||||
| 	} | ||||
| 
 | ||||
| 	i->value.add(pCallback); | ||||
| } | ||||
| 
 | ||||
| void CHook::RemoveCallback(HookType_t eHookType, HookHandlerFn* pCallback) | ||||
| { | ||||
| 	if (IsCallbackRegistered(eHookType, pCallback)) | ||||
| 		m_hookHandler[eHookType].remove(pCallback); | ||||
| 	HookTypeMap::Result r = m_hookHandler.find(eHookType); | ||||
| 	if (!r.found()) | ||||
| 		return; | ||||
| 
 | ||||
| 	r->value.removeIfExists(pCallback); | ||||
| } | ||||
| 
 | ||||
| bool CHook::IsCallbackRegistered(HookType_t eHookType, HookHandlerFn* pCallback) | ||||
| { | ||||
| 	std::list<HookHandlerFn *> callbacks = m_hookHandler[eHookType]; | ||||
| 	for(std::list<HookHandlerFn *>::iterator it=callbacks.begin(); it != callbacks.end(); it++) | ||||
| 	{ | ||||
| 		if (*it == pCallback) | ||||
| 			return true; | ||||
| 	} | ||||
| 	HookTypeMap::Result r = m_hookHandler.find(eHookType); | ||||
| 	if (!r.found()) | ||||
| 		return false; | ||||
| 
 | ||||
| 	return r->value.has(pCallback); | ||||
| } | ||||
| 
 | ||||
| bool CHook::AreCallbacksRegistered() | ||||
| { | ||||
| 	return !m_hookHandler[HOOKTYPE_PRE].empty() || !m_hookHandler[HOOKTYPE_POST].empty(); | ||||
| 	HookTypeMap::Result r = m_hookHandler.find(HOOKTYPE_PRE); | ||||
| 	if (r.found() && r->value.elements() > 0) | ||||
| 		return true; | ||||
| 
 | ||||
| 	r = m_hookHandler.find(HOOKTYPE_POST); | ||||
| 	if (r.found() && r->value.elements() > 0) | ||||
| 		return true; | ||||
| 
 | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| bool CHook::HookHandler(HookType_t eHookType) | ||||
| { | ||||
| 	bool bOverride = false; | ||||
| 	std::list<HookHandlerFn *> callbacks = this->m_hookHandler[eHookType]; | ||||
| 	for(std::list<HookHandlerFn *>::iterator it=callbacks.begin(); it != callbacks.end(); it++) | ||||
| 	HookTypeMap::Result r = m_hookHandler.find(eHookType); | ||||
| 	if (!r.found()) | ||||
| 		return bOverride; | ||||
| 
 | ||||
| 	HookHandlerSet &callbacks = r->value; | ||||
| 	for(HookHandlerSet::iterator it=callbacks.iter(); !it.empty(); it.next()) | ||||
| 	{ | ||||
| 		bool result = ((HookHandlerFn) *it)(eHookType, this); | ||||
| 		if (result) | ||||
| @ -144,15 +169,17 @@ bool CHook::HookHandler(HookType_t eHookType) | ||||
| 
 | ||||
| void* __cdecl CHook::GetReturnAddress(void* pESP) | ||||
| { | ||||
| 	if (m_RetAddr.count(pESP) == 0) | ||||
| 	ReturnAddressMap::Result r = m_RetAddr.find(pESP); | ||||
| 	if (!r.found()) | ||||
| 		puts("ESP not present."); | ||||
| 
 | ||||
| 	return m_RetAddr[pESP]; | ||||
| 	return r->value; | ||||
| } | ||||
| 
 | ||||
| void __cdecl CHook::SetReturnAddress(void* pRetAddr, void* pESP) | ||||
| { | ||||
| 	m_RetAddr[pESP] = pRetAddr; | ||||
| 	ReturnAddressMap::Insert i = m_RetAddr.findForAdd(pESP); | ||||
| 	m_RetAddr.add(i, pESP, pRetAddr); | ||||
| } | ||||
| 
 | ||||
| void* CHook::CreateBridge() | ||||
|  | ||||
| @ -34,11 +34,10 @@ | ||||
| // ============================================================================
 | ||||
| // >> INCLUDES
 | ||||
| // ============================================================================
 | ||||
| #include <list> | ||||
| #include <map> | ||||
| 
 | ||||
| #include "registers.h" | ||||
| #include "convention.h" | ||||
| #include <am-hashmap.h> | ||||
| #include <am-hashset.h> | ||||
| 
 | ||||
| // ============================================================================
 | ||||
| // >> HookType_t
 | ||||
| @ -63,6 +62,20 @@ typedef bool (*HookHandlerFn)(HookType_t, CHook*); | ||||
| #define __cdecl | ||||
| #endif | ||||
| 
 | ||||
| struct IntegerPolicy | ||||
| { | ||||
| 	static inline uint32_t hash(size_t i) { | ||||
| 		return ke::HashInteger<sizeof(size_t)>(i); | ||||
| 	} | ||||
| 	static inline bool matches(size_t i1, size_t i2) { | ||||
| 		return i1 == i2; | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| typedef ke::HashSet<HookHandlerFn*, ke::PointerPolicy<HookHandlerFn>> HookHandlerSet; | ||||
| typedef ke::HashMap<HookType_t, HookHandlerSet, IntegerPolicy> HookTypeMap; | ||||
| typedef ke::HashMap<void*, void*, ke::PointerPolicy<void>> ReturnAddressMap; | ||||
| 
 | ||||
| namespace sp | ||||
| { | ||||
| 	class MacroAssembler; | ||||
| @ -164,12 +177,12 @@ private: | ||||
| 	void __cdecl SetReturnAddress(void* pRetAddr, void* pESP); | ||||
| 
 | ||||
| public: | ||||
| 	std::map<HookType_t, std::list<HookHandlerFn*> > m_hookHandler; | ||||
| 
 | ||||
| 	HookTypeMap m_hookHandler; | ||||
| 
 | ||||
| 	// Address of the original function
 | ||||
| 	void* m_pFunc; | ||||
| 
 | ||||
| 
 | ||||
| 	ICallingConvention* m_pCallingConvention; | ||||
| 
 | ||||
| 	// Address of the bridge
 | ||||
| @ -184,7 +197,7 @@ public: | ||||
| 	// New return address
 | ||||
| 	void* m_pNewRetAddr; | ||||
| 
 | ||||
| 	std::map<void*, void*> m_RetAddr; | ||||
| 	ReturnAddressMap m_RetAddr; | ||||
| }; | ||||
| 
 | ||||
| #endif // _HOOK_H
 | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user