From f0001f10055839883544cd273f494fb7f85a3fdd Mon Sep 17 00:00:00 2001 From: OctoWoW Date: Sat, 8 Aug 2026 13:10:50 -0700 Subject: [PATCH] Add LeviFix: client-side fix for the ERROR #132 levitate crash Stops the crash that hits every nearby player when someone levitates. The client tells worn attachments to play their wearer's animation index without checking it fits their own animation table; hover is index 137 and most attachments have exactly one animation, so the lookup reads far past the end of the range table and faults at 0x00713DFF. The DLL adds the missing bounds check and returns the client's own empty-table result instead. It verifies the six bytes at the target address before hooking, so it patches nothing on an unrecognised build. Not needed by launcher users: the launcher applies the same fix to WoW.exe directly. This is for people who run the client themselves. --- LICENSE | 21 ++++++ README.md | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++++ SHA256SUMS | 1 + levifix.dll | Bin 0 -> 48519 bytes 4 files changed, 204 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 SHA256SUMS create mode 100644 levifix.dll diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3d9ecc0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 LeviFix contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..3d5d67f --- /dev/null +++ b/README.md @@ -0,0 +1,182 @@ +# LeviFix + +Stops the **ERROR #132** crash that happens when a player near you starts levitating. + +For **WoW 1.12.1, client build 5875** only. + +--- + +## Do I need this? + +**If you play through the OctoWoW launcher: no.** The launcher already applies this +same fix directly to `WoW.exe` every time it updates. There is nothing to install and +nothing to turn on. + +**If you run the client yourself, without the launcher: yes.** Nothing else is +protecting you, and one priest levitating nearby can drop you out of the game. + +--- + +## What it fixes + +Every character animation has a number. Running is 0, walking 1, standing 2, +falling 35 — hovering is 137. + +Your character model has around 150 animations. The things you *wear* — helm, +shoulders, cape, weapon — are separate small models, and the client keeps them in +sync by telling each one: *play the same animation number as your wearer.* + +A helm does not have 150 animations. Most have exactly one. Its table is one entry +long. + +Nobody checks whether the number fits the table. The helm is told "play number 137", +and the client counts 137 entries forward from a table that ended after one — landing +in memory belonging to something else entirely, and reading whatever happens to be +there. That value is then used as a position. Usually it is obvious nonsense and gets +rejected. Sometimes it is a huge number, the client reads an address a gigabyte away +that does not exist, and Windows kills the game. + +This is why the crash: + +- hits **bystanders**, never the person who cast the spell — their own model has all + the animations, +- depends on what the levitating player is **wearing**, +- happens **sometimes** rather than every time, +- takes out **several people at once**, since everyone watching reads the same bad + table, +- and never occurred on retail vanilla, where players had no hover animation. + +LeviFix adds the missing check. When the animation number does not fit the table, it +returns exactly what the client itself returns for an empty table: first keyframe, no +blending. The attachment holds a frame. Nothing else changes, and nothing is visible +in game. + +--- + +## Requirements + +- WoW **1.12.1**, client build **5875** +- A `dlls.txt` loader — **VanillaFixes** + +If you already use nampower, SuperWoW, UnitXP or transmogFix, you have VanillaFixes +already and `dlls.txt` exists. + +--- + +## Install + +1. Put `levifix.dll` in your WoW folder, next to `WoW.exe`. + +2. Open `dlls.txt` in that same folder and add a line: + + ``` + levifix.dll + ``` + + If `dlls.txt` does not exist, create it with that single line in it. + +3. Start the game through **`VanillaFixes.exe`**, not by running `WoW.exe` directly. + Launching `WoW.exe` on its own loads no DLLs at all and the fix will not be active. + +4. Restart the client completely. A `/reload` is not enough. + +To turn it off again, put a `#` in front of the line in `dlls.txt`, or delete the DLL. + +--- + +## Checking that it works + +On startup LeviFix writes **`levifix.txt`** next to `WoW.exe`: + +``` +levifix=1 +status=installed at 0x00713D50 +prevented=0 +worst_index=0 +``` + +- **`status`** — `installed …` means the fix is active. Anything starting with + `refused:` means it patched nothing; see Safety below. +- **`prevented`** — how many out-of-range lookups it has refused. Each one is a read + that would otherwise have gone past the end of a table. +- **`worst_index`** — the largest out-of-range animation number seen so far. Expect + **137** to appear after someone levitates near you. + +The file is rewritten every few seconds while the count changes. + +--- + +## Safety + +Before patching anything, LeviFix compares the six bytes at the target address against +what it expects to find. If they differ — a different client build, a game update, or +another mod that got there first — **it patches nothing at all** and records the reason +in `levifix.txt`. It cannot corrupt a client it does not recognise. + +It hooks exactly one function, changes six bytes **in memory only, never on disk**, +touches no game files, sends nothing anywhere, and has no effect on gameplay. The only +observable change is that an attached model can hold a single animation frame instead +of the game crashing. + +It does **not** fix the underlying bug — that is in the client, and only the client +authors can fix it properly. It stops the crash at the last moment. If a different +crash appears, check `status` in `levifix.txt` first, and disable the DLL to rule it +out. + +### Antivirus + +`levifix.dll` is unsigned, and it modifies a running process in memory. Some scanners +flag that pattern heuristically. Verify the download against the checksum below before +using it. + +--- + +## Verifying your download + +``` +SHA-256 4059caa60e92536efaa988612565b64389a5497dd0505728d7e0414215d3f3ef levifix.dll +``` + +Windows: + +```powershell +Get-FileHash levifix.dll -Algorithm SHA256 +``` + +Linux / macOS: + +```sh +sha256sum levifix.dll +``` + +If the hash does not match, do not use the file. + +--- + +## Technical detail + +- Faulting instruction: `0x00713DFF`, `mov ebx, [ecx+edx*4]`, inside `sub_00713D50`. + That function receives an M2 animation track — confirmed by the + `word [track+2] == 0xFFFF` global-sequence test at `0x713D96` — plus an animation + index. +- It loads the track's entry count from `[track+4]`, tests it **only against zero**, + and then indexes an 8-byte-stride range table at `[track+8]` with the animation + index, without ever comparing the two. The only follow-up check is `start < end`, + and both of those come from the same, possibly out-of-bounds entry — two garbage + values in ascending order pass it. +- The index arrives from the model instance's field `+0x9C`, which at `0x00714650` is + copied verbatim from another model instance: an attachment inherits its wearer's + animation index with no regard for its own animation count. +- Measured across one installation: of 4502 attachment models, 3837 have exactly one + animation, and 305 have at least one animation track shorter than index 137. Of the + 1239 short tracks, reading at index 137 yields a value that passes the `start < end` + check and is large enough to fault in about 17% of cases — which is why the crash is + occasional rather than constant. +- The hook refuses the lookup and returns `{0, 0, 0.0f}`, matching the client's own + degenerate-range path at `0x00713D7F`. + +--- + +## Licence + +MIT. See [LICENSE](LICENSE). diff --git a/SHA256SUMS b/SHA256SUMS new file mode 100644 index 0000000..ee15300 --- /dev/null +++ b/SHA256SUMS @@ -0,0 +1 @@ +4059caa60e92536efaa988612565b64389a5497dd0505728d7e0414215d3f3ef *levifix.dll diff --git a/levifix.dll b/levifix.dll new file mode 100644 index 0000000000000000000000000000000000000000..9ffde85fb534643d75c79ab7746061e2dfa37f24 GIT binary patch literal 48519 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 hUDcDg8JN9mkE