Beispiel #1
0
void *HookAPI(LPVOID lpFunc,LPVOID lpHandler)
{
    void *lpRet=NULL;
    if (GetHookInfo(lpFunc))
        UnhookAPI(lpFunc);

    if (NumOfHooks < MAX_HOOKS-1)
    {
        void *lpBackup=MemAlloc(JUMP_SIZE*4);
        ULONG_PTR *lpTable=0;
#ifdef _AMD64_
        lpTable=(ULONG_PTR *)MemAlloc(sizeof(ULONG_PTR)*MAX_JUMPS);
        LPVOID lpRelay=malloc_SomewhereAroundHere(lpFunc,sizeof(JMP_REL));
        if (!lpRelay)
        {
            MemFree(lpBackup);
            return lpRet;
        }
#endif
        SIZE_T dwBackupCodeSize=0;
        void *lpBridge=CreateBridge(lpFunc,lpBackup,&dwBackupCodeSize,&lpTable[1]);
        if (lpBridge)
        {
            EnterCriticalSection(&csHookApi);

                hooks[NumOfHooks].lpRealFunc=lpFunc;
                hooks[NumOfHooks].lpBridge=lpBridge;
                hooks[NumOfHooks].lpHandler=lpHandler;
                hooks[NumOfHooks].lpBackup=lpBackup;
                hooks[NumOfHooks].dwCodeSize=dwBackupCodeSize;
#ifdef _AMD64_
                hooks[NumOfHooks].lpRelay=lpRelay;
                hooks[NumOfHooks].lpTable=lpTable;
                WriteAbsoluteJump(lpRelay,lpHandler,lpTable);
                WriteRelativeJump(lpFunc,lpRelay);
#else
                WriteRelativeJump(lpFunc,lpHandler);
#endif
                NumOfHooks++;
                lpRet=lpBridge;

            LeaveCriticalSection(&csHookApi);
        }
    }
    return lpRet;
}
Beispiel #2
0
	MH_STATUS CreateHook(void* pTarget, void* const pDetour, void** ppOriginal)
	{
		CriticalSection::ScopedLock lock(*gCS);

		if (!gIsInitialized)
		{
			return MH_ERROR_NOT_INITIALIZED;
		}

		HOOK_ENTRY *pHook = FindHook(pTarget);
		if (pHook != NULL)
		{
			return MH_ERROR_ALREADY_CREATED;
		}

		if (!IsExecutableAddress(pTarget) || !IsExecutableAddress(pDetour))
		{
			return MH_ERROR_NOT_EXECUTABLE;
		}

		{
			bool committed = false;
			RollbackIfNotCommitted scopedRollback(&committed);

			// トランポリン関数を作成する
			CREATE_TREMPOLINE_T ct = { 0 };
			ct.pTarget = pTarget;
			if (!CreateTrampolineFunction(ct))
			{
				return MH_ERROR_UNSUPPORTED_FUNCTION;
			}

			void* pJmpPtr = pTarget;
			if (ct.patchAbove)
			{
				pJmpPtr = reinterpret_cast<char*>(pJmpPtr) - sizeof(JMP_REL);
			}

			void* pTrampoline = AllocateCodeBuffer(pJmpPtr, ct.trampoline.size());
			if (pTrampoline == NULL)
			{
				return MH_ERROR_MEMORY_ALLOC;
			}
#if defined _M_X64
			void* pTable = AllocateDataBuffer(pTrampoline, (ct.table.size() + 1) * sizeof(uintptr_t));
			if (pTable == NULL)
			{
				return MH_ERROR_MEMORY_ALLOC;
			}
#endif

			ct.pTrampoline = pTrampoline;
#if defined _M_X64
			ct.pTable = pTable;
#endif
			if (!ResolveTemporaryAddresses(ct))
			{
				return MH_ERROR_UNSUPPORTED_FUNCTION;
			}

			memcpy(pTrampoline, &ct.trampoline[ 0 ], ct.trampoline.size());
#if defined _M_X64
			if (ct.table.size() != 0)
			{
				memcpy(pTable, &ct.table[ 0 ], ct.table.size() * sizeof(uintptr_t));
			}
#endif

			// ターゲット関数のバックアップをとる
			size_t backupSize = sizeof(JMP_REL);
			if (ct.patchAbove)
			{
				backupSize += sizeof(JMP_REL_SHORT);
			}

			void* pBackup = AllocateDataBuffer(NULL, backupSize);
			if (pBackup == NULL)
			{
				return MH_ERROR_MEMORY_ALLOC;
			}

			memcpy(pBackup, pJmpPtr, backupSize);

			// 中継関数を作成する
#if defined _M_X64
			void* pRelay = AllocateCodeBuffer(pJmpPtr, sizeof(JMP_ABS));
			if (pRelay == NULL)
			{
				return MH_ERROR_MEMORY_ALLOC;
			}

			WriteAbsoluteJump(pRelay, pDetour, reinterpret_cast<uintptr_t*>(pTable) + ct.table.size());
#endif
			CommitBuffer();
			committed = true;

			// フック情報の登録
			HOOK_ENTRY hook = { 0 };
			hook.pTarget = pTarget;
			hook.pDetour = pDetour;
#if defined _M_X64
			hook.pTable  = pTable;
			hook.pRelay  = pRelay;
#endif
			hook.pTrampoline = pTrampoline;
			hook.pBackup = pBackup;
			hook.patchAbove = ct.patchAbove;
			hook.isEnabled = false;
			hook.queueEnable = false;
			hook.oldIPs = ct.oldIPs;
			hook.newIPs = ct.newIPs;

			std::vector<HOOK_ENTRY>::iterator i	= std::lower_bound(gHooks.begin(), gHooks.end(), hook);
			i = gHooks.insert(i, hook);
			pHook = &(*i);
		}

		// OUT引数の処理
		*ppOriginal = pHook->pTrampoline;

		return MH_OK;
	}