All pastes #461566 Raw Edit

Unnamed

public text v1 · immutable
#461566 ·published 2007-04-27 19:16 UTC
rendered paste body
u32 CHook::OriginalFunc(u32 num, ...)
{
	u32 retVal;

	if(!bHooked)
		return 0;

	u32 *argArray = NULL;
	if(num)
	{
		va_list args;
		va_start(args, num);
	
		argArray = new u32[num];

		for(u32 i = 0; i < num; i++)
			argArray[i] = va_arg(args, u32);

		//	Push the arguments onto the stack
		_asm
		{
			mov ecx, num
	loop1:
			dec ecx
			mov eax, argArray
			mov ebx, [eax + ecx * 4]
			push ebx
			test ecx, ecx
			jnz loop1
		}

		va_end(args);
	}

	FARPROC tmp;
	switch(type)
	{
	//	Debug hooks are called in exactly the same way as patch's
	case Debug:
	case Patch:
		tmp = MakePtr(FARPROC, entryStub, 0);
		break;
	//	IAT/EAT hooks are the same for this part
	case IAT:
	case EAT:
		tmp = m_hookFrom;
		break;
	default: 
		// ?
		break;
	}


	//	Call it based on the calling convention specified by the user
	switch(convention)
	{
	//	Properties of Normal:
	//		Arguments are pushed onto the stack from left to right
	//		Caller restores ESP after the function exits
	//		
	//		NOTE: Normal is not a real calling convention.  It's my
	//		combination of Stdcall and Cdecl.  It simply restores ESP
	//		regardless of whether or not the callee already did so.
	case Normal:
		_asm
		{
			mov ecx, num
			lea ecx, [ecx * 4]
			xor ebx, ebx
			add ebx, ecx
			add ebx, esp	//	Calculate the value of esp before args were pushed, and store
							//	it in ebx
			mov eax, tmp
			call eax
			mov retVal, eax
			mov esp, ebx	//	Restore esp
		}
		break;
	//	Properties of Fastcall:
	//		First two arguments are passed in ecx and edx
	//		
	case Fastcall:
		_asm
		{
			mov eax, argArray
			mov ecx, [eax]
			mov edx, [eax + 4]
			add esp, 8			//	Get rid of the first 2 args that we pushed earlier
			mov eax, tmp
			call eax
			mov retVal, eax
			add esp, 8
		}
		break;
	//	Properties of NoRet:
	//		Takes first argument where the return address should be
	//		Function does not return
	case NoRet:
		_asm
		{
			mov eax, tmp
			jmp eax
		}
		break;
	default:
		retVal = 0;
		break;
	}

	if(argArray)
		delete argArray;

	return retVal;
}