← back to the investigation

supporting evidence / markdown

akatsuki loader / network report

the details behind what i found inside the akatsuki patcher.

download .md

i manually traced the loader's outbound calls, then followed the stable DLL it downloaded on 11 october 2026. the loader contacts akatsuki's update and patcher service on its own. the downloaded DLL also collects process/window information and replaces fs in osu!'s score request builder. i've put the collection and hook chain in the technical report.

when it runsrequestexplicit application datawhat the response is used for
The loader window finishes loading; retried after connection failureGET https://air_conditioning.akatsuki.gg/loader/loader-updatesNo application query parameters or request body at this call siteJSON update information and available branches
The user presses LaunchGET https://air_conditioning.akatsuki.gg/patcher/patcher-version?branch=<selected branch>Selected branch in the URL; the configured default is stableDownloaded managed patcher bytes
The local loader's MD5 differs from the hash in update metadataGET <LoaderUpdates.Loader.DownloadUrl>No explicit request body at this call siteReplacement loader executable

the updater takes its download URL from the service response. i found no hostname allowlist or additional downloaded-byte hash/signature check in that replacement chain. the MD5 comparison decides whether the current loader needs replacing; it doesn't verify the replacement bytes. those two fixed endpoints therefore aren't a complete list of hosts every future download could use. the metadata i saved offers 20261005 at s3.ca-central-1.wasabisys.com/akatsuki.pw/loaders/20261005.exe. the stable patcher request redirected to that bucket's patchers/stable-20261007.dll. these are executable downloads. i haven't observed them receiving the process report. temporary signed queries are omitted.

the downloaded patcher is passed to Injector.Inject and loaded into the osu! process through ManagedMemoryLoader.Load, with the game launched using -devserver akatsuki.gg. that library isn't embedded in the supplied exe. i inspected it separately so its behaviour wasn't inferred from the loader's three HTTP calls.

what the loader sends#

the loader's network operations are HttpClientJsonExtensions.GetFromJsonAsync, HttpClient.GetByteArrayAsync and HttpClient.GetAsync. the explicit application value added to a fixed request is the selected release branch. i found no POST/upload call, explicit username/password transfer or separate telemetry destination in those loader paths. the exe's MD5 is compared locally. the inspected code doesn't send it. that finding covers the loader, not everything the downloaded code or platform might do.

the updater sets Cache-Control: no-cache. i found no custom Authorization, Cookie or User-Agent setter in the loader's member/call references. ordinary networking metadata is separate from explicit application data.

SignalR client libraries are bundled, but i found no member references to SignalR connections or WebSocket operations in the loader assembly. having those libraries in the bundle doesn't establish a /loader-hub connection.

current service check#

my first Python TLS request rejected hostname validation for air_conditioning.akatsuki.gg. macOS native curl later acquired the payload and update JSON with certificate checks enabled and no insecure override. the DLL request followed HTTP 302 to HTTP 200. the saved DLL is 3,674,624 bytes, with SHA-256 7dbc3efcbff2dba1d38ba2fecec46ed69828d38349eb2e1f087ae640aadb5441.

the 566-byte metadata snapshot at 05:43 UTC names loader version 20261005, expected MD5 c0166f4e6b3235991979f3b9acaefccc, and stable branch version 20261007. the supplied exe's MD5 is 7640235573c5666de089734c7bf8c6b4. that mismatch explains why its update comparison would trigger replacement. i derived that decision from the code; i didn't run the updater. the separate replacement review is retained under deeper-review/replacement-loader/.

i acquired the offered replacement as bytes and verified its advertised MD5. its managed network and updater bodies match the supplied loader after metadata-token normalization. it still injects using -devserver akatsuki.gg, waits for the runtime/auth module and loads the downloaded patcher. its added process enumeration checks desktop-user tokens for an unelevated launch. those routines add no network call. the exact anchors are retained in deeper-review/replacement-loader/report.md.

score reporting in the downloaded payload#

the DLL's required Submission feature hooks AddParameter. when the name is fs, it substitutes a Base64 envelope containing an AES-encrypted JSON report. that JSON includes visible window titles, executable paths and executable hashes for other processes, plus method-integrity and heuristic detections. i recovered the request-modification path statically. i haven't captured a live POST.

the intended carrier is the game's existing score request. public route registration accepts POST /web/osu-submit-modular-selector.php. i haven't captured the exact live URL, transport or submitted bytes. i found no separate fixed telemetry host in the main patcher, and assist.games is a detection label in this path. the review of thirteen embedded managed libraries found no extra reporter. public server code supports an internal queue handoff, but downstream processing, storage, access and retention remain unknown. the technical report covers that evidence and its limits.

akatsuki's patcher page links the download to this service host. that supports its advertised role. it doesn't authenticate my supplied file's exact hash or guarantee what a later service response contains.

artifact and code anchors#

  • Original: local-input/akatsuki_patcher.exe, 1,378,202 bytes, SHA-256 87f8dadbe18cac959194dfb173eea9f1076cc8943279cb018e40b25073193002.
  • The outer PE is a Windows x86 .NET apphost. Its version-6 single-file bundle contains Akatsuki.Loader.dll and two JSON configuration files. Static extraction used the Microsoft bundle layout and file entry format.
  • Extracted assembly SHA-256: b2e738596763639c8c80d27f19aae775b3f7f351b617655d179051f8052efea0; x86 CIL, .NET 6.0, assembly name Akatsuki.Loader, version 1.0.0.0.
  • Startup URL: <Connect>d__13.MoveNext, method token 0x0600004e, IL_0031; GetFromJsonAsync at IL_003f via MethodSpec 0x2b00000c -> MemberRef 0x0a000069.
  • Patcher URL: <PatcherRequest>d__4.MoveNext, token 0x06000052, IL_0032; branch concatenation at IL_003d, GetByteArrayAsync at IL_0042.
  • Dynamic update URL: <CheckUpdates>d__2.MoveNext, token 0x0600009e, get_DownloadUrl at IL_0099; <UpdateFromUrl>d__5.MoveNext, token 0x060000a0, GetAsync at IL_001c.
  • osu! launch argument: Akatsuki.Loader.Injector.Inject, token 0x06000032, IL_0073.
  • i inventoried 236 method declarations and 345 member references, checked the network and user-string references, and manually followed the three outbound request paths. the artifact inventory has partial member coverage overall; the decoded CIL instruction bodies weren't reported as partial or truncated. static inspection doesn't establish successful runtime traffic.

i retained the resource inventory, assembly details, decoded method bodies and native-call declarations under evidence/. the resolved call/string anchors are in cil-anchors.txt, resolved-methods.json and string-cross-references.json. these are the records behind the manual trace, with parsing outputs kept so the findings can be checked. the original executable bytes are unchanged.

about this copy#

i rewrote the prose on 12 october 2026 so it's easier to read alongside the post. the file hashes, method references and findings still refer to the 11 october review. the unedited source report is retained locally with SHA-256 290b8aa44de2fc7130bf624ba6ee0bf7daf1707200cc583ff37e535f0bbfa32c. local absolute paths are redacted, and temporary signed download queries are omitted. filenames for supporting local records are retained as references; they are not public download links.

supporting evidenceback to the investigation ↗