void EnableAutoMipmaps()
	{
		enabled = true;
		WriteJump((void*)0x0078CD2A, GenerateMipmaps_asm);	// Hooks the end of the function that converts PVRs to D3D textures
#ifdef PALLETIZED_MIPMAPS
		// This happens every frame for every palletized texture in the scene. Rather inefficient where mipmap generation is concerned.
		// Assuming somebody can figure out a method of keeping track of palette changes and textures who's mips have already been generated,
		// we can enable this for mainstream builds. Otherwise it should stay off.
		WriteJump((void*)0x0078CF06, GeneratePalletizedMipmaps_asm);
#endif
	}
Beispiel #2
0
void ConfigureFOV()
{
	static const double default_ratio = 4.0 / 3.0;
	const uint32_t width = HorizontalResolution;
	const uint32_t height = VerticalResolution;

	WriteJump(SetupScreen, SetupScreenFix);

	// Taking advantage of a nullsub call.
	WriteCall((void*)0x00513A88, DisplayVideoFrame_FixAspectRatio);

	// 4:3 and "tallscreen" (5:4, portrait, etc)
	// We don't need to do anything since these resolutions work fine with the default code.
	if ((height * default_ratio) == width || (height * default_ratio) > width)
		return;

	fov_rads = 0.96712852;	// 55.412382 degrees
	fov_bams = NJM_RAD_ANG(fov_rads);

	// Function hooks
	WriteJump(njSetPerspective, njSetPerspective_hook);
	WriteJump(njSetScreenDist, njSetScreenDist_hook);

	// Code patches
	WriteJump((void*)0x0079124A, SetFOV);
	WriteData((float**)0x00781525, &dummy); // Dirty hack to disable a write to ClippingRelated and keep the floating point stack balanced.
	WriteData((Angle**)0x0040872B, &last_bams); // Fixes a case of direct access to HorizontalFOV_BAMS
	WriteData((Angle**)0x00402F01, &last_bams); // Changes return value of GetHorizontalFOV_BAMS

	njSetPerspective_hook(bams_default);

	// Stops the Pause Menu from using horizontal stretch in place of vertical stretch in coordinate calculation
	// Main Pause Menu
	WriteData((float**)0x00457F69, &VerticalStretch); // Elipse/Oval
	WriteData((float**)0x004584EE, &VerticalStretch); // Blue Transparent Box
	WriteData((float**)0x0045802F, &VerticalStretch); // Pause Menu Options
	// Camera options
	WriteData((float**)0x00458D5C, &VerticalStretch); // Blue Transparent Box
	WriteData((float**)0x00458DF4, &VerticalStretch); // Auto Cam
	WriteData((float**)0x00458E3A, &VerticalStretch); // Free Cam
	// Controls
	WriteData((float**)0x0045905A, &VerticalStretch); // Blue Transparent Box
	WriteData((float**)0x004590BB, &VerticalStretch); // Each Control Element
	WriteData((float**)0x00459133, &VerticalStretch); // Default Button
}
Beispiel #3
0
stdc 
VOID __cdecl EnableHook(ULONG_PTR Function)
{
	HOOK_INFO *hinfo = GetHookInfoFromFunction(Function);
	if (hinfo)
	{
		if(!hinfo->Enabled){
			hinfo->Enabled = true;
			WriteJump((VOID *)hinfo->Function, hinfo->Hook, hinfo->hooktype, hinfo->index );
		}
	}
}
Beispiel #4
0
stdc  
VOID __cdecl DisableHook(ULONG_PTR Function)
{
	HOOK_INFO *hinfo = GetHookInfoFromFunction(Function);
	if (hinfo)
	{
		if(hinfo->Enabled){
			hinfo->Enabled = false;
			WriteJump((VOID *)hinfo->Function, hinfo->Bridge, ht_jmp, hinfo->index);
		}
	}

}
Beispiel #5
0
inline void WriteStubGate(Process const& process,
                          void* address,
                          void* stub,
                          void* get_orig_user_ptr_ptr_fn)
{
  using StubT = typename PatchDetourStub<TargetFuncT>;
#if defined(HADESMEM_DETAIL_ARCH_X64)
  auto const stub_gate = GenStubGate64(stub, get_orig_user_ptr_ptr_fn);
#elif defined(HADESMEM_DETAIL_ARCH_X86)
  auto const stub_gate = GenStubGate32(stub, get_orig_user_ptr_ptr_fn);
#else
#error "[HadesMem] Unsupported architecture."
#endif
  WriteVector(process, address, stub_gate);
  WriteJump(process,
            static_cast<std::uint8_t*>(address) + stub_gate.size(),
            &StubT::Stub,
            true,
            nullptr);
  FlushInstructionCache(process, address, stub_gate.size());
}
Beispiel #6
0
stdc
BOOL __cdecl HookFunction(ULONG_PTR OriginalFunction, ULONG_PTR NewFunction, char *name, hookType ht)
{

	lastErrorCode = he_None;
	specificError = hs_None;
    lastError[0] = 0;

	if(!initilized){
		if( !InitHookEngine() ){
			lastErrorCode = he_cantInit;
			strcpy(lastError,"Can not Initilize HookEngine.");
			dbgmsg(1,lastError);
			return FALSE;
		}
	}

	HOOK_INFO *hinfo = GetHookInfoFromFunction(OriginalFunction);

	if (hinfo) return TRUE; //already hooked...

	if (g_NumberOfHooks == (MAX_HOOKS - 1)){
		lastErrorCode = he_maxHooks;
		strcpy(lastError,"Maximum number of hooks reached.");
		dbgmsg(1,lastError);
		return FALSE;
	}

	if(ht > ht_auto){
	   sprintf(lastError, "Unimplemented hook type asked for");
	   lastErrorCode = he_UnknownHookType;
	   return false;
	}

	hinfo = &g_HookInfo[g_NumberOfHooks];

	hinfo->Function = OriginalFunction;
	hinfo->Hook = NewFunction;
    hinfo->hooktype = ht;
	hinfo->index = g_NumberOfHooks;
	hinfo->ApiName = strdup(name);
	hinfo->preAlignBytes = CountPreAlignBytes( (BYTE*)OriginalFunction );
    hinfo->hookableBytes = HookableBytes( OriginalFunction );

	dbgmsg(1, "Hooking %s (0x%llx) -> 0x%llx, pre=%d avail=%d\n", hinfo->ApiName, hinfo->Function , hinfo->Hook , hinfo->preAlignBytes, hinfo->hookableBytes);

	if( ht == ht_auto ){
		if(!AutoChooseHookType(hinfo)){
			lastErrorCode = he_cantHook;
			dbgmsg(1, lastError);
			ZeroHookInfo(hinfo->index);
			return FALSE;
		}
		dbgmsg(1, "AutoChooseHookType selected %s for %s\n", hook_name[(int)hinfo->hooktype], hinfo->ApiName );
	}

	if( !ValidateHookType(hinfo) ){
		lastErrorCode = he_cantHook;
		dbgmsg(1, lastError);
		ZeroHookInfo(hinfo->index);
		return FALSE;
	}

	VOID *pBridge = CreateBridge(hinfo);

	if (pBridge == NULL){
		ZeroHookInfo(g_NumberOfHooks);
		return FALSE;
	}

	hinfo->Bridge = (ULONG_PTR) pBridge;
	hinfo->Enabled = true;

	OverWriteScratchPad((VOID *)OriginalFunction, hinfo); //make pad were going to overwrite all 0xCC for debugging sake..

	if(!WriteJump((VOID *) OriginalFunction, NewFunction, hinfo->hooktype, g_NumberOfHooks)){ //activates hook in api prolog..
		ZeroHookInfo(g_NumberOfHooks);
		return FALSE;
	}

	g_NumberOfHooks++; //now its complete..
	return TRUE;
}
Beispiel #7
0
VOID *CreateBridge(HOOK_INFO *hinfo)
{
	if (g_pBridgeBuffer == NULL) return NULL;

	UINT x = 0;
	_DecodeResult res;
	_DecodedInst decodedInstructions[MAX_INSTRUCTIONS];
	unsigned int decodedInstructionsCount = 0;
	_DecodeType dt =  isX64 ? Decode64Bits : Decode32Bits;
	_OffsetType offset = 0;

	ULONG_PTR Function = hinfo->Function;
	int JumpSize = GetJumpSize(hinfo->hooktype);

	res = distorm_decode(offset,	// offset for buffer
		(const BYTE *) Function,	// buffer to disassemble
		50,							// function size (code size to disasm) 
									// 50 instr should be _quite_ enough
		dt,							// x86 or x64?
		decodedInstructions,		// decoded instr
		MAX_INSTRUCTIONS,			// array size
		&decodedInstructionsCount	// how many instr were disassembled?
		);

	if (res == DECRES_INPUTERR){
		sprintf(lastError, "Could not disassemble address %x", (UINT)Function);
		//dbgmsg(lastError);
		lastErrorCode = he_cantDisasm;
		return NULL;
	}

	DWORD InstrSize = 0;
	VOID *pBridge = (VOID *) &g_pBridgeBuffer[g_CurrentBridgeBufferSize];

	//copy full instructions from API to our trampoline.
	for (x ; x < decodedInstructionsCount; x++)
	{
		if (InstrSize >= JumpSize) break;

		BYTE *pCurInstr = (BYTE *) (InstrSize + (ULONG_PTR) Function);
		
		if(logLevel >=3){
			dbgmsg(3, "%s+%d \t %-10s %-6s %s", 
				 hinfo->ApiName,
				 InstrSize,
				 decodedInstructions[x].instructionHex.p, 
				 decodedInstructions[x].mnemonic.p, 
				 decodedInstructions[x].operands.p
			);
		}

		if( UnSupportedOpcode(pCurInstr, hinfo->index) ){
			dbgmsg(0, "CreatreBridge::UnSupportedOpcode found missed in pre-Validation?! needed=%d, hookable=%d, cur=%d, type=%s",
						JumpSize, hinfo->hookableBytes,InstrSize, GetHookName(hinfo->hooktype)
				   );
			DebugBreak(); 
			//if we leave here, g_CurrentBridgeBufferSize has been incremented and bytes copied to
			//the alloced g_pBridgeBuffer, but the API itself is untouched.
			return NULL; 
		}

		memcpy(&g_pBridgeBuffer[g_CurrentBridgeBufferSize], (VOID *) pCurInstr, decodedInstructions[x].size);

		g_CurrentBridgeBufferSize += decodedInstructions[x].size;
		InstrSize += decodedInstructions[x].size;
	}

	hinfo->OverwrittenInstructions = x;
	hinfo->OverwrittenBytes = InstrSize; //we will 0xCC this many in API latter for debugging sake...

	//to leave trampoline...
	hookType ht = isX64 ? ht_jmp : ht_pushret; //both absolute address jumps for safety...
	bool rv = WriteJump(&g_pBridgeBuffer[g_CurrentBridgeBufferSize], Function + InstrSize, ht, hinfo->index);
	g_CurrentBridgeBufferSize +=  GetJumpSize(ht);  

	if(!rv) return NULL;

	return pBridge;
}