示例#1
0
bool CDetour::CreateDetour()
{
	if (!gameconf->GetMemSig(signame, &detour_address))
	{
		g_pSM->LogError(myself, "Could not locate %s - Disabling detour", signame);
		return false;
	}

	if (!detour_address)
	{
		g_pSM->LogError(myself, "Sigscan for %s failed - Disabling detour to prevent crashes", signame);
		return false;
	}

	detour_restore.bytes = copy_bytes((unsigned char *)detour_address, NULL, OP_JMP_SIZE+1);

	/* First, save restore bits */
	for (size_t i=0; i<detour_restore.bytes; i++)
	{
		detour_restore.patch[i] = ((unsigned char *)detour_address)[i];
	}

	JitWriter wr;
	JitWriter *jit = &wr;
	jit_uint32_t CodeSize = 0;
	
	wr.outbase = NULL;
	wr.outptr = NULL;

jit_rewind:

	/* Patch old bytes in */
	if (wr.outbase != NULL)
	{
		copy_bytes((unsigned char *)detour_address, (unsigned char*)wr.outptr, detour_restore.bytes);
	}
	wr.outptr += detour_restore.bytes;

	/* Return to the original function */
	jitoffs_t call = IA32_Jump_Imm32(jit, 0);
	IA32_Write_Jump32_Abs(jit, call, (unsigned char *)detour_address + detour_restore.bytes);

	if (wr.outbase == NULL)
	{
		CodeSize = wr.get_outputpos();
		wr.outbase = (jitcode_t)spengine->AllocatePageMemory(CodeSize);
		spengine->SetReadWrite(wr.outbase);
		wr.outptr = wr.outbase;
		detour_trampoline = wr.outbase;
		goto jit_rewind;
	}

	spengine->SetReadExecute(wr.outbase);

	*trampoline = detour_trampoline;

	return true;
}
// this was pretty much copied verbatim from pRED's CBaseServer code.  Too much I didn't 
// understand in this area .... yet
bool CDetour::StartDetour() {
	if (!DetourAddress) {
		Msg ("Detour for %s failed - no valid pointer was provided.\n", FunctionDetoured);
		return false;
	}

	orig_bytes.size_stored = copy_bytes((mem_t *)DetourAddress, NULL, OP_JMP_SIZE+1);

	for ( size_t i=0; i < orig_bytes.size_stored; i++ )
		orig_bytes.bytes_from_memory[i] = ((mem_t *)DetourAddress)[i];

	JitWriter wr;
	JitWriter *jit = &wr;
	jit_uint32_t CodeSize = 0;
	
	wr.outbase = NULL;
	wr.outptr = NULL;

jit_rewind:

	/* Patch old bytes in */
	if (wr.outbase != NULL) 
		copy_bytes((mem_t *)DetourAddress, (mem_t *)wr.outptr, orig_bytes.size_stored);
	wr.outptr += orig_bytes.size_stored;

	/* Return to the original function */
	jitoffs_t call = IA32_Jump_Imm32(jit, 0);
	IA32_Write_Jump32_Abs(jit, call, (mem_t *)DetourAddress + orig_bytes.size_stored);

	if (wr.outbase == NULL)
	{
		CodeSize = wr.get_outputpos();
		wr.outbase = (jitcode_t)KE_AllocCode(g_pCodeCache, CodeSize);
		wr.outptr = wr.outbase;
		TrampolineAddress = wr.outbase;
		goto jit_rewind;
	}

	*TrampolineFunc = TrampolineAddress;

	return true;
}