static VOID After1WithContext  (ADDRINT ip, 
                                ADDRINT repInsAddr,
                                CONTEXT * ctxt,
                                CONTEXT *constCtxt,
                                ADDRINT *constRefToIp
                                )
{
    ADDRINT expectedIpAfter;
    numCallsToAfter1WithContext++;
    printf ("***After1WithContext#    %d repInsAddr %p ip %p\n",//*constRefToIp %p\n", 
           numCallsToAfter1WithContext, (char *)repInsAddr, (char *)ip
           //,(char *)constRefToIp, 
           //(char *)(*constRefToIp)
           );
    if (numCallsToAfter1WithContext == 2)
    { // see "Test different string comparison" in rep_ip_at_ipoint_after_app.c
        expectedIpAfter = repInsAddr+GetInstructionLength(repInsAddr);
    }
    else
    {
        expectedIpAfter = repInsAddr;
    }
    
    if (ip != *constRefToIp)
    {
        printf ("Unexpcted diff between ip and *constRefToIp\n");
        exit (1);
    }


    if (PIN_GetContextReg( ctxt, REG_INST_PTR )!=expectedIpAfter)
    {
        printf ("  After1WithContext Unexpected IP in ctxt %p\n",
                (char *)PIN_GetContextReg( ctxt, REG_INST_PTR ));
        exit (1);
    }

    if (PIN_GetContextReg( constCtxt, REG_INST_PTR )!=expectedIpAfter)
    {
        printf ("  After1WithContext Unexpected IP in constCtxt %p\n",
                (char *)PIN_GetContextReg( constCtxt, REG_INST_PTR ));
        exit (1);
    }
    if (expectedIpAfter!=ip)
    {
        printf ("  After1WithContext Unexpected IP from REG_VALUE REG_INST_PTR %p\n", (char *)ip);
        exit (1);
    }
}
예제 #2
0
/**	---------------------------------------------------------------------------
	\brief	

		[target function]
			A1                       A2 (A1 + RealPatchSize)
			|-----jmp A3 -- x90x90 --|^-------------
			     (   RealPatchSize   )
			jmp A3
			===> 
			A4 (  OpenProcess_Detour() 함수 주소  )

			A4 = A2 + A3 이므로 (jmp 명령이니까)
			A3 = A4 - A2 

		[trampoline]
			T1                       T2      T3     T4
			|-----MAX_PATCH_SIZE-----|jmp|-----4----|			 
			jmp T3
			===> A2

			A2 = T4 + T3 이므로
			T3 = A2 - T4

	\param	
	\return			
	\code
	\endcode		
-----------------------------------------------------------------------------*/
int InjectDetour(TD_HOOK_INFO*	pHookInfo)
{
	_ASSERTE(NULL != pHookInfo);
	_ASSERTE(NULL != pHookInfo->Target);
	_ASSERTE(NULL != pHookInfo->Detour);
	_ASSERTE(NULL != pHookInfo->Trampoline);

	if ((NULL == pHookInfo) || 
		(NULL == pHookInfo->Target) ||
		(NULL == pHookInfo->Detour) ||
		(NULL == pHookInfo->Trampoline) )
	{
		return -1;
	}


	//-------------------------------------------------------------------------
	// # STEP 1
	//		build trampoline
	//-------------------------------------------------------------------------
	// [TargetFunc's original opcode] [jmp] [TagetFunc + 5]
	//
	// trampoline 에 TargetFunc 의 코드를 복사해 둔다.
	//		- TargetFunc 에 JMP_REL_32_SIZE 만큼의 명령어 공간을 계산
	// 
	int Len = 0;
	DWORD	dwOpcodeLen = 0;
	do 
	{
		Len = GetInstructionLength(pHookInfo->Target + dwOpcodeLen);
		if (-1 == Len)
		{
			_ASSERTE(!"GetInstructionLength");
			return -1;
		}
		dwOpcodeLen += Len;
	} while (JMP_REL_32_SIZE > dwOpcodeLen);

	pHookInfo->OriginalOpcodeLen = dwOpcodeLen;

	#ifdef _DEBUG
	_tprintf(TEXT("target instruction length: %ld\n"), pHookInfo->OriginalOpcodeLen);
	#endif	
	
	if (MAX_PATCH_SIZE < pHookInfo->OriginalOpcodeLen)
	{
		_ASSERTE(!"too big patch size");
		return -1;
	}


	if (0 != CopyCodeBytes(pHookInfo->Target, 
							pHookInfo->Trampoline, 
							pHookInfo->OriginalOpcodeLen))
	{
		_ASSERTE(!"CopycodeBytes");
		return -1;
	}

	pHookInfo->Trampoline[MAX_PATCH_SIZE] = INST_JMP;
	DWORD_PTR tp_jmp = (pHookInfo->Target + pHookInfo->OriginalOpcodeLen) - 
						(pHookInfo->Trampoline + MAX_PATCH_SIZE + JMP_REL_32_SIZE);
	*(DWORD_PTR*)(&pHookInfo->Trampoline[MAX_PATCH_SIZE + INST_JMP_SIZE]) = tp_jmp;


	//-------------------------------------------------------------------------
	// # STEP 2
	//		build jmp [detour] stub
	//		reroute TargetFunc to DetourFunc
	//-------------------------------------------------------------------------
	// bto (buffer to overwite) = jmp [DetourFunc]
	//
	BYTE* bto = (BYTE*) malloc(pHookInfo->OriginalOpcodeLen);

	// RealPatchSize 에서 jmp rel_32 명령을 제외한 나머지 부분은 nop 처리
	//
	memset(bto, 0x90, pHookInfo->OriginalOpcodeLen);

	bto[0] = INST_JMP;
	*(reinterpret_cast<DWORD_PTR*>(bto + 1)) = 
		pHookInfo->Detour - (pHookInfo->Target + JMP_REL_32_SIZE);
	
	if (0 != CopyCodeBytes(bto, 
						pHookInfo->Target, 
						pHookInfo->OriginalOpcodeLen))
	{
		_ASSERTE(!"CopycodeBytes");
		if (NULL != bto){ free(bto); bto = NULL; }
		return -1;
	}	

	if (NULL != bto){ free(bto); bto = NULL; }
	pHookInfo->Enabled = TRUE;

	return 0;
}