static public void CanPowerAttack() { Trampoline.WriteRelativeCallBranch ( ScrambledBugs.Offsets.Patches.PowerAttackStamina.GetStaminaCostActor, PowerAttackStamina.CanPowerAttack(Memory.ReadRelativeCall(ScrambledBugs.Offsets.Patches.PowerAttackStamina.GetStaminaCostActor)) ); var assemblyActor = new UnmanagedArray <System.Byte>(); assemblyActor.Add(new System.Byte[2] { 0x84, 0xC0 }); // test al, al assemblyActor.Add(new System.Byte[1] { Assembly.Nop }); // nop assemblyActor.Add(new System.Byte[2] { 0x74, 0x6E }); // jz 6E Memory.SafeWrite <System.Byte>(ScrambledBugs.Offsets.Patches.PowerAttackStamina.HasStaminaCostActor, assemblyActor); Trampoline.WriteRelativeCallBranch ( ScrambledBugs.Offsets.Patches.PowerAttackStamina.GetStaminaCostPlayerCharacter, PowerAttackStamina.CanPowerAttack(Memory.ReadRelativeCall(ScrambledBugs.Offsets.Patches.PowerAttackStamina.GetStaminaCostPlayerCharacter)) ); var assemblyPlayerCharacter = new UnmanagedArray <System.Byte>(); assemblyPlayerCharacter.Add(new System.Byte[2] { 0x84, 0xC0 }); // test al, al assemblyPlayerCharacter.Add(new System.Byte[1] { Assembly.Nop }); // nop assemblyPlayerCharacter.Add(new System.Byte[2] { 0x75, 0x34 }); // jnz 34 Memory.SafeWrite <System.Byte>(ScrambledBugs.Offsets.Patches.PowerAttackStamina.HasStaminaCostPlayerCharacter, assemblyPlayerCharacter); }
static public void IsPlayerOrTeammate() { var assembly = new UnmanagedArray <System.Byte>(); assembly.Add(Memory.ReadArray <System.Byte>(ScrambledBugs.Offsets.Patches.TeammateDifficulty.IsPlayer, System.Runtime.CompilerServices.Unsafe.SizeOf <RelativeCall>())); // mov edx, 18 assembly.Add(new System.Byte[2] { 0x74, 6 + 3 + 2 + 2 }); // je B assembly.Add(new System.Byte[6] { 0x8B, 0x81, 0xE0, 0x00, 0x00, 0x00 }); // mov eax, [rcx+E0] assembly.Add(new System.Byte[3] { 0xC1, 0xE8, 0x1A }); // shr eax, 1A assembly.Add(new System.Byte[2] { 0xF6, 0xD0 }); // not al assembly.Add(new System.Byte[2] { 0xA8, 0x01 }); // test al, 1 assembly.Add(new System.Byte[1] { Assembly.Ret }); // ret Trampoline.WriteRelativeCallBranch(ScrambledBugs.Offsets.Patches.TeammateDifficulty.IsPlayer, assembly); // rax // eflags // actor != null /* * Actor* actor; // rcx * * return * (actor == player) || || ((actor->BoolBits() & ActorBoolBits.PlayerTeammate) == ActorBoolBits.PlayerTeammate); */ }
static public void GetMaximumWardPower() { var assembly = new UnmanagedArray <System.Byte>(); assembly.Add(new System.Byte[1] { 0x51 }); // push rcx assembly.Add(new System.Byte[4] { 0x48, 0x83, 0xEC, 0x40 }); // sub rsp, 40 assembly.Add(new System.Byte[2] { 0x48, 0xB8 }); assembly.Add(Eggstensions.Offsets.FindMaxMagnitudeVisitor.VirtualFunctionTable); // mov rax assembly.Add(new System.Byte[5] { 0x48, 0x89, 0x44, 0x24, 0x20 }); // mov [rsp+20], rax assembly.Add(new System.Byte[2] { 0x31, 0xC0 }); // xor eax, eax assembly.Add(new System.Byte[5] { 0x48, 0x89, 0x44, 0x24, 0x28 }); // mov [rsp+28], rax assembly.Add(new System.Byte[5] { 0xB8, 0xFF, 0xFF, 0xFF, 0xFF }); // mov eax, -1 assembly.Add(new System.Byte[4] { 0xF3, 0x0F, 0x2A, 0xC0 }); // cvtsi2ss xmm0, eax assembly.Add(new System.Byte[6] { 0xF3, 0x0F, 0x11, 0x44, 0x24, 0x30 }); // movss [rsp+30], xmm0 assembly.Add(new System.Byte[5] { 0x48, 0x8D, 0x54, 0x24, 0x20 }); // lea rdx, [rsp+20] assembly.Add(new System.Byte[7] { 0x48, 0x81, 0xC1, 0x98, 0x00, 0x00, 0x00 }); // add rcx, 98 assembly.Add(Assembly.AbsoluteCall(Eggstensions.Offsets.MagicTarget.VisitActiveEffects.ToPointer())); // call MagicTarget.VisitActiveEffects assembly.Add(new System.Byte[6] { 0xF3, 0x0F, 0x10, 0x4C, 0x24, 0x30 }); // movss xmm1, [rsp+30] assembly.Add(new System.Byte[5] { 0x48, 0x8B, 0x4C, 0x24, 0x40 }); // mov rcx, [rsp+40] assembly.Add(Assembly.AbsoluteCall(Eggstensions.Offsets.Actor.SetMaximumWardPower.ToPointer())); // call Actor.SetMaximumWardPower assembly.Add(new System.Byte[5] { 0x48, 0x8B, 0x4C, 0x24, 0x40 }); // mov rcx, [rsp+40] assembly.Add(Assembly.AbsoluteCall(Memory.ReadRelativeCall(ScrambledBugs.Offsets.Patches.AccumulatingMagnitude.GetMaximumWardPower))); // call Actor.GetMaximumWardPower assembly.Add(new System.Byte[4] { 0x48, 0x83, 0xC4, 0x48 }); // add rsp, 48 assembly.Add(new System.Byte[1] { Assembly.Ret }); // ret Trampoline.WriteRelativeCallBranch(ScrambledBugs.Offsets.Patches.AccumulatingMagnitude.GetMaximumWardPower, assembly); /* * Actor* actor; // rcx * * var findMaxMagnitudeVisitor = new FindMaxMagnitudeVisitor(); *(System.IntPtr*)&findMaxMagnitudeVisitor = Eggstensions.Offsets.FindMaxMagnitudeVisitor.VirtualFunctionTable; * findMaxMagnitudeVisitor.FinishedActiveEffect = null; * findMaxMagnitudeVisitor.MaximumMagnitude = -1.0F; * * actor->MagicTarget()->VisitActiveEffects(&findMaxMagnitudeVisitor); * actor->SetMaximumWardPower(findMaxMagnitudeVisitor.MaximumMagnitude); * * return actor->GetMaximumWardPower(); */ }
static public void ShouldAttach() { var assemblyBranch = new UnmanagedArray <System.Byte>(); assemblyBranch.Add(new System.Byte[2] { 0x41, 0x54 }); // push r12 assemblyBranch.Add(new System.Byte[2] { 0x41, 0x55 }); // push r13 assemblyBranch.Add(new System.Byte[4] { 0x48, 0x83, 0xEC, 0x28 }); // sub rsp, 28 assemblyBranch.Add(new System.Byte[4] { 0x48, 0x8B, 0x4E, 0x30 }); // mov rcx, [rsi+30] (modelReferenceEffect->Controller) assemblyBranch.Add(new System.Byte[3] { 0x48, 0x8B, 0x01 }); // mov rax, [rcx] assemblyBranch.Add(new System.Byte[3] { 0xFF, 0x50, 0x78 }); // call [rax+78] (ReferenceEffectController.GetAttachRoot(controller)) assemblyBranch.Add(new System.Byte[3] { 0x48, 0x85, 0xC0 }); // test rax, rax (attachRoot) assemblyBranch.Add(new System.Byte[2] { 0x75, 3 + 3 + 6 }); // jnz C (attachRoot == null) assemblyBranch.Add(new System.Byte[3] { 0x48, 0x8B, 0xCB }); // mov rcx, rbx (actor) assemblyBranch.Add(new System.Byte[3] { 0x48, 0x8B, 0x01 }); // mov rax, [rcx] assemblyBranch.Add(new System.Byte[6] { 0xFF, 0x90, 0x68, 0x04, 0x00, 0x00 }); // call [rax+468] (TESObjectREFR.GetCurrent3D(actor)) assemblyBranch.Add(new System.Byte[3] { 0x45, 0x31, 0xE4 }); // xor r12d, r12d (attachRootNode) assemblyBranch.Add(new System.Byte[3] { 0x48, 0x85, 0xC0 }); // test rax, rax assemblyBranch.Add(new System.Byte[2] { 0x74, (3 + 3 + 3 + 3 + 3 + 3 + 2) + 4 }); // jz 18 (attachRoot != null) assemblyBranch.Add(new System.Byte[3] { 0x4C, 0x8B, 0xE8 }); // mov r13, rax assemblyBranch.Add(new System.Byte[3] { 0x48, 0x8B, 0xC8 }); // mov rcx, rax assemblyBranch.Add(new System.Byte[3] { 0x48, 0x8B, 0x01 }); // mov rax, [rcx] assemblyBranch.Add(new System.Byte[3] { 0xFF, 0x50, 0x18 }); // call [rax+18] (NiObject.AsNode(attachRoot)) assemblyBranch.Add(new System.Byte[3] { 0x4C, 0x8B, 0xE0 }); // mov r12, rax assemblyBranch.Add(new System.Byte[3] { 0x4D, 0x85, 0xE4 }); // test r12, r12 assemblyBranch.Add(new System.Byte[2] { 0x75, 4 }); // jnz 4 (attachRootNode == null) assemblyBranch.Add(new System.Byte[4] { 0x4D, 0x8B, 0x65, 0x30 }); // mov r12, [r13+30] (attachRoot->Parent) assemblyBranch.Add(new System.Byte[4] { 0x4C, 0x3B, 0x66, 0x70 }); // cmp r12, [rsi+70] assemblyBranch.Add(new System.Byte[3] { 0x0F, 0x95, 0xC0 }); // setne al (attachRootNode != modelReferenceEffect->HitEffectArtData.AttachRoot) assemblyBranch.Add(new System.Byte[4] { 0x48, 0x83, 0xC4, 0x28 }); // add rsp, 28 assemblyBranch.Add(new System.Byte[2] { 0x41, 0x5D }); // pop r13 assemblyBranch.Add(new System.Byte[2] { 0x41, 0x5C }); // pop r12 assemblyBranch.Add(new System.Byte[1] { Assembly.Ret }); // ret Trampoline.WriteRelativeCallBranch(ScrambledBugs.Offsets.Patches.AttachHitEffectArt.IsPlayerAttach, assemblyBranch); // Volatile registers // actor != null // modelReferenceEffect != null // modelReferenceEffect->Controller != null /* * ModelReferenceEffect* modelReferenceEffect; // rsi * Actor* actor; // rbx * * ReferenceEffectController* controller = modelReferenceEffect->Controller(); * NiAVObject* attachRoot = controller->GetAttachRoot(); * * if (attachRoot == null) * { * attachRoot = actor->GetCurrent3D(); * } * * NiNode* attachRootNode = null; * * if (attachRoot != null) * { * attachRootNode = attachRoot->AsNode(); * * if (attachRootNode == null) * { * attachRootNode = attachRoot->Parent(); * } * } * * return attachRootNode != modelReferenceEffect->HitEffectArtData()->AttachRoot(); */ var assembly = new UnmanagedArray <System.Byte>(); assembly.Add(new System.Byte[2] { 0x84, 0xC0 }); // test al, al assembly.Add(new System.Byte[2] { 0x74, 0x55 }); // jz 55 Memory.SafeWrite <System.Byte>(ScrambledBugs.Offsets.Patches.AttachHitEffectArt.IsPlayerAttach, System.Runtime.CompilerServices.Unsafe.SizeOf <RelativeCall>(), assembly); }
static public void ShouldUpdate() { var assembly = new UnmanagedArray <System.Byte>(); assembly.Add(new System.Byte[1] { 0x52 }); // push rdx assembly.Add(new System.Byte[2] { 0x8B, 0xD0 }); // mov edx, eax assembly.Add(new System.Byte[3] { 0xC1, 0xEA, 0x07 }); // shr edx, 7 (ActiveEffectFlags.HasConditions) assembly.Add(new System.Byte[3] { 0xF6, 0xC2, 0x01 }); // test dl, 1 assembly.Add(new System.Byte[2] { 0x75, (2 + 3 + 3 + 2) + (2 + 3 + 3) }); // jne 12 assembly.Add(new System.Byte[2] { 0x8B, 0xD0 }); // mov edx, eax assembly.Add(new System.Byte[3] { 0xC1, 0xEA, 0x05 }); // shr edx, 5 (ActiveEffectFlags.ApplyingVisualEffects) assembly.Add(new System.Byte[3] { 0xF6, 0xC2, 0x01 }); // test dl, 1 assembly.Add(new System.Byte[2] { 0x75, 2 + 3 + 3 }); // jne 8 assembly.Add(new System.Byte[2] { 0x8B, 0xD0 }); // mov edx, eax assembly.Add(new System.Byte[3] { 0xC1, 0xEA, 0x06 }); // shr edx, 6 (ActiveEffectFlags.ApplyingSoundEffects) assembly.Add(new System.Byte[3] { 0xF6, 0xC2, 0x01 }); // test dl, 1 assembly.Add(new System.Byte[1] { 0x5A }); // pop rdx assembly.Add(new System.Byte[1] { Assembly.Ret }); // ret Trampoline.WriteRelativeCallBranch(ScrambledBugs.Offsets.Fixes.HitEffectRaceCondition.ShouldUpdate, assembly); // eflags /* * ActiveEffectFlags flags; // ecx * * return * ((flags & ActiveEffectFlags.Dispelled) == ActiveEffectFlags.Dispelled) || || ((flags & ActiveEffectFlags.ApplyingVisualEffects) == ActiveEffectFlags.ApplyingVisualEffects) || || ((flags & ActiveEffectFlags.ApplyingSoundEffects) == ActiveEffectFlags.ApplyingSoundEffects); */ }