// 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 }
void ReputationsInit() { int count; if(count=GetPrivateProfileIntA("Misc", "CityRepsCount", 0, ini)) { repList=new CityRep[count]; char buf[512]; GetPrivateProfileStringA("Misc", "CityRepsList", "", buf, 512, ini); char* end; char* start=buf; for(int i=0;i<count;i++) { end=strchr(start,':'); *end='\0'; repList[i].cityID=atoi(start); start=end+1; if(i==count-1) { repList[i].globalID=atoi(start); } else { end=strchr(start,','); *end='\0'; repList[i].globalID=atoi(start); start=end+1; } } SafeWrite32(0x43BEA5, (DWORD)&repList[0].cityID); SafeWrite32(0x43BF3C, (DWORD)&repList[0].cityID); SafeWrite32(0x43BF4C, (DWORD)&repList[0].globalID); SafeWrite32(0x43C03E, count*8); } }
void PremadeInit() { char buf[512]; GetPrivateProfileString("misc", "PremadePaths", "", buf, 512, ini); if(buf[0]) { char buf2[512]; GetPrivateProfileString("misc", "PremadeFIDs", "", buf2, 512, ini); int count=1; char* tmp=buf; while(tmp=strchr(tmp, ',')) { tmp++; count++; } premade=new PremadeChar[count]; tmp=buf; char* tmp2=buf2; for(int i=0;i<count;i++) { char* tmp3=strchr(tmp, ','); if(tmp3) *tmp3=0; strcpy_s(premade[i].path, 20, "premade\\"); strcat_s(premade[i].path, 20, tmp); tmp=tmp3 + 1; tmp3=strchr(tmp2, ','); if(tmp3) *tmp3=0; premade[i].fid=atoi(tmp2); tmp2=tmp3 + 1; } SafeWrite32(0x51C8D4, count); SafeWrite32(0x4A7D76, (DWORD)premade); SafeWrite32(0x4A8B1E, (DWORD)premade); SafeWrite32(0x4A7E2C, (DWORD)premade + 20); strcpy_s((char*)0x50AF68, 20, premade[0].path); } }
static void _stdcall SetInventoryCheck(bool skip) { if (skip) { SafeWrite16(0x46E7CD, 0x9090); //Inventory check SafeWrite32(0x46E7Cf, 0x90909090); } else { SafeWrite16(0x46E7CD, 0x850F); //Inventory check SafeWrite32(0x46E7Cf, 0x4B1); } }
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 OBSEPlugin_Load(const OBSEInterface * obse) { g_pluginHandle = obse->GetPluginHandle(); _MESSAGE("RuntimeEditorIDs Initializing..."); gLog.Indent(); if(!obse->isEditor) { for (int i = 0; i < VTBLTableSize; i++) { UInt32 PatchAddress = g_VTBLTable[i].Address + kTESForm_SetEditorID_VTBLOffset; SafeWrite32(PatchAddress, (UInt32)TESForm_HandleEditorID); _MESSAGE("Patched '%s' VTBL offset 0x%08X", g_VTBLTable[i].Class, PatchAddress); } } obse->SetOpcodeBase(0x2740); // 0x2740 - 0x274F obse->RegisterTypedCommand(&kCommandInfo_GetRuntimeEditorID, kRetnType_String); g_msgIntfc->RegisterListener(g_pluginHandle, "OBSE", OBSEMessageHandler); gLog.Outdent(); _MESSAGE("RuntimeEditorIDs Initialized!\n\n"); 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); }
UInt32 WriteRelJle(UInt32 jumpSrc, UInt32 jumpTgt) { // jle rel32 SafeWrite16(jumpSrc, 0x8E0F); jumpSrc += 2; UInt32 oldTgt = SafeWrite32(jumpSrc, jumpTgt - jumpSrc - 4); return jumpSrc + oldTgt + 4; }
UInt32 WriteRelCall(UInt32 jumpSrc, UInt32 jumpTgt) { // call rel32 SafeWrite8(jumpSrc, 0xE8); jumpSrc += 1; UInt32 oldTgt = SafeWrite32(jumpSrc, jumpTgt - jumpSrc - 4); return jumpSrc + oldTgt + 4; }
UInt32 WriteRelJump(UInt32 jumpSrc, UInt32 jumpTgt) { // jmp rel32 SafeWrite8(jumpSrc, 0xE9); jumpSrc += 1; UInt32 oldTgt = SafeWrite32(jumpSrc, jumpTgt - jumpSrc - 4); return jumpSrc + oldTgt + 4; }
void Hook_Animation_Init(void) { UInt32 enableAnimationHook = 0; if(GetNVSEConfigOption_UInt32("Animation", "EnableAnimationHook", &enableAnimationHook) && enableAnimationHook) { SafeWrite32(kHookGetGlobalModelPath, (UInt32)AnimationHook); } }
void PatchEndOfLineCheck(bool bDisableCheck) { if (bDisableCheck) WriteRelJump(kEndOfLineCheckPatchAddr, kEndOfLineCheckJumpAddr); else { SafeWrite8(kEndOfLineCheckPatchAddr, 0x0F); SafeWrite8(kEndOfLineCheckPatchAddr + 1, 0x83); SafeWrite32(kEndOfLineCheckPatchAddr + 2, kEndOfLineCheckJumpDelta); } }
void Hooks_Papyrus_Commit(void) { #ifdef PAPYRUS_CUSTOM_CLASS SafeWrite32(0x010EAA64, GetFnAddr(&IObjectHandlePolicy::Unk_02_Hook)); SafeWrite32(0x010EAA60, GetFnAddr(&IObjectHandlePolicy::IsType_Hook)); SafeWrite32(0x010EAA6C, GetFnAddr(&IObjectHandlePolicy::Create_Hook)); SafeWrite32(0x010EAA7C, GetFnAddr(&IObjectHandlePolicy::Resolve_Hook)); #endif WriteRelCall(0x008D7A40 + 0x098B, (UInt32)RegisterPapyrusFunctions_Hook); // GlobalData / event regs WriteRelCall(0x008D6550 + 0x002A, GetFnAddr(&SkyrimVM::OnFormDelete_Hook)); WriteRelCall(0x008D6990 + 0x0017, GetFnAddr(&SkyrimVM::RevertGlobalData_Hook)); // Normal game load WriteRelCall(0x008D6D00 + 0x0116, GetFnAddr(&SkyrimVM::RevertGlobalData_Hook)); // New script reload command WriteRelCall(0x008D3750 + 0x0101, GetFnAddr(&SkyrimVM::SaveGlobalData_Hook)); WriteRelCall(0x008D69C0 + 0x01B9, GetFnAddr(&SkyrimVM::LoadGlobalData_Hook)); // SafeWrite32(0x01149B98 + 4 * 3, GetFnAddr(&VMClassLoader::Load_Hook)); }
void InstallHook(void * retaddr, UInt32 hookSrc) { if(hookInstalled) return; else hookInstalled = true; _MESSAGE("InstallHook: thread = %d retaddr = %08X hookSrc = %d", GetCurrentThreadId(), retaddr, hookSrc); // DumpThreads(); std::string appPath = GetAppPath(); _MESSAGE("appPath = %s", appPath.c_str()); std::string dllSuffix; ProcHookInfo procHookInfo; bool isEditor = RunningEditor(); if(!IdentifyEXE(appPath.c_str(), isEditor, &dllSuffix, &procHookInfo)) { _ERROR("unknown exe"); return; } // build full path to our dll const char * dllPrefix = (isEditor == false) ? "\\skse_" : "\\skse_editor_"; g_dllPath = GetAppDir() + dllPrefix + dllSuffix + ".dll"; _MESSAGE("dll = %s", g_dllPath.c_str()); // hook winmain call UInt32 hookBaseAddr = procHookInfo.hookCallAddr; UInt32 hookBaseCallAddr = *((UInt32 *)(hookBaseAddr + 1)); hookBaseCallAddr += 5 + hookBaseAddr; // adjust for relcall _MESSAGE("old winmain = %08X", hookBaseCallAddr); g_hookedWinMain = (_HookedWinMain)hookBaseCallAddr; UInt32 newHookDst = ((UInt32)OnHook) - hookBaseAddr - 5; SafeWrite32(hookBaseAddr + 1, newHookDst); Hooks_Memory_PreloadCommit(); FlushInstructionCache(GetCurrentProcess(), NULL, 0); }
void Hook_DirectInput8Create_Init() { #if OBLIVION_VERSION == OBLIVION_VERSION_1_1 UInt32 thunkAddress = 0x009FC02C; #elif OBLIVION_VERSION == OBLIVION_VERSION_1_2 UInt32 thunkAddress = 0x00A2802C; #elif OBLIVION_VERSION == OBLIVION_VERSION_1_2_416 UInt32 thunkAddress = 0x00A2802C; #else #error unsupported version of oblivion #endif DICreate_RealFunc=*(DWORD*)thunkAddress; SafeWrite32(thunkAddress,(DWORD)Hook_DirectInput8Create_Execute); ZeroMemory(&DI_data,sizeof(DI_data)); for(WORD w=0;w<kMaxMacros;w++) DI_data.DisallowStates[w]=0x80; }
static void ApplyPatch(const PatchLocation * patch, UInt32 newData) { for(; patch->ptr; ++patch) { switch(patch->type) { case 0: SafeWrite32(patch->ptr, newData + patch->offset); break; case 1: SafeWrite16(patch->ptr, newData + patch->offset); break; } } }
void Hooks_Debug_Init(void) { GetSystemTime(&s_launchTime); UInt32 enableMiniDump = 0; GetConfigOption_UInt32("Debug", "WriteMinidumps", &enableMiniDump); if(enableMiniDump) { _MESSAGE("minidumps enabled"); // try to get dbghelp s_dbgHelpDLL = LoadLibrary("dbghelp.dll"); if(s_dbgHelpDLL) { s_dbgHelpWriteDump = (_MiniDumpWriteDump)GetProcAddress(s_dbgHelpDLL, "MiniDumpWriteDump"); if(!s_dbgHelpWriteDump) _WARNING("dbghelp missing MiniDumpWriteDump, upgrade to dbghelp 5.1 or later"); } else { _MESSAGE("no dbghelp"); } // we want to catch crashes from hook commit, apply exception filter in Init function if(s_dbgHelpDLL && s_dbgHelpWriteDump) { // precalculate as much as possible char myDocumentsPath[MAX_PATH]; ASSERT(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, myDocumentsPath))); sprintf_s(s_crashDumpPath, sizeof(s_crashDumpPath), "%s\\My Games\\Skyrim\\SKSE\\Crashdumps\\%04d-%02d-%02d_%02d.%02d.%02d.dmp", myDocumentsPath, s_launchTime.wYear, s_launchTime.wMonth, s_launchTime.wDay, s_launchTime.wHour, s_launchTime.wMinute, s_launchTime.wSecond); IFileStream::MakeAllDirs(s_crashDumpPath); // replace previous exception filter s_oldExceptionFilter = SetUnhandledExceptionFilter(ExceptionFilter); _MESSAGE("old exception filter = %08X", s_oldExceptionFilter); // disable game overwriting exception filter UInt32 thunkAddress = (UInt32)GetIATAddr((UInt8 *)GetModuleHandle(NULL), "kernel32.dll", "SetUnhandledExceptionFilter"); SafeWrite32(thunkAddress, (UInt32)SetUnhandledExceptionFilter_Hook); } } }
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); } }
void CritInit() { mode=GetPrivateProfileIntA("Misc", "OverrideCriticalTable", 2, ini); if(mode<0||mode>3) mode=0; if(!mode) return; dlog("Initilizing critical table override.", DL_INIT); critTable=new CritStruct[CritTableSize]; playerCrit=&critTable[6*9*38]; SafeWrite32(0x423F96, (DWORD)playerCrit); SafeWrite32(0x423FB3, (DWORD)critTable); dlog(". ", DL_INIT); if(mode==2 || mode==3) { CritStruct* defaultTable=(CritStruct*)_crit_succ_eff; SetEntry(2,4,1,4,0); SetEntry(2,4,1,5,5216); SetEntry(2,4,1,6,5000); SetEntry(2,4,2,4,0); SetEntry(2,4,2,5,5216); SetEntry(2,4,2,6,5000); SetEntry(2,5,1,4,0); SetEntry(2,5,1,5,5216); SetEntry(2,5,1,6,5000); SetEntry(2,5,2,4,0); SetEntry(2,5,2,5,5216); SetEntry(2,5,2,6,5000); SetEntry(3,5,1,6,5306); SetEntry(4,0,4,2,-1); SetEntry(5,0,4,2,-1); SetEntry(6,4,1,4,2); SetEntry(6,5,1,4,2); SetEntry(6,5,2,6,5608); SetEntry(9,3,3,4,2); SetEntry(13,5,1,4,4); SetEntry(13,5,2,4,4); SetEntry(13,5,3,4,4); SetEntry(13,5,4,4,4); SetEntry(13,5,5,4,4); SetEntry(18,0,0,5,5001); SetEntry(18,0,1,5,5001); SetEntry(18,0,2,5,5001); SetEntry(18,0,3,5,7105); SetEntry(18,0,4,5,7101); SetEntry(18,0,4,6,7104); SetEntry(18,0,5,5,7101); SetEntry(18,1,0,5,5008); SetEntry(18,1,1,5,5008); SetEntry(18,1,2,5,5009); SetEntry(18,1,3,5,5009); SetEntry(18,1,4,5,7102); SetEntry(18,1,5,5,7102); SetEntry(18,2,0,5,5008); SetEntry(18,2,1,5,5008); SetEntry(18,2,2,5,5009); SetEntry(18,2,3,5,5009); SetEntry(18,2,4,5,7102); SetEntry(18,2,5,5,7102); SetEntry(18,3,4,5,7101); SetEntry(18,3,5,5,7101); SetEntry(18,4,0,5,5023); SetEntry(18,4,1,5,7101); SetEntry(18,4,1,6,7103); SetEntry(18,4,2,5,7101); SetEntry(18,4,2,6,7103); SetEntry(18,4,3,5,7103); SetEntry(18,4,4,5,7103); SetEntry(18,4,5,5,7103); SetEntry(18,5,0,5,5023); SetEntry(18,5,1,5,7101); SetEntry(18,5,1,6,7103); SetEntry(18,5,2,5,7101); SetEntry(18,5,2,6,7103); SetEntry(18,5,3,5,7103); SetEntry(18,5,4,5,7103); SetEntry(18,5,5,5,7103); SetEntry(18,6,0,5,5027); SetEntry(18,6,1,5,5027); SetEntry(18,6,2,5,5027); //SetEntry(18,6,2,6,0); SetEntry(18,6,3,5,5027); SetEntry(18,6,4,5,7104); SetEntry(18,6,5,5,7104); SetEntry(18,7,0,5,5033); SetEntry(18,7,1,5,5027); SetEntry(18,7,1,6,7101); SetEntry(18,7,2,5,7101); SetEntry(18,7,3,5,7101); SetEntry(18,7,4,5,7101); SetEntry(18,7,5,5,7101); } Inited=true; dlogr(" Done", DL_INIT); }
void WriteRelJnz(UInt32 jumpSrc, UInt32 jumpTgt) { // jnz rel32 SafeWrite16(jumpSrc, 0x850F); SafeWrite32(jumpSrc + 2, jumpTgt - jumpSrc - 2 - 4); }
void SafeWriteJle(uint32_t src, uint32_t tgt) { SafeWrite16(src, 0x8E0F); SafeWrite32(src + 2, tgt - src - 2 - 4); }
void WriteRelJle(UInt32 jumpSrc, UInt32 jumpTgt) { // jle rel32 SafeWrite16(jumpSrc, 0x8E0F); SafeWrite32(jumpSrc + 2, jumpTgt - jumpSrc - 2 - 4); }
void HookCall(DWORD addr, void* func) { SafeWrite32(addr+1, (DWORD)func - (addr+5)); }
void ApplyPatchEditorOpCodeDataList(void) { SInt32 RelativeAddress = (UInt32)(&hookOpCodeDataList) - hookOpCodeDataListAddress - 5 /* EIP after instruction that we modify*/; SafeWrite32(hookOpCodeDataListAddress+1, (UInt32)RelativeAddress); }
void WriteRelCall(UInt32 jumpSrc, UInt32 jumpTgt) { // call rel32 SafeWrite8(jumpSrc, 0xE8); SafeWrite32(jumpSrc + 1, jumpTgt - jumpSrc - 1 - 4); }
void RegisterPapyrusFunctions_Hook(VMClassRegistry ** registryPtr) { #if LOG_PAPYRUS_FUNCTIONS // this is all kinds of bad VTableProxy ** vtableProxy = (VTableProxy **)registryPtr; void * oldRegisterFunction = (*vtableProxy)->vtbl[0x16 + 1]; SafeWrite32((UInt32)&(*vtableProxy)->vtbl[0x16 + 1], GetFnAddr(&VTableProxy::RegisterFunction_Hook)); #endif // call original code RegisterPapyrusFunctions(registryPtr); #if LOG_PAPYRUS_FUNCTIONS SafeWrite32((UInt32)&(*vtableProxy)->vtbl[0x16 + 1], (UInt32)oldRegisterFunction); #endif VMClassRegistry * registry = *registryPtr; // SKSE papyrusSKSE::RegisterFuncs(registry); // TESForm papyrusForm::RegisterFuncs(registry); // DefaultObjectManager papyrusDefaultObjectManager::RegisterFuncs(registry); // ColorForm papyrusColorComponent::RegisterFuncs(registry); papyrusColorForm::RegisterFuncs(registry); // Art papyrusArt::RegisterFuncs(registry); // EquipSlot papyrusEquipSlot::RegisterFuncs(registry); // HeadPart papyrusHeadPart::RegisterFuncs(registry); // TESObjectCELL papyrusCell::RegisterFuncs(registry); // ArmorAddon (TESObjectARMA) papyrusArmorAddon::RegisterFuncs(registry); // TESObjectARMO papyrusArmor::RegisterFuncs(registry); // TESSoulGem papyrusSoulGem::RegisterFuncs(registry); // BGSApparatus papyrusApparatus::RegisterFuncs(registry); // Math papyrusMath::RegisterFuncs(registry); // Input papyrusInput::RegisterFuncs(registry); // ObjectReference papyrusObjectReference::RegisterFuncs(registry); // Weapon papyrusWeapon::RegisterFuncs(registry); // Ammo papyrusAmmo::RegisterFuncs(registry); // CombatStyle papyrusCombatStyle::RegisterFuncs(registry); // Actor papyrusActor::RegisterFuncs(registry); // ActorBase (TESNPC) papyrusActorBase::RegisterFuncs(registry); // Outfit papyrusOutfit::RegisterFuncs(registry); // Potion papyrusPotion::RegisterFuncs(registry); // Race papyrusRace::RegisterFuncs(registry); // Spell papyrusSpell::RegisterFuncs(registry); // Enchantment papyrusEnchantment::RegisterFuncs(registry); // Ingredient papyrusIngredient::RegisterFuncs(registry); // Scroll papyrusScroll::RegisterFuncs(registry); // StringUtil papyrusStringUtil::RegisterFuncs(registry); // Keyword papyrusKeyword::RegisterFuncs(registry); // TESObjectBOOK papyrusBook::RegisterFuncs(registry); // ConstructibleObject papyrusConstructibleObject::RegisterFuncs(registry); #ifdef PAPYRUS_CUSTOM_CLASS // TintMask papyrusTintMask::RegisterFuncs(registry); #endif // Game papyrusGame::RegisterFuncs(registry); // UI papyrusUI::RegisterFuncs(registry); // Alias papyrusAlias::RegisterFuncs(registry); // Quest papyrusQuest::RegisterFuncs(registry); // Shout papyrusShout::RegisterFuncs(registry); // Utility papyrusUtility::RegisterFuncs(registry); // ActiveMagicEffect papyrusActiveMagicEffect::RegisterFuncs(registry); // SoundDescriptor papyrusSoundDescriptor::RegisterFuncs(registry); // Sound papyrusSound::RegisterFuncs(registry); // Weather papyrusWeather::RegisterFuncs(registry); // NetImmerse papyrusNetImmerse::RegisterFuncs(registry); // TextureSet papyrusTextureSet::RegisterFuncs(registry); // Tree papyrusTree::RegisterFuncs(registry); // Flora papyrusFlora::RegisterFuncs(registry); // Perk papyrusPerk::RegisterFuncs(registry); // MagicEffect papyrusMagicEffect::RegisterFuncs(registry); // UICallback papyrusUICallback::RegisterFuncs(registry); // ModEvent papyrusModEvent::RegisterFuncs(registry); // ActorValueInfo papyrusActorValueInfo::RegisterFuncs(registry); // LeveledItem papyrusLeveledItem::RegisterFuncs(registry); // LeveledSpell papyrusLeveledSpell::RegisterFuncs(registry); // LeveledActor papyrusLeveledActor::RegisterFuncs(registry); // WornObject papyrusWornObject::RegisterFuncs(registry); //#ifdef _PPAPI // Plugins for(PapyrusPluginList::iterator iter = s_pap_plugins.begin(); iter != s_pap_plugins.end(); ++iter) { (*iter)(registry); } //#endif }
void SafeWriteCall(uint32_t src, uint32_t tgt) { SafeWrite8(src, 0xE8); SafeWrite32(src + 1, tgt - src - 1 - 4); }
void SafeWriteJump(uint32_t src, uint32_t tgt) { SafeWrite8(src, 0xE9); SafeWrite32(src + 1, tgt - src - 1 - 4); }
void WriteRelJump(UInt32 jumpSrc, UInt32 jumpTgt) { // jmp rel32 SafeWrite8(jumpSrc, 0xE9); SafeWrite32(jumpSrc + 1, jumpTgt - jumpSrc - 1 - 4); }