From 2781aacf45d9cfef4e226efacf6f7d1ac467b99c Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Thu, 20 Aug 2026 15:22:15 -0400 Subject: [PATCH] Add remaining interesting bits for the SupportDesk HTTP API This will enable us to finally introspect the data for these requests! The most important bit was figuring out the stages and then making up a sensible delegate to hook into. --- .../Client/SupportDesk/HttpConnection.cs | 13 ++++- .../Client/SupportDesk/HttpConnectionImpl.cs | 2 +- .../FFXIV/Client/SupportDesk/HttpRequest.cs | 8 +++ .../Client/SupportDesk/HttpRequestImpl.cs | 56 +++++++++++++++++-- ida/data.yml | 6 +- 5 files changed, 75 insertions(+), 10 deletions(-) diff --git a/FFXIVClientStructs/FFXIV/Client/SupportDesk/HttpConnection.cs b/FFXIVClientStructs/FFXIV/Client/SupportDesk/HttpConnection.cs index 70de340fbb..a61f840b6f 100644 --- a/FFXIVClientStructs/FFXIV/Client/SupportDesk/HttpConnection.cs +++ b/FFXIVClientStructs/FFXIV/Client/SupportDesk/HttpConnection.cs @@ -7,11 +7,20 @@ public unsafe partial struct HttpConnection { [VirtualFunction(0)] public partial HttpRequest* Dtor(byte freeFlags); - // Initializes the HTTP session. + /// Initializes the HTTP session. [VirtualFunction(1)] public partial void OpenSession(); - // Cleans up the HTTP session. + /// Cleans up the HTTP session. [VirtualFunction(2)] public partial void CloseSession(); + + /// Creates a new HTTPRequest. + /// URL to make a request to. + /// The HTTP verb, such as "GET" or "POST". + /// Any request data to send (only relevant for POST requests really). + /// Length of the data buffer. + /// The new HTTPRequest handle if it could be successfully created. + [VirtualFunction(4)] + public partial HttpRequest* MakeRequest(byte* url, byte* verb, byte* data, ulong dataLength); } diff --git a/FFXIVClientStructs/FFXIV/Client/SupportDesk/HttpConnectionImpl.cs b/FFXIVClientStructs/FFXIV/Client/SupportDesk/HttpConnectionImpl.cs index c6a8017a7b..615a838afd 100644 --- a/FFXIVClientStructs/FFXIV/Client/SupportDesk/HttpConnectionImpl.cs +++ b/FFXIVClientStructs/FFXIV/Client/SupportDesk/HttpConnectionImpl.cs @@ -6,5 +6,5 @@ namespace FFXIVClientStructs.FFXIV.Client.SupportDesk; [Inherits] [StructLayout(LayoutKind.Explicit, Size = 0x10)] public unsafe partial struct HttpConnectionImpl { - [FieldOffset(0x008)] void* SessionHandle; // HINTERNET + [FieldOffset(0x008)] public void* SessionHandle; // HINTERNET } diff --git a/FFXIVClientStructs/FFXIV/Client/SupportDesk/HttpRequest.cs b/FFXIVClientStructs/FFXIV/Client/SupportDesk/HttpRequest.cs index f1be72157a..19cba0d1b6 100644 --- a/FFXIVClientStructs/FFXIV/Client/SupportDesk/HttpRequest.cs +++ b/FFXIVClientStructs/FFXIV/Client/SupportDesk/HttpRequest.cs @@ -6,4 +6,12 @@ namespace FFXIVClientStructs.FFXIV.Client.SupportDesk; public unsafe partial struct HttpRequest { [VirtualFunction(0)] public partial HttpRequest* Dtor(byte freeFlags); + + /// Updates various bits based on the current stage. + [VirtualFunction(1)] + public partial bool Update(); + + /// Cleans up the open handle. + [VirtualFunction(2)] + public partial bool CloseHandle(); } diff --git a/FFXIVClientStructs/FFXIV/Client/SupportDesk/HttpRequestImpl.cs b/FFXIVClientStructs/FFXIV/Client/SupportDesk/HttpRequestImpl.cs index d8d6c762d2..db98ed97df 100644 --- a/FFXIVClientStructs/FFXIV/Client/SupportDesk/HttpRequestImpl.cs +++ b/FFXIVClientStructs/FFXIV/Client/SupportDesk/HttpRequestImpl.cs @@ -6,10 +6,54 @@ namespace FFXIVClientStructs.FFXIV.Client.SupportDesk; [Inherits] [StructLayout(LayoutKind.Explicit, Size = 0x8C8)] public unsafe partial struct HttpRequestImpl { - [FieldOffset(0x010)] void* RequestHandle; // HINTERNET - [FieldOffset(0x018)] void* ResponseData; - [FieldOffset(0x020)] void* ResponseDataOffset; - [FieldOffset(0x028)] void* ResponseDataSize; - [FieldOffset(0x470)] void* OptionalData; - [FieldOffset(0x480)] int Stage; + [FieldOffset(0x010)] public void* RequestHandle; // HINTERNET + [FieldOffset(0x018)] public byte* ResponseData; + [FieldOffset(0x020)] public long ResponseDataOffset; + [FieldOffset(0x028)] public ulong ResponseDataSize; + [FieldOffset(0x470)] public byte* OptionalData; + [FieldOffset(0x480)] public HttpRequestStage Stage; + [FieldOffset(0x48C)] public int StatusCode; + /// Increased by Framework.FrameDeltaTime every time Update is called. + [FieldOffset(0x8C0)] public float FrameDeltaTimeCounter; + + /// Initializes and begins this request. + /// The HINTERNET handle to use. + /// URL to make a request to. + /// The HTTP verb, such as "GET" or "POST". + /// Any request data to send (only relevant for POST requests really). + /// Length of the data buffer. + /// Whether the request was successfully sent. + [MemberFunction("E8 ?? ?? ?? ?? 84 C0 75 ?? 48 8B 03 BA ?? ?? ?? ?? 48 8B CB FF 10 33 DB")] + public partial bool BeginRequest(void* sessionHandle, byte* url, byte* verb, byte* data, ulong dataLength); + + /// Used as the WinHttp status callback. + /// Documentation for this callback can be found here. + [MemberFunction("48 85 D2 0F 84 ?? ?? ?? ?? 48 89 5C 24 ?? 56 57")] + public static partial void StatusCallback(void* requestHandle, HttpRequestImpl* context, uint internetStatus, void* statusInformation, uint statusInformationLength); } + +public enum HttpRequestStage { + Unk0 = 0, + /// Set during BeginRequest. + Began = 1, + /// Used while and shortly after fetching the ContentLength and StatusCode headers from the response. + ReadingHeaders = 2, + /// Used while reading the response data. + ReadingData = 3, + /// Seen after FetchingData, and there's nothing more to read. + ReadAllData = 4, + Unk5 = 5, + Unk6 = 6, + /// Set for WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING. + Closing = 7, + /// Set when the StatusCode is not 200 OK. Can also happen when WinHttpSendRequest is unsuccessful. + NotOk = 8, + Unk9 = 9, + Unk10 = 10, + Unk11 = 11, + Unk12 = 12, + Unk13 = 13, + /// Set for WINHTTP_CALLBACK_STATUS_SECURE_FAILURE. + SecureFailure = 14, +} + diff --git a/ida/data.yml b/ida/data.yml index 34517a678a..ec46c2c514 100644 --- a/ida/data.yml +++ b/ida/data.yml @@ -320,7 +320,6 @@ functions: 0x141C17880: lua_gethookmask 0x141C17A70: lua_sethook 0x141C17AA0: lua_setlocal - 0x141CF2790: SupportDeskHttpCallback 0x141C59F10: SupportDeskCreateConnection 0x1418F20E0: luaL_openlibs 0x1418F22D0: luaL_addlstring @@ -1013,11 +1012,14 @@ classes: base: Client::SupportDesk::HttpConnection funcs: 0x141CB27A0: Initialize + 0x141CF2790: StatusCallback # static Client::SupportDesk::HttpRequest: vtbls: - ea: 0x142493A60 vfuncs: 0: dtor + 1: Update + 2: CloseHandle Client::SupportDesk::HttpRequestImpl: vtbls: - ea: 0x1424938C8 @@ -11783,6 +11785,8 @@ classes: - ea: 0x142410618 funcs: 0x141A42DD0: ctor + vfuncs: + 0: dtor Client::UI::Misc::CharaViewPortrait: vtbls: - ea: 0x142198BA8