static bool SafeWriteJump_Internal(uintptr_t src, uintptr_t dst, UInt8 op) { #pragma pack(push, 1) struct Code { UInt8 op; SInt32 displ; }; #pragma pack(pop) STATIC_ASSERT(sizeof(Code) == 5); ptrdiff_t delta = dst - (src + sizeof(Code)); if((delta < INT_MIN) || (delta > INT_MAX)) return false; Code code; code.op = op; code.displ = delta; SafeWriteBuf(src, &code, sizeof(code)); return true; }
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); }
void xEdit_ObScript_Commit() { ObScriptCommand cmd = *s_hijackedCommand; cmd.longName = xEditCommandName; cmd.shortName = ""; cmd.helpText = ""; cmd.needsParent = 0; cmd.numParams = 0; cmd.execute = xEditCommand_Execute; cmd.flags = 0; SafeWriteBuf((uintptr_t)s_hijackedCommand, &cmd, sizeof(cmd)); _MESSAGE("xEdit console command '%s' installed as 0x%08x", cmd.longName, cmd.opcode); }
void SafeWrite64(uintptr_t addr, UInt64 data) { SafeWriteBuf(addr, &data, sizeof(data)); }
void SafeWrite32(uintptr_t addr, UInt32 data) { SafeWriteBuf(addr, &data, sizeof(data)); }
void SafeWrite16(uintptr_t addr, UInt16 data) { SafeWriteBuf(addr, &data, sizeof(data)); }