Beispiel #1
0
// fix render path selection
void PatchRenderPath(void)
{
	//	0	none
	//	1	1x
	//	2	2
	//	3	2a (96)
	//	4	2b (96)
	//	5	2a
	//	6	2b
	//	7	3

#if RUNTIME_VERSION == RUNTIME_VERSION_1_4_0_525
	for(UInt32 i = 0; i < 6; i++)
		SafeWrite8(0x00B4F94D + i, 0x90);	// nop

	SafeWrite32(0x00B4F953 + 6, 7);	// render path goes here
#elif RUNTIME_VERSION == RUNTIME_VERSION_1_4_0_525ng
	for(UInt32 i = 0; i < 6; i++)
		SafeWrite8(0x00B4FCBD + i, 0x90);	// nop

	SafeWrite32(0x00B4FCC3 + 6, 7);	// render path goes here
#else
#error
#endif
}
Beispiel #2
0
static void FixEditorFont(void)
{
	// try something nice, otherwise fall back on SYSTEM_FIXED_FONT
	fontHandle = CreateFontIndirect(&kLucidaConsole9);
	if(fontHandle)
	{
		fontInfo = kLucidaConsole9;
	}
	else
	{
		fontHandle = GetStockObject(SYSTEM_FIXED_FONT);
		GetObject(fontHandle, sizeof(fontInfo), &fontInfo);
	}

#if CS_VERSION == CS_VERSION_1_0
	UInt32	basePatchAddr = 0x004F4491;
#elif CS_VERSION == CS_VERSION_1_2
	UInt32	basePatchAddr = 0x004FEAB9;
#else
#error unhandled cs version
#endif

	SafeWrite8(basePatchAddr + 0,	0xFF);
	SafeWrite8(basePatchAddr + 1,	0x15);
	SafeWrite32(basePatchAddr + 2,	(UInt32)&pModScriptWindow);
	SafeWrite8(basePatchAddr + 6,	0x90);
}
bool Cmd_OutputLocalMapPicturesOverride_Execute(COMMAND_ARGS)
{
	UInt8 oldGrids = *(SInt8*)kuGridsSquareAddr;

	bool bDoHook = (sGridsToLoad_Override != -1);
	if (bDoHook)
	{
		// temporarily modify uGridToLoad
		//*kuGridsSquareAddr = sGridsToLoad_Override;
		SafeWrite8(kuGridsSquareAddr, sGridsToLoad_Override);

		// install hook
		// not needed WriteRelJump(kOLMPPatchAddr, (UInt32)&GridCellArray_GetGridEntry_Hook);
	}

	Cmd_OutputLocalMapPictures_Execute(PASS_COMMAND_ARGS);

	if (bDoHook)
	{
		// restore original uGridsToLoad
		//*kuGridsToLoadAddr = oldGrids;
		SafeWrite8(kuGridsSquareAddr, oldGrids);

		// uninstall hook
		// not needed WriteRelCall(kOLMPPatchAddr, kGridCellArray_GetGridEntry);
	}

	return true;
}
Beispiel #4
0
void PatchEndOfLineCheck(bool bDisableCheck)
{

	if (bDisableCheck)
		SafeWrite8(kEndOfLineCheckPatchAddr, 0xEB);		// unconditional (short) jump
	else
		SafeWrite8(kEndOfLineCheckPatchAddr, 0x73);		// conditional jnb (short)
}
Beispiel #5
0
void PatchEndOfLineCheck(bool bDisableCheck)
{
	if (bDisableCheck)
		WriteRelJump(kEndOfLineCheckPatchAddr, kEndOfLineCheckJumpAddr);
	else
	{
		SafeWrite8(kEndOfLineCheckPatchAddr, 0x0F);
		SafeWrite8(kEndOfLineCheckPatchAddr + 1, 0x83);
		SafeWrite32(kEndOfLineCheckPatchAddr + 2, kEndOfLineCheckJumpDelta);
	}
}
static void FixErrorReportBug(void)
{
	// bethesda passes strings containing user input to printf-like functions
	// this causes crashes when the user input contains tokens printf is interested in
	// so we fix it

	// move the entire block of code before the call to printf down, add a new argument pointing to "%s"

	const UInt32	kBlockMoveDelta =	5;

#error	const UInt32	kBlockMoveSrc =		0x00500001;							// inside ShowCompilerError, one past last referebnce
#error	const UInt32	kBlockMoveDst =		kBlockMoveSrc + kBlockMoveDelta;
#error	const UInt32	kBlockMoveSize =	0x00500035 - kBlockMoveSrc;
#error	const UInt32	kFormatStrPos =		0x0092BBE4;	// "%s"
#error	const UInt32	kStackFixupPos =	0x0B + 2;
#error	const UInt32	kPCRelFixups[] =	{ 0x00 + 1, 0x06 + 1, 0x28 + 1 };

	UInt8	tempBuf[kBlockMoveSize];

	memcpy(tempBuf, (void *)kBlockMoveSrc, kBlockMoveSize);

	// jumps/calls are pc-relative, we're moving code so fix them up
	*((UInt32 *)&tempBuf[kPCRelFixups[0]]) -= kBlockMoveDelta;
	*((UInt32 *)&tempBuf[kPCRelFixups[1]]) -= kBlockMoveDelta;
	*((UInt32 *)&tempBuf[kPCRelFixups[2]]) -= kBlockMoveDelta;

	// added a new arg, so we need to clean it off the stack
	tempBuf[kStackFixupPos] += 4;

	SafeWriteBuf(kBlockMoveDst, tempBuf, kBlockMoveSize);

	SafeWrite8(kBlockMoveSrc + 0, 0x68);	// push "%s"
	SafeWrite32(kBlockMoveSrc + 1, kFormatStrPos);
}
Beispiel #7
0
UInt32 WriteRelCall(UInt32 jumpSrc, UInt32 jumpTgt)
{
	// call rel32
	SafeWrite8(jumpSrc, 0xE8);
	jumpSrc += 1;
	UInt32 oldTgt = SafeWrite32(jumpSrc, jumpTgt - jumpSrc - 4);
	return jumpSrc + oldTgt + 4;
}
Beispiel #8
0
UInt32 WriteRelJump(UInt32 jumpSrc, UInt32 jumpTgt)
{
	// jmp rel32
	SafeWrite8(jumpSrc, 0xE9);
	jumpSrc += 1;
	UInt32 oldTgt = SafeWrite32(jumpSrc, jumpTgt - jumpSrc - 4);
	return jumpSrc + oldTgt + 4;
}
Beispiel #9
0
void _stdcall RegAnimCombatCheck(DWORD newValue) {
	char oldValue = reg_anim_combat_check;
	reg_anim_combat_check = (newValue > 0);
	if (oldValue != reg_anim_combat_check) {
		SafeWrite8(0x459C97, reg_anim_combat_check); // reg_anim_func
		SafeWrite8(0x459D4B, reg_anim_combat_check); // reg_anim_animate
		SafeWrite8(0x459E3B, reg_anim_combat_check); // reg_anim_animate_reverse
		SafeWrite8(0x459EEB, reg_anim_combat_check); // reg_anim_obj_move_to_obj
		SafeWrite8(0x459F9F, reg_anim_combat_check); // reg_anim_obj_run_to_obj
		SafeWrite8(0x45A053, reg_anim_combat_check); // reg_anim_obj_move_to_tile
		SafeWrite8(0x45A105, reg_anim_combat_check); // reg_anim_obj_run_to_tile
		SafeWrite8(0x45AE53, reg_anim_combat_check); // reg_anim_animate_forever
	}
}
Beispiel #10
0
void Hook_Script_Init()
{
	WriteRelJump(ExtractStringPatchAddr, (UInt32)&ExtractStringHook);

	// patch the "apple bug"
	// game caches information about the most recently retrieved RefVariable for the current executing script
	// if same refIdx requested twice in a row returns previously returned ref without
	// bothering to check if form stored in ref var has changed
	// this fixes it by overwriting a conditional jump with an unconditional one
	SafeWrite8(kResolveRefVarPatchAddr, 0xEB);

	// game also caches information about the most recently retrieved local numeric variable for
	// currently executing script. Causes issues with function scripts. As above, overwrite conditional jump with unconditional
	SafeWrite8(kResolveNumericVarPatchAddr, 0xEB);

	// hook code in the vanilla expression parser's subroutine to fix the buffer overflow
	WriteRelJump(kExpressionParserBufferOverflowHookAddr_1, (UInt32)&ExpressionParserBufferOverflowHook_1);
	WriteRelJump(kExpressionParserBufferOverflowHookAddr_2, (UInt32)&ExpressionParserBufferOverflowHook_2);

	// hook ExtractArgs() to handle commands normally compiled with Cmd_Default_Parse which were instead compiled with Cmd_Expression_Parse
	ExtractArgsOverride::Init_Hooks();
}
Beispiel #11
0
void GameplayPatches(void)
{
	// originally supposed to be 100 /decimal/ but oops
	UInt8	kPickpocketChance[] =
	{
		0xB8, 0x00, 0x01, 0x00, 0x00,	// mov eax, 0x0100
		0xC3							// retn
	};

	ApplyPatch(0x00598DB0, kPickpocketChance, sizeof(kPickpocketChance));

	SafeWrite8(0x008F0850, 0xC3);	// disable achievements
}
Beispiel #12
0
	void __stdcall ToggleOverride(bool bOverride)
	{
		static const UInt32 patchLoc = 0x005C67E0;	// editor default parse routine	(g_defaultParseCommand in CommandTable)	(F3:0x005C01F0)
		
		// ToggleOverride() only gets invoked when we parse a begin or end statement, so set mode accordingly
		s_currentMode = kOverride_BlockType;

		// overwritten instructions
		static const UInt8 s_patchedInstructions[5] = { 0x81, 0xEC, 0x30, 0x02, 0x00 };	// same first five bytes as Oblivion
		if (bOverride) {			
			WriteRelJump(patchLoc, (UInt32)&Hook_Cmd_Default_Parse);
		}
		else {		
			for (UInt32 i = 0; i < sizeof(s_patchedInstructions); i++) {
				SafeWrite8(patchLoc+i, s_patchedInstructions[i]);
			}
		}
	}
Beispiel #13
0
// fix dinput code so it doesn't acquire the keyboard/mouse in exclusive mode
// bBackground Mouse works on startup, but when gaining focus that setting is ignored
// there's probably a better way to fix the bug but this is good enough
void PatchCoopLevel(void)
{
#if RUNTIME_VERSION == RUNTIME_VERSION_1_4_0_525
	SafeWrite8(0x00A227A1 + 1, 0x16);
	SafeWrite8(0x00A229CB + 1, 0x06);
	SafeWrite8(0x00A23CAD + 1, 0x06);
#elif RUNTIME_VERSION == RUNTIME_VERSION_1_4_0_525ng
	SafeWrite8(0x00A22371 + 1, 0x16);
	SafeWrite8(0x00A2259B + 1, 0x06);
	SafeWrite8(0x00A2387D + 1, 0x06);
#else
#error
#endif
}
Beispiel #14
0
void AnimationsAtOnceInit(signed char aniMax) {

	if (aniMax <= 32) return;

	AniLimitFixActive = true;

	int i;

	//allocate memory to store larger animation struct arrays
	anim_set = new BYTE[2656*(aniMax+1)];
	sad = new BYTE[3240*(aniMax+1)];

	//set general animation limit check (old 20) aniMax-12 -- +12 reserved for PC movement(4) + other critical animations(8)?
	SafeWrite8(0x413C07, aniMax-12);

	//PC movement animation limit checks (old 24) aniMax-8 -- +8 reserved for other critical animations?.
	for (i = 0; i < sizeof(AnimPCMove)/4; i++) {
		SafeWrite8(AnimPCMove[i], aniMax-8);
	}

	//Max animation limit checks (old 32) aniMax
	for (i = 0; i < sizeof(AnimMaxCheck)/4; i++) {
		SafeWrite8(AnimMaxCheck[i], aniMax);
	}

	//Max animations checks - animation struct size * max num of animations (old 2656*32=84992)
	for (i = 0; i < sizeof(AnimMaxSizeCheck)/4; i++) {
		SafeWrite32(AnimMaxSizeCheck[i], 2656*aniMax);
	}


	//divert old animation structure list pointers to newly alocated memory

	//struct array 1///////////////////

	//old addr 0x54C1B4
	SafeWrite32(0x413A9E, (DWORD)anim_set);

	//old addr 0x54C1C0
	for (i = 0; i < sizeof(fake_anim_set_C)/4; i++) {
		SafeWrite32(fake_anim_set_C[i], 12+(DWORD)anim_set);
	}

	//old addr 0x54CC14
	for (i = 0; i < sizeof(anim_set_0)/4; i++) {
		SafeWrite32(anim_set_0[i], 2656+(DWORD)anim_set);
	}

	//old addr 0x54CC18
	for (i = 0; i < sizeof(anim_set_4)/4; i++) {
		SafeWrite32(anim_set_4[i], 2656+4+(DWORD)anim_set);
	}

	//old addr 0x54CC1C
	for (i = 0; i < sizeof(anim_set_8)/4; i++) {
		SafeWrite32(anim_set_8[i], 2656+8+(DWORD)anim_set);
	}

	//old addr 0x54CC20
	for (i = 0; i < sizeof(anim_set_C)/4; i++) {
		SafeWrite32(anim_set_C[i], 2656+12+(DWORD)anim_set);
	}

	//old addr 0x54CC24
	for (i = 0; i < sizeof(anim_set_10)/4; i++) {
		SafeWrite32(anim_set_10[i], 2656+16+(DWORD)anim_set);
	}

	//old addr 0x54CC28
	for (i = 0; i < sizeof(anim_set_14)/4; i++) {
		SafeWrite32(anim_set_14[i], 2656+20+(DWORD)anim_set);
	}

	//old addr 0x54CC38
	SafeWrite32(0x413F29, 2656+36+(DWORD)anim_set);

	//old addr 0x54CC3C
	for (i = 0; i < sizeof(anim_set_28)/4; i++) {
		SafeWrite32(anim_set_28[i], 2656+40+(DWORD)anim_set);
	}

	//old addr 0x54CC48
	SafeWrite32(0x415C35, 2656+52+(DWORD)anim_set);


	//struct array 2///////////////////

	//old addr 0x530014
	for (i = 0; i < sizeof(sad_0)/4; i++) {
		SafeWrite32(sad_0[i], (DWORD)sad);
	}

	//old addr 0x530018
	for (i = 0; i < sizeof(sad_4)/4; i++) {
		SafeWrite32(sad_4[i], 4+(DWORD)sad);
	}

	//old addr 0x53001C
	for (i = 0; i < sizeof(sad_8)/4; i++) {
		SafeWrite32(sad_8[i], 8+(DWORD)sad);
	}

	//old addr 0x530020
	for (i = 0; i < sizeof(sad_C)/4; i++) {
		SafeWrite32(sad_C[i], 12+(DWORD)sad);
	}

	//old addr 0x530024
	for (i = 0; i < sizeof(sad_10)/4; i++) {
		SafeWrite32(sad_10[i], 16+(DWORD)sad);
	}

	//old addr 0x530028
	for (i = 0; i < sizeof(sad_14)/4; i++) {
		SafeWrite32(sad_14[i], 20+(DWORD)sad);
	}

	//old addr 0x53002C
	for (i = 0; i < sizeof(sad_18)/4; i++) {
		SafeWrite32(sad_18[i], 24+(DWORD)sad);
	}

	//old addr 0x530030
	for (i = 0; i < sizeof(sad_1C)/4; i++) {
		SafeWrite32(sad_1C[i], 28+(DWORD)sad);
	}

	//old addr 0x530034
	for (i = 0; i < sizeof(sad_20)/4; i++) {
		SafeWrite32(sad_20[i], 32+(DWORD)sad);
	}

	//old addr 0x530038
	for (i = 0; i < sizeof(sad_24)/4; i++) {
		SafeWrite32(sad_24[i], 36+(DWORD)sad);
	}

	//old addr 0x53003A
	SafeWrite32(0x416903, 38+(DWORD)sad);

	//old addr 0x53003B
	for (i = 0; i < sizeof(sad_27)/4; i++) {
		SafeWrite32(sad_27[i], 39+(DWORD)sad);
	}

	//old addr 0x53003C
	for (i = 0; i < sizeof(sad_28)/4; i++) {
		SafeWrite32(sad_28[i], 40+(DWORD)sad);
	}

}
Beispiel #15
0
void SafeWriteCall(uint32_t src, uint32_t tgt) {
	SafeWrite8(src, 0xE8);
	SafeWrite32(src + 1, tgt - src - 1 - 4);
}
Beispiel #16
0
void WriteRelCall(UInt32 jumpSrc, UInt32 jumpTgt)
{
	// call rel32
	SafeWrite8(jumpSrc, 0xE8);
	SafeWrite32(jumpSrc + 1, jumpTgt - jumpSrc - 1 - 4);
}
Beispiel #17
0
void MakeCall(DWORD addr, void* func, bool jump) {
	SafeWrite8(addr, jump?0xe9:0xe8);
	HookCall(addr, func);
}
Beispiel #18
0
void ApplyPatch(UInt32 base, UInt8 * buf, UInt32 len)
{
	for(UInt32 i = 0; i < len; i++)
		SafeWrite8(base + i, buf[i]);
}
Beispiel #19
0
void SafeWriteJump(uint32_t src, uint32_t tgt) {
	SafeWrite8(src, 0xE9);
	SafeWrite32(src + 1, tgt - src - 1 - 4);
}
Beispiel #20
0
void WriteRelJump(UInt32 jumpSrc, UInt32 jumpTgt)
{
	// jmp rel32
	SafeWrite8(jumpSrc, 0xE9);
	SafeWrite32(jumpSrc + 1, jumpTgt - jumpSrc - 1 - 4);
}