This commit is contained in:
parent
dfea844a19
commit
ee77c4afad
4 changed files with 58 additions and 0 deletions
BIN
content/blog/sqpackdll/china.webp
Normal file
BIN
content/blog/sqpackdll/china.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 112 KiB |
BIN
content/blog/sqpackdll/dolphin.webp
Normal file
BIN
content/blog/sqpackdll/dolphin.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
58
content/blog/sqpackdll/index.md
Normal file
58
content/blog/sqpackdll/index.md
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
---
|
||||||
|
title: "I figured out the API to sqexPatch.dll"
|
||||||
|
date: 2025-07-10
|
||||||
|
draft: false
|
||||||
|
tags:
|
||||||
|
- FFXIV
|
||||||
|
- Reverse Engineering
|
||||||
|
summary: "One of my special interests lately has been exploring the different operating regions of FFXIV."
|
||||||
|
bluesky_url: ""
|
||||||
|
mastodon_url: ""
|
||||||
|
---
|
||||||
|
|
||||||
|
One of my special interests lately has been exploring the different operating regions of FFXIV. If you don't know, there are two independent operators running their own "versions" of FFXIV: Shenqu Games and ActozSoft, for the Chinese and South Korean markets respectively.
|
||||||
|
|
||||||
|
Since I don't live in either China or South Korea, and I don't know anybody who does - trying to play these versions is hard. Both regions have stringent video game laws (to prevent youths from spending all of their time online) and also strong ties between corporations and the government. So I would need to _actually_ be a Chinese or Korean citizen to use an account, because one of the first steps is identity verification.
|
||||||
|
|
||||||
|
However I found out it's possible to download the Chinese client from the official website, and you can set it up to a certain point without an account. I started digging into the files I did have access to, and found this:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
What _is_ this? The filename immediately intrigued me, and it's purpose makes a whole lot of sense when you look at the bigger picture. In these regions, they don't use the launcher we use. These launchers are 100% custom, but work in the same general fashion - websites that interact with native code:
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
And these are not made by Square Enix obviously, but are maintained by their operators. However, if you look at the game files they are identical (in structure) to what you see in Global. So putting 2 and 2 together, they must use a similar patching system for updating the game[^1]! That's where `sqexPatch.dll` comes in, and after some reverse-engineering of the Chinese launcher it confirms my suspicion - they indeed use this to update their game files.
|
||||||
|
|
||||||
|
The DLL sat in my Ghidra for a few months, but I finally figured out how it works - _mostly_. For example, you can install patch files like so:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let path = CString::new("boot\\2025.04.09.0000.0001.patch").unwrap();
|
||||||
|
let dest = CString::new("C:\\GameInstall\\boot").unwrap();
|
||||||
|
sqexPatchInstallStart(1, dest.as_ptr() as *mut i8, path.as_ptr() as *mut i8);
|
||||||
|
|
||||||
|
while sqexPatchInstallIsBusy(1, data.as_mut_ptr()) {}
|
||||||
|
|
||||||
|
sqexPatchInstallGetResponse(1);
|
||||||
|
```
|
||||||
|
|
||||||
|
Downloading from a patch server (like [Kawari](https://github.com/redstrate/Kawari)) is also possible, although that's quite involved. You can find a complete working example [here](https://codeberg.org/redstrate/sqexpatch-sys/src/branch/main/examples/basic.rs). There's still a few functions left that I haven't explored, and I need to try patching a full game someday.
|
||||||
|
|
||||||
|
What this means for FFXIV reverse engineering is very little I think, but it's still super cool. We already have close-to-retail patching figured out, but knowing another official patching method is neat.
|
||||||
|
|
||||||
|
The Rust bindings for this DLL are available on [my Codeberg](https://codeberg.org/redstrate/sqexpatch-sys/src/branch/main).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Are all the normal people done reading? Okay, now here's a big info dump of stuff I can't naturally fit into the text above:
|
||||||
|
|
||||||
|
If you search for this filename online, one real search result comes up! It's a Chinese user [hacking the DLL to make it download faster](https://blog.homura.cc/articles/2023/02/28/post_04.html)! Neat!
|
||||||
|
|
||||||
|
Both the South Korean and Chinese launchers hardcode an identical string: `ffxivboot.exe/149504/5f2a70612aa58378eb347869e75adeb8f5581a1b`. They feed this to the `sqexPatchInitialize` function since they don't have a "regular" boot component.
|
||||||
|
|
||||||
|
For some reason, the `sqexPatch.dll` differs slightly than `ffxivupdater64.exe` for example with it's user agent. Global says it's "FFXIV PATCH CLIENT" but the DLL says it's "FFXIV_Patch". This is identical for both regions, as far as I can tell.
|
||||||
|
|
||||||
|
Both the Chinese and Korean versions are built for 32-bit Windows, I have no idea why. It should also be noted that they are _not_ the same DLL - they have two different file hashes and they have two very different build paths.
|
||||||
|
|
||||||
|
[^1]: If you aren't aware, the patching system in FFXIV is closely tied to it's own compressed, proprietary data format. So it figures that they wouldn't bother reinventing that wheel, especially since they should have source code access anyway.
|
BIN
content/blog/sqpackdll/korea.webp
Normal file
BIN
content/blog/sqpackdll/korea.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 183 KiB |
Loading…
Add table
Reference in a new issue