2 Commits

Author SHA1 Message Date
zhaoyilun
a9e692a574 feat: add in-process adapter research contract 2026-07-12 11:15:07 +08:00
zhaoyilun
a4242c12be docs: add offline b-route reverse decision 2026-07-12 02:36:59 +08:00
18 changed files with 3211 additions and 13 deletions

View File

@@ -0,0 +1,309 @@
# B-Route Bridge/IPC/Plugin Static Map
Date: 2026-07-12
## Scope
This report uses offline IL, binary string metadata, reflection metadata for `HttpServerLib.dll`, and returned live-probe JSON. It does not log in, open sockets, attach hooks, inject into a process, replay traffic, or mutate client binaries.
Machine-readable evidence: `runs/offline-broute-reverse/bridge-map.json`
Reflection metadata: `runs/offline-broute-reverse/httpserverlib-reflection.json`
## Recommendation
| Question | Answer |
| --- | --- |
| Should B-route pursue existing IPC/plugin before an in-process adapter? | **No** |
| Offline decision | `in_process_adapter_research` |
| External sidecar boundary | `external_sidecar_preview_only_until_bridge_exists` |
| Reason | Offline static evidence found no existing local IPC/plugin route that exposes send-message or send-file. HttpServerLib and plugin surfaces either require logged-in runtime state or are UI/framework-only; the named-pipe stub is empty. |
## Sources
### Text/IL sources
| Source | Role | Exists | Lines | Size bytes |
| --- | --- | --- | ---: | ---: |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il` | main client IL; login, plugin manager, local HTTP starter, chat/runtime | yes | 1360035 | 74148460 |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Common.dll.il` | common helpers; WinCommand, ProcessComm, DTOs | yes | 118343 | 5703293 |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ISphere.exe.il` | ISphere companion app IL; CEF and command helpers | yes | 81273 | 5679074 |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.UI.dll.il` | UI/browser support IL | yes | 242314 | 13545362 |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Service.dll.il` | file service implementation IL | yes | 3351 | 207786 |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il` | XMPP/socks5/network IL | yes | 87425 | 5019807 |
### Binary/string sources
| Source | Role | Exists | Strings | Size bytes |
| --- | --- | --- | ---: | ---: |
| `runs\offline-real-client-window\full\zyl\Impp\HttpServerLib.dll` | local HTTP server framework binary | yes | 555 | 26624 |
| `runs\offline-real-client-window\full\zyl\Impp\IMPlatformClient.Web.exe` | CEF/web helper process binary | yes | 185 | 9216 |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll` | native network abstraction | yes | 563 | 87552 |
| `runs\offline-real-client-window\full\zyl\Impp\IOClientNetwork.dll` | native network implementation | yes | 870 | 145920 |
| `runs\offline-real-client-window\full\zyl\Impp\IMPlatformClient.exe` | main client binary | yes | 76877 | 8366592 |
## Candidate classification
| Candidate | Category | Classification | Usable for B-route send | Recommendation | Matches |
| --- | --- | --- | --- | --- | ---: |
| `frmLogin.StartWinServer / HttpServerLib.HttpService` | `localhost_http` | `requires_logged_in_process` | no | `do_not_pursue_before_in_process_adapter` | 31 |
| `HttpServerLib route/module framework` | `localhost_http` | `static_only_unknown` | no | `no_existing_ipc_first` | 8 |
| `PluginLightAppMulProcessCommunication NamedPipeServerStream` | `named_pipe` | `not_a_bridge` | no | `do_not_use` | 17 |
| `IMPP.Common.Helper.ProcessComm WM_COPYDATA helper` | `window_message` | `static_only_unknown` | no | `not_a_send_bridge` | 164 |
| `PluginManager / IMPlugin command surface` | `plugin` | `requires_logged_in_process` | no | `plugin_extension_not_first` | 2696 |
| `IMPlatformClient.Web / CEF helper` | `child_process` | `requires_logged_in_process` | no | `preview_only_not_send` | 343 |
| `INetwork / IOClientNetwork native stack` | `native_network` | `not_a_bridge` | no | `do_not_pursue_as_ipc` | 72 |
| `returned live-probe named pipe inventory` | `named_pipe` | `static_only_unknown` | no | `do_not_assume_isphere_api` | 49 |
| `local TcpListener candidates` | `tcp_listener` | `not_a_bridge` | no | `not_existing_ipc` | 145 |
## Verified facts
- `frmLogin.StartWinServer` constructs `HTTPServerLib.HttpService` on `0.0.0.0` and starts `HttpServer.Start` in a thread, but it depends on `IMPPManager.UserInfo` and `ServiceManager.UnifiedAuthentication` state.
- `HttpServerLib.dll` exposes route/module primitives such as `HttpService.RegisterModule`, `ServiceModule`, `ServiceRoute`, `RouteAttribute`, `OnGet`, and `OnPost`.
- Main client IL does not show a concrete `RegisterModule` call or send-message/send-file HTTP route registration.
- `PluginLightAppMulProcessCommunication` declares a `NamedPipeServerStream` field, but `StartLightAppMultProssCommunication` returns immediately.
- Returned live probe showed one remote TCP connection to port `10088` and a named pipe `\\.\\pipe\\zfpinject-msg-server`; neither proves an iSphere send API.
- `PluginManager`/`IMPlugin` evidence is UI/app-store/context-menu oriented; no local assembly-load plugin bridge or send route was confirmed.
## Candidate evidence
### frmLogin.StartWinServer / HttpServerLib.HttpService
Classification: `requires_logged_in_process`; usable for B-route send: `False`; matches: 31.
Reason: Static IL builds a local HTTP service from logged-in user/auth state, but no send route or active live local listener was confirmed.
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:223` | `reference` | `.assembly extern HttpServerLib` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:888716` | `reference` | `RepairDatabase() cil managed` | `L888715: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:888818` | `string_literal` | `IL_00f8: ldstr "{0}/ifim/messageAuth\?version={1}&user={2}&resource"` | `L888715: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:888944` | `string_literal` | `IL_0287: ldstr "RepairDatabase.exe"` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:889041` | `method_end` | `} // end of method frmLogin::RepairDatabase` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:889166` | `callsite` | `IL_004d: call instance void IMPP.Client.frmLogin::RepairDatabase()` | `L889120: .method private hidebysig instance bool` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:889253` | `signature_continuation` | `StartWinServer() cil managed` | `L889252: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:889272` | `reference` | `class [HttpServerLib]HTTPServerLib.HttpService V_15,` | `L889252: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:889518` | `callsite` | `IL_0276: call instance int32 IMPP.Client.frmLogin::GetFreePort(int32[])` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:889551` | `string_literal` | `IL_02d3: ldstr "0.0.0.0"` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:889554` | `constructor_call` | `IL_02dc: newobj instance void [HttpServerLib]HTTPServerLib.HttpService::.ctor(string,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:889559` | `reference` | `IL_02e5: ldftn instance void [HttpServerLib]HTTPServerLib.HttpServer::Start()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:889677` | `method_end` | `} // end of method frmLogin::StartWinServer` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:889680` | `signature_continuation` | `GetFreePort(int32[] portArray) cil managed` | `L889679: .method private hidebysig instance int32` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:889798` | `method_end` | `} // end of method frmLogin::GetFreePort` | `L889679: .method private hidebysig instance int32` |
| `runs\offline-broute-reverse\httpserverlib-reflection.json` | `reflection_metadata` | `HttpServerLib reflection exposes matching types/methods; see httpserverlib-reflection.json` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\HttpServerLib.dll#str10` | `binary_string` | `HttpServerLib.dll` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\HttpServerLib.dll#str12` | `binary_string` | `HTTPServerLib` | `` |
### HttpServerLib route/module framework
Classification: `static_only_unknown`; usable for B-route send: `False`; matches: 8.
Reason: HttpServerLib has ServiceModule/RouteAttribute primitives, but client IL does not show RegisterModule or send-message routes.
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-broute-reverse\httpserverlib-reflection.json` | `reflection_metadata` | `HttpServerLib reflection exposes matching types/methods; see httpserverlib-reflection.json` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\HttpServerLib.dll#str21` | `binary_string` | `RouteAttribute` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\HttpServerLib.dll#str22` | `binary_string` | `RouteMethod` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\HttpServerLib.dll#str23` | `binary_string` | `ServiceModule` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\HttpServerLib.dll#str24` | `binary_string` | `ServiceRoute` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\HttpServerLib.dll#str292` | `binary_string` | `RegisterModule` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\HttpServerLib.dll#str302` | `binary_string` | `SearchRoute` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\HttpServerLib.dll#str303` | `binary_string` | `ExecuteRoute` | `` |
### PluginLightAppMulProcessCommunication NamedPipeServerStream
Classification: `not_a_bridge`; usable for B-route send: `False`; matches: 17.
Reason: A NamedPipeServerStream field exists, but StartLightAppMultProssCommunication has a one-instruction ret body.
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9039` | `type_definition` | `.class private auto ansi beforefieldinit IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication` | `L9012: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9042` | `reference` | `.field private static class IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication _instance` | `L9012: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9043` | `reference` | `.field private class [System.Core]System.IO.Pipes.NamedPipeServerStream _pipeServer` | `L9012: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9052` | `method_end` | `} // end of method PluginLightAppMulProcessCommunication::.ctor` | `L9044: .method private hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9058` | `constructor_call` | `IL_0000: newobj instance void IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication::.ctor()` | `L9054: .method public hidebysig static void Init() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9059` | `reference` | `IL_0005: stsfld class IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication::_instance` | `L9054: .method public hidebysig static void Init() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9060` | `reference` | `IL_000a: ldsfld class IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication::_instance` | `L9054: .method public hidebysig static void Init() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9061` | `callsite` | `IL_000f: callvirt instance void IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication::StartLightAppMultProssCommunication()` | `L9054: .method public hidebysig static void Init() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9063` | `method_end` | `} // end of method PluginLightAppMulProcessCommunication::Init` | `L9054: .method public hidebysig static void Init() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9066` | `reference` | `StartLightAppMultProssCommunication() cil managed` | `L9065: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9071` | `method_end` | `} // end of method PluginLightAppMulProcessCommunication::StartLightAppMultProssCommunication` | `L9065: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9079` | `method_end` | `} // end of method PluginLightAppMulProcessCommunication::.cctor` | `L9073: .method private hidebysig specialname rtspecialname static` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9081` | `reference` | `} // end of class IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication` | `L9073: .method private hidebysig specialname rtspecialname static` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:217833` | `callsite` | `IL_0071: call void IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication::Init()` | `L217793: .method private hidebysig specialname rtspecialname` |
| `runs\offline-real-client-window\full\zyl\Impp\IMPlatformClient.exe#str2852` | `binary_string` | `NamedPipeServerStream` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\IMPlatformClient.exe#str6922` | `binary_string` | `PluginLightAppMulProcessCommunication` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\IMPlatformClient.exe#str8523` | `binary_string` | `StartLightAppMultProssCommunication` | `` |
### IMPP.Common.Helper.ProcessComm WM_COPYDATA helper
Classification: `static_only_unknown`; usable for B-route send: `False`; matches: 164.
Reason: ProcessComm can send WM_COPYDATA to a foreground or titled window, but no receive handler or send-command contract is confirmed.
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:271124` | `reference` | `native int GetForegroundWindow() cil managed preservesig` | `L271123: .method public hidebysig static pinvokeimpl("user32.dll" winapi)` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:278221` | `type_definition` | `.class sequential ansi sealed nested private beforefieldinit COPYDATASTRUCT` | `L278204: .method private hidebysig static object` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:278227` | `reference` | `} // end of class COPYDATASTRUCT` | `L278204: .method private hidebysig static object` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:279144` | `reference` | `.field private static literal int32 WM_COPYDATA = int32(0x0000004A)` | `L279026: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:282985` | `reference` | `int32 FindWindow(string lpClassName,` | `L282984: .method private hidebysig static pinvokeimpl("user32.dll" winapi)` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:317869` | `callsite` | `IL_3827: call native int IMPP.Client.utils.Utils::GetForegroundWindow()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:412102` | `callsite` | `IL_3613: call native int IMPP.Client.utils.Utils::GetForegroundWindow()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:543733` | `reference` | `.field public static literal int32 WM_COPYDATA = int32(0x0000004A)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:660716` | `reference` | `.locals init (valuetype IMPP.Client.Business.Logon.Native/COPYDATASTRUCT V_0,` | `L660712: .method public hidebysig static bool DefWndProc(valuetype [System.Windows.Forms]System.Windows.Forms.Message& m) cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:660731` | `reference` | `valuetype IMPP.Client.Business.Logon.Native/COPYDATASTRUCT V_15,` | `L660712: .method public hidebysig static bool DefWndProc(valuetype [System.Windows.Forms]System.Windows.Forms.Message& m) cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:660735` | `reference` | `valuetype IMPP.Client.Business.Logon.Native/COPYDATASTRUCT V_19,` | `L660712: .method public hidebysig static bool DefWndProc(valuetype [System.Windows.Forms]System.Windows.Forms.Message& m) cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:660746` | `reference` | `valuetype IMPP.Client.Business.Logon.Native/COPYDATASTRUCT V_30,` | `L660712: .method public hidebysig static bool DefWndProc(valuetype [System.Windows.Forms]System.Windows.Forms.Message& m) cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:661348` | `reference` | `IL_06b6: initobj IMPP.Client.Business.Logon.Native/COPYDATASTRUCT` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:661350` | `reference` | `IL_06bd: ldtoken IMPP.Client.Business.Logon.Native/COPYDATASTRUCT` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:661353` | `reference` | `IL_06cc: unbox.any IMPP.Client.Business.Logon.Native/COPYDATASTRUCT` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:661356` | `reference` | `IL_06d5: ldfld int32 IMPP.Client.Business.Logon.Native/COPYDATASTRUCT::cbData` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:661360` | `reference` | `IL_06e3: ldfld native int IMPP.Client.Business.Logon.Native/COPYDATASTRUCT::lpData` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:661446` | `reference` | `IL_07e8: stfld native int IMPP.Client.Business.Logon.Native/COPYDATASTRUCT::dwData` | `` |
### PluginManager / IMPlugin command surface
Classification: `requires_logged_in_process`; usable for B-route send: `False`; matches: 2696.
Reason: Plugin evidence is UI/app-store/context-menu oriented and depends on logged-in PluginManager state; no Assembly.Load/LoadFrom or send API bridge was confirmed.
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1048` | `reference` | `.mresource public IMPP.Client.Core.Plugins.Manager.FrmAppStore.resources` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1051` | `reference` | `// 警告: 创建了托管资源文件 IMPP.Client.Core.Plugins.Manager.FrmAppStore.resources` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1063` | `reference` | `.mresource public IMPP.Client.Core.Plugins.Manager.WindowForm.FrmCefHomePage.resources` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1066` | `reference` | `// 警告: 创建了托管资源文件 IMPP.Client.Core.Plugins.Manager.WindowForm.FrmCefHomePage.resources` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:82622` | `callsite` | `IL_0156: call class IMPP.Client.Core.Plugins.Manager.PluginManager IMPP.Client.Core.Plugins.Manager.PluginManager::GetInstance()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:82623` | `callsite` | `IL_015b: callvirt instance class [mscorlib]System.Collections.Generic.List`1<class IMPP.Client.Core.Plugins.Manager.IMPlugin> IMPP.Client.Core.Plugins.Manager.PluginManager::GetPluginList()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:85884` | `callsite` | `IL_0157: call class IMPP.Client.Core.Plugins.Manager.PluginManager IMPP.Client.Core.Plugins.Manager.PluginManager::GetInstance()` | `L85783: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:85890` | `callsite` | `IL_0168: callvirt instance void IMPP.Client.Core.Plugins.Manager.PluginManager::add_PluginMessageNotify(class [IMPP.Interface]IMPP.Interface.PluginMessageEventHandler)` | `L85783: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:88002` | `callsite` | `IL_045d: call class IMPP.Client.Core.Plugins.Manager.PluginManager IMPP.Client.Core.Plugins.Manager.PluginManager::GetInstance()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:88007` | `callsite` | `IL_0470: callvirt instance void IMPP.Client.Core.Plugins.Manager.PluginManager::DoNotifyAction(string,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:90512` | `callsite` | `IL_0111: call void IMPP.Client.Core.Plugins.Manager.PluginUtils::LoadPluginContextMenu(class [System.Windows.Forms]System.Windows.Forms.ContextMenuStrip,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:90677` | `callsite` | `IL_016d: call void IMPP.Client.Core.Plugins.Manager.PluginUtils::LoadPluginContextMenu(class [System.Windows.Forms]System.Windows.Forms.ContextMenuStrip,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:91111` | `callsite` | `IL_00f8: call void IMPP.Client.Core.Plugins.Manager.PluginUtils::LoadPluginContextMenu(class [System.Windows.Forms]System.Windows.Forms.ContextMenuStrip,` | `L91000: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:91274` | `callsite` | `IL_00cb: call void IMPP.Client.Core.Plugins.Manager.PluginUtils::LoadPluginContextMenu(class [System.Windows.Forms]System.Windows.Forms.ContextMenuStrip,` | `L91188: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:105364` | `callsite` | `IL_03c1: callvirt instance string IMPP.Client.Core.Plugins.Manager.IMPlugin::get_Command()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:105401` | `callsite` | `IL_042d: call class IMPP.Client.Core.Plugins.Manager.PluginManager IMPP.Client.Core.Plugins.Manager.PluginManager::GetInstance()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:105402` | `callsite` | `IL_0432: callvirt instance class [mscorlib]System.Collections.Generic.List`1<class IMPP.Client.Core.Plugins.Manager.IMPlugin> IMPP.Client.Core.Plugins.Manager.PluginManager::GetPluginList()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:217227` | `reference` | `class IMPP.Client.Core.Plugins.Manager.PluginManager V_3,` | `L217219: .method public hidebysig newslot virtual final` |
### IMPlatformClient.Web / CEF helper
Classification: `requires_logged_in_process`; usable for B-route send: `False`; matches: 343.
Reason: The web helper/CEF surface exists, but static evidence points to UI/plugin browser support, not an external send/file API.
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:278553` | `reference` | `.field public static class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [IMPP.Cef4CSharp]IMPP.Cef4CSharp.Win.Wi...` | `L278527: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:300455` | `reference` | `IL_0428: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [IMPP.Cef4CSharp]IMPP.Cef4CSharp.Win.Wi...` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:300465` | `string_literal` | `IL_0442: ldstr "NavigateTo"` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:300492` | `callsite` | `IL_0477: call class [System.Core]System.Runtime.CompilerServices.CallSite`1<!0> class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.Compi...` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:300493` | `reference` | `IL_047c: stsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [IMPP.Cef4CSharp]IMPP.Cef4CSharp.Win.Wi...` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:300500` | `reference` | `IL_048f: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [IMPP.Cef4CSharp]IMPP.Cef4CSharp.Win.Wi...` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:300501` | `reference` | `IL_0494: ldfld !0 class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [IMPP.Cef4CSharp]IMPP.Cef4CSharp.Win...` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:300502` | `reference` | `IL_0499: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [IMPP.Cef4CSharp]IMPP.Cef4CSharp.Win.Wi...` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:300504` | `callsite` | `IL_04a0: callvirt instance class [IMPP.Cef4CSharp]IMPP.Cef4CSharp.Win.WinCefBrowser IMPP.Client.Core.Plugins.Manager.WindowForm.frmPluginTabCtrl::get_CefBrowser()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:300506` | `callsite` | `IL_04a6: callvirt instance void class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [IMPP.Cef4CSharp]IMPP.Cef4CSharp.Win.WinCefBrowser,object>::Invoke(!0,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:388726` | `reference` | `.field public static class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [IMPP.Cef4CSharp]IMPP.Cef4CSharp.Win.Wi...` | `L388681: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:413211` | `callsite` | `IL_0266: callvirt instance class [IMPP.Cef4CSharp]IMPP.Cef4CSharp.Win.WinCefBrowser IMPP.Client.Business.ISphereAssistant.frmExtendTabCtrl::get_CefBrowser()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:413215` | `callsite` | `IL_0277: callvirt instance void [IMPP.Cef4CSharp]IMPP.Cef4CSharp.Win.WinCefBrowser::NavigateTo(string)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:414754` | `reference` | `IL_0b96: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [IMPP.Cef4CSharp]IMPP.Cef4CSharp.Win.Wi...` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:414764` | `string_literal` | `IL_0bb0: ldstr "NavigateTo"` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:414791` | `callsite` | `IL_0be5: call class [System.Core]System.Runtime.CompilerServices.CallSite`1<!0> class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.Compi...` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:414792` | `reference` | `IL_0bea: stsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [IMPP.Cef4CSharp]IMPP.Cef4CSharp.Win.Wi...` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:414799` | `reference` | `IL_0bfd: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [IMPP.Cef4CSharp]IMPP.Cef4CSharp.Win.Wi...` | `` |
### INetwork / IOClientNetwork native stack
Classification: `not_a_bridge`; usable for B-route send: `False`; matches: 72.
Reason: Native NETIO send/recv symbols are low-level transport, not a local command bridge into logged-in chat objects.
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str249` | `binary_string` | `D:\work\me\sourcecode\app_project\Network_node\bin\release\INetwork.pdb` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str314` | `binary_string` | `INetwork.dll` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str317` | `binary_string` | `??0StreamClientBase@@QAE@ABV0@@Z` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str318` | `binary_string` | `??0StreamClientBase@@QAE@XZ` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str319` | `binary_string` | `??0StreamClientChannel@@QAE@ABV0@@Z` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str320` | `binary_string` | `??0StreamClientChannel@@QAE@XZ` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str321` | `binary_string` | `??0StreamClientFrameSink@@QAE@ABV0@@Z` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str322` | `binary_string` | `??0StreamClientFrameSink@@QAE@XZ` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str323` | `binary_string` | `??0StreamClientMsg@@QAE@ABV0@@Z` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str324` | `binary_string` | `??0StreamClientMsg@@QAE@XZ` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str325` | `binary_string` | `??0StreamClientMsgSink@@QAE@ABV0@@Z` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str326` | `binary_string` | `??0StreamClientMsgSink@@QAE@XZ` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str327` | `binary_string` | `??0StreamClientNetEventSink@@QAE@ABV0@@Z` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str328` | `binary_string` | `??0StreamClientNetEventSink@@QAE@XZ` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str329` | `binary_string` | `??0StreamClientRecverEventSink@@QAE@ABV0@@Z` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str330` | `binary_string` | `??0StreamClientRecverEventSink@@QAE@XZ` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str331` | `binary_string` | `??0StreamClientSenderEventSink@@QAE@ABV0@@Z` | `` |
| `runs\offline-real-client-window\full\zyl\Impp\INetwork.dll#str332` | `binary_string` | `??0StreamClientSenderEventSink@@QAE@XZ` | `` |
### returned live-probe named pipe inventory
Classification: `static_only_unknown`; usable for B-route send: `False`; matches: 49.
Reason: Live probe saw \\.\\pipe\\zfpinject-msg-server, but no matching iSphere static string or send contract was found in the configured samples.
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:905746` | `reference` | `frmMain_OnReConnectionSucceed(object sender,` | `L905745: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:905814` | `reference` | `IL_0081: ldftn void IMPP.Client.frmMain::'<frmMain_OnReConnectionSucceed>b__4'()` | `L905745: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:905828` | `method_end` | `} // end of method frmMain::frmMain_OnReConnectionSucceed` | `L905745: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:919019` | `reference` | `IL_006e: ldftn instance void IMPP.Client.frmMain::frmMain_OnReConnectionSucceed(object,` | `L918967: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:919023` | `callsite` | `IL_0079: callvirt instance void [smack]com.vision.smack.XMPPConnection::add_OnReConnectionSucceed(class [mscorlib]System.EventHandler)` | `L918967: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:928079` | `method_header` | `.method private hidebysig static void '<frmMain_OnReConnectionSucceed>b__4'() cil managed` | `L928079: .method private hidebysig static void '<frmMain_OnReConnectionSucceed>b__4'() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:928087` | `method_end` | `} // end of method frmMain::'<frmMain_OnReConnectionSucceed>b__4'` | `L928079: .method private hidebysig static void '<frmMain_OnReConnectionSucceed>b__4'() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1126866` | `reference` | `IL_00e2: ldftn instance void IMPP.Client.Business.ReConnection.WindowForm.FrmReConnection::OnReConnectionSucceed(object,` | `L1126773: .method private hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1126870` | `callsite` | `IL_00ed: callvirt instance void [smack]com.vision.smack.XMPPConnection::add_OnReConnectionSucceed(class [mscorlib]System.EventHandler)` | `L1126773: .method private hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1127782` | `reference` | `OnReConnectionSucceed(object sender,` | `L1127781: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1127841` | `reference` | `IL_0069: ldftn instance void IMPP.Client.Business.ReConnection.WindowForm.FrmReConnection::'<OnReConnectionSucceed>b__0'()` | `L1127781: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1127855` | `method_end` | `} // end of method FrmReConnection::OnReConnectionSucceed` | `L1127781: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1127979` | `reference` | `'<OnReConnectionSucceed>b__0'() cil managed` | `L1127978: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1127987` | `method_end` | `} // end of method FrmReConnection::'<OnReConnectionSucceed>b__0'` | `L1127978: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ISphere.exe.il:33510` | `reference` | `IL_00e2: ldftn instance void IMPP.ISphere.IMPPManage.FrmReConnection::OnReConnectionSucceed(object,` | `L33417: .method private hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ISphere.exe.il:33514` | `callsite` | `IL_00ed: callvirt instance void [smack]com.vision.smack.XMPPConnection::add_OnReConnectionSucceed(class [mscorlib]System.EventHandler)` | `L33417: .method private hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ISphere.exe.il:34155` | `reference` | `OnReConnectionSucceed(object sender,` | `L34154: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ISphere.exe.il:34182` | `reference` | `IL_0031: ldftn instance void IMPP.ISphere.IMPPManage.FrmReConnection::'<OnReConnectionSucceed>b__0'()` | `L34154: .method private hidebysig instance void` |
### local TcpListener candidates
Classification: `not_a_bridge`; usable for B-route send: `False`; matches: 145.
Reason: TcpListener evidence is tied to TCP file manage or smack socks5, not a command API for text/file send. Returned live probe had only one remote XMPP connection.
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:889833` | `callsite` | `IL_003c: callvirt instance class [System]System.Net.IPEndPoint[] [System]System.Net.NetworkInformation.IPGlobalProperties::GetActiveTcpListeners()` | `L889800: .method private hidebysig instance bool` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1117108` | `reference` | `.field private static class [System]System.Net.Sockets.TcpListener _listener` | `L1117034: .method public hidebysig instance bool` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1118022` | `reference` | `IL_0058: ldsfld class [System]System.Net.Sockets.TcpListener IMPP.Client.Business.TCPFileManage.TCPFileManager::_listener` | `L1117985: .method public hidebysig static class [System]System.Net.IPEndPoint` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1118096` | `reference` | `IL_011e: ldsfld class [System]System.Net.Sockets.TcpListener IMPP.Client.Business.TCPFileManage.TCPFileManager::_listener` | `L1117985: .method public hidebysig static class [System]System.Net.IPEndPoint` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1118097` | `callsite` | `IL_0123: callvirt instance class [System]System.Net.EndPoint [System]System.Net.Sockets.TcpListener::get_LocalEndpoint()` | `L1117985: .method public hidebysig static class [System]System.Net.IPEndPoint` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1118817` | `callsite` | `IL_0091: callvirt instance class [System]System.Net.IPEndPoint[] [System]System.Net.NetworkInformation.IPGlobalProperties::GetActiveTcpListeners()` | `L1118746: .method public hidebysig static int32 FindFreeTCPPort([opt] int32 startPort) cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1119636` | `reference` | `IL_0009: stsfld class [System]System.Net.Sockets.TcpListener IMPP.Client.Business.TCPFileManage.TCPFileManager::_listener` | `L1119622: .method private hidebysig specialname rtspecialname static` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:64917` | `reference` | `.field private class com.vision.smack.socks5.TCPSocks5Server '<Server>k__BackingField'` | `L64879: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:64926` | `signature_continuation` | `instance void .ctor(class com.vision.smack.socks5.TCPSocks5Server server,` | `L64925: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:64935` | `callsite` | `IL_0008: call instance void com.vision.smack.socks5.TCPSocks5Connection::set_Server(class com.vision.smack.socks5.TCPSocks5Server)` | `L64925: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:64942` | `method_header` | `.method private hidebysig specialname instance class com.vision.smack.socks5.TCPSocks5Server` | `L64942: .method private hidebysig specialname instance class com.vision.smack.socks5.TCPSocks5Server` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:64949` | `reference` | `IL_0001: ldfld class com.vision.smack.socks5.TCPSocks5Server com.vision.smack.socks5.TCPSocks5Connection::'<Server>k__BackingField'` | `L64942: .method private hidebysig specialname instance class com.vision.smack.socks5.TCPSocks5Server` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:64954` | `reference` | `set_Server(class com.vision.smack.socks5.TCPSocks5Server 'value') cil managed` | `L64953: .method private hidebysig specialname instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:64961` | `reference` | `IL_0002: stfld class com.vision.smack.socks5.TCPSocks5Server com.vision.smack.socks5.TCPSocks5Connection::'<Server>k__BackingField'` | `L64953: .method private hidebysig specialname instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:65018` | `callsite` | `IL_0001: call instance class com.vision.smack.socks5.TCPSocks5Server com.vision.smack.socks5.TCPSocks5Connection::get_Server()` | `L65012: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:65019` | `callsite` | `IL_0006: callvirt instance bool com.vision.smack.socks5.TCPSocks5Server::get_IsStarting()` | `L65012: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:65027` | `callsite` | `IL_0016: call instance class com.vision.smack.socks5.TCPSocks5Server com.vision.smack.socks5.TCPSocks5Connection::get_Server()` | `L65012: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:65028` | `callsite` | `IL_001b: callvirt instance bool com.vision.smack.socks5.TCPSocks5Server::get_RequireValidate()` | `L65012: .method private hidebysig instance void` |
## Decision
No existing IPC/plugin/local HTTP bridge is confirmed usable for B-route text send or file send. The next B-route branch should be `in_process_adapter_research`. Until that exists, an external sidecar can only do preview/probe work, while A-route/RPA remains backup-only.
## Next work
1. Update the B-route next plan and capability source matrix with `in_process_adapter_research` as the offline decision.
2. Create a separate plan before implementing any in-process adapter work.
3. Do not promote RPA beyond backup in this branch.

View File

@@ -0,0 +1,230 @@
# B-Route File Send Static Map
Date: 2026-07-12
## Scope
This report uses offline IL only. It does not upload files, send file messages, replay traffic, inject into a process, or mutate the original iSphere binaries.
Machine-readable evidence: `runs/offline-broute-reverse/file-send-map.json`
## Sources
| Source | Role | Exists | Lines | Size bytes |
| --- | --- | --- | ---: | ---: |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il` | main client IL; UC_FileSend, OffLineFileSend, MessageScheduling | yes | 1360035 | 74148460 |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Service.dll.il` | file transfer service implementation | yes | 3351 | 207786 |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il` | file transfer contracts, parameters, and result DTOs | yes | 1641 | 93585 |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Interface.dll.il` | transport/event interface contracts | yes | 4429 | 227335 |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il` | Chat.sendFileMessage and XMPP message construction | yes | 87425 | 5019807 |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\TcpFileTransfer.dll.il` | native TCP transfer candidate; IL may be unavailable | yes | 5 | 241 |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Model.dll.il` | chat record models if extracted | no | 0 | |
## Target classification
| Target | Phase | Intent | Classification | Matches |
| --- | --- | --- | --- | ---: |
| `IMPP.Client.OffLineFileSend.sendFile` | `upload` | offline file upload orchestration from UI file sender | `confirmed_signature` | 3 |
| `IMPP.Client.OffLineFileSend.trans_UploadCompleted` | `upload_to_message_boundary` | upload-completed handler that converts FileUploadResult.FileID into a chat file message | `confirmed_signature` | 3 |
| `IMPP.Service.BLL.FileTransfer.FileUpload` | `upload` | synchronous service upload entry returning FileUploadResult | `confirmed_signature` | 17 |
| `IMPP.Service.BLL.FileTransfer.AsynFileUpload` | `upload` | asynchronous upload queue entry | `confirmed_signature` | 3 |
| `FileUploadPara` | `upload_parameters` | host/port/domain/local file path/cache/timeout/upload flags | `confirmed_signature` | 66 |
| `FileUploadResult.FileID` | `upload_result` | server-side file id and URL returned by upload | `confirmed_signature` | 75 |
| `MessageScheduling.SendFileMessage` | `message` | scheduled/file-message finalization path using RosterContactsArgs and FileTransferArgs | `confirmed_signature` | 3 |
| `Chat.sendFileMessage` | `message` | smack API that sends the XMPP file message after upload metadata is known | `confirmed_signature` | 8 |
| `Required values: path id size target jid` | `requirements` | static evidence for local file path, remote folder/file id, file size/name, target JID/chat, and server auth | `confirmed_signature` | 550 |
## Upload step vs chat-message step
| Step | Static evidence | Business meaning |
| --- | --- | --- |
| 1. Upload | `IMPP.Client.OffLineFileSend.sendFile` constructs `FileUploadPara` and calls `IFileTransfer.FileUpload`; `IMPP.Service.BLL.FileTransfer.FileUpload` delegates to `SyncFileTransfer` and private `Upload`. | The local file must be uploaded to the HTTP file service first. |
| 2. Upload result | `FileUploadResult.FileID` is read; upload notification calls `IMPP.Client.OffLineFileSend.trans_UploadCompleted(fileId)`. | The server-issued file id becomes the durable reference. |
| 3. Chat file message | `trans_UploadCompleted` and `MessageScheduling.SendFileMessage` build `OFFLINE_FILE_TRANSFER;...` payloads and call `Chat.sendFileMessage`. | The chat send step publishes metadata/reference, not raw file bytes. |
Conclusion: file send is upload-first, chat-message-second. A direct chat message is insufficient without a valid uploaded file id or remote folder reference.
## Required values
| Value | Status | Evidence |
| --- | --- | --- |
| local file path | `required_confirmed` | OffLineFileSend constructor receives localFilePath; sendFile uses get__localFilePath; MessageScheduling.SendFileMessage uses FileTransferArgs.get_LocalFilePath. |
| server file id / remote folder | `required_confirmed` | Upload returns FileUploadResult.FileID; trans_UploadCompleted(fileId) passes it to Chat.sendFileMessage and Packet.set_id. MessageScheduling path uses FileTransferArgs.get_RemoteFolder. |
| file name and file size | `required_confirmed` | SendFileMessage builds OFFLINE_FILE_TRANSFER payload from FileInfo/FileSystemInfo name and length; OffLineFileSend keeps _fileSize. |
| target JID / chat object | `required_confirmed` | UC_FileSend and MessageScheduling both require a live smack Chat; scheduled path derives it from RosterContactsArgs.get_RosterJid + UtilsChat.GetChat. |
| HTTP file server and auth | `required_confirmed` | FileUploadPara construction uses Config.ServerInfo.HTTPFileServer IP/Port/domain; service upload builds /FS/auth/resource/upload URL with UnifiedAuthentication token/app key/client secret/time/user id. |
| file hash | `not_confirmed_in_file_send_path` | No file-transfer-path MD5/SHA/checksum requirement was confirmed in the configured IL. MD5 hits belong to image/RTF or auth digest areas, not the offline file-send path. |
## Evidence excerpts
### IMPP.Client.OffLineFileSend.sendFile
Classification: `confirmed_signature`; phase: `upload`; matches: 3.
| Source line | Kind | Snippet | Method context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:826149` | `signature_continuation` | `sendFile() cil managed` | `L826148: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:826572` | `method_end` | `} // end of method OffLineFileSend::sendFile` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:824164` | `callsite` | `IL_026b: callvirt instance void IMPP.Client.OffLineFileSend::sendFile()` | `` |
### IMPP.Client.OffLineFileSend.trans_UploadCompleted
Classification: `confirmed_signature`; phase: `upload_to_message_boundary`; matches: 3.
| Source line | Kind | Snippet | Method context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:826888` | `signature_continuation` | `trans_UploadCompleted(string fileId) cil managed` | `L826887: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:827241` | `method_end` | `} // end of method OffLineFileSend::trans_UploadCompleted` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:826670` | `callsite` | `IL_0104: call instance void IMPP.Client.OffLineFileSend::trans_UploadCompleted(string)` | `L826574: .method private hidebysig instance void` |
### IMPP.Service.BLL.FileTransfer.FileUpload
Classification: `confirmed_signature`; phase: `upload`; matches: 17.
| Source line | Kind | Snippet | Method context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Service.dll.il:851` | `signature_continuation` | `FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara para) cil managed` | `L849: .method public hidebysig newslot virtual final` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Service.dll.il:870` | `method_end` | `} // end of method FileTransfer::FileUpload` | `L849: .method public hidebysig newslot virtual final` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Service.dll.il:873` | `signature_continuation` | `instance void AsynFileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara para) cil managed` | `L872: .method public hidebysig newslot virtual final` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:164` | `method_end` | `} // end of method IFileTransfer::FileUpload` | `L160: .method public hidebysig newslot abstract virtual` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:512182` | `callsite` | `IL_01d9: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608800` | `callsite` | `IL_00b2: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara)` | `L608722: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608921` | `callsite` | `IL_00c5: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara)` | `L608836: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:679721` | `callsite` | `IL_00bf: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara)` | `L679642: .method public hidebysig static void UploadGroupImage(string jid,` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:699952` | `callsite` | `IL_024c: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:738959` | `callsite` | `IL_00bf: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara)` | `L738869: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:739560` | `callsite` | `IL_00bf: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara)` | `L739470: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:790010` | `callsite` | `IL_018b: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:826414` | `callsite` | `IL_02b6: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Service.dll.il:2852` | `reference` | `} // end of property FileTransfer::FileUploadMaxCount` | `L2825: .method family hidebysig newslot virtual` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Service.dll.il:2861` | `reference` | `} // end of property FileTransfer::FileUploadCount` | `L2825: .method family hidebysig newslot virtual` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:186` | `reference` | `} // end of property IFileTransfer::FileUploadMaxCount` | `L177: .method public hidebysig newslot abstract virtual` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:205` | `reference` | `} // end of property IFileTransfer::FileUploadCount` | `L177: .method public hidebysig newslot abstract virtual` |
### IMPP.Service.BLL.FileTransfer.AsynFileUpload
Classification: `confirmed_signature`; phase: `upload`; matches: 3.
| Source line | Kind | Snippet | Method context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Service.dll.il:873` | `signature_continuation` | `instance void AsynFileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara para) cil managed` | `L872: .method public hidebysig newslot virtual final` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Service.dll.il:883` | `method_end` | `} // end of method FileTransfer::AsynFileUpload` | `L872: .method public hidebysig newslot virtual final` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:169` | `method_end` | `} // end of method IFileTransfer::AsynFileUpload` | `L166: .method public hidebysig newslot abstract virtual` |
### FileUploadPara
Classification: `confirmed_signature`; phase: `upload_parameters`; matches: 66.
| Source line | Kind | Snippet | Method context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Service.dll.il:851` | `signature_continuation` | `FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara para) cil managed` | `L849: .method public hidebysig newslot virtual final` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Service.dll.il:873` | `signature_continuation` | `instance void AsynFileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara para) cil managed` | `L872: .method public hidebysig newslot virtual final` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:162` | `signature_continuation` | `FileUpload(class IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara para) cil managed` | `L160: .method public hidebysig newslot abstract virtual` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:167` | `signature_continuation` | `instance void AsynFileUpload(class IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara para) cil managed` | `L166: .method public hidebysig newslot abstract virtual` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:1139` | `type_definition` | `.class public auto ansi serializable beforefieldinit IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara` | `L1086: .method family hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:1155` | `method_end` | `} // end of method FileUploadPara::get_IsImg` | `L1146: .method public hidebysig specialname instance bool` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:1167` | `method_end` | `} // end of method FileUploadPara::set_IsImg` | `L1157: .method private hidebysig specialname instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:1178` | `method_end` | `} // end of method FileUploadPara::get_IsPublic` | `L1169: .method public hidebysig specialname instance bool` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:1190` | `method_end` | `} // end of method FileUploadPara::set_IsPublic` | `L1180: .method public hidebysig specialname instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:1234` | `method_end` | `} // end of method FileUploadPara::.ctor` | `L1192: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:1263` | `method_end` | `} // end of method FileUploadPara::.ctor` | `L1236: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:512182` | `callsite` | `IL_01d9: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:512459` | `constructor_call` | `IL_04a3: newobj instance void [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara::.ctor(string,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608787` | `constructor_call` | `IL_0092: newobj instance void [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara::.ctor(string,` | `L608722: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608795` | `callsite` | `IL_009c: callvirt instance void [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara::set_IsPublic(bool)` | `L608722: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608800` | `callsite` | `IL_00b2: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara)` | `L608722: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608908` | `constructor_call` | `IL_00a5: newobj instance void [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara::.ctor(string,` | `L608836: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608916` | `callsite` | `IL_00af: callvirt instance void [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara::set_IsPublic(bool)` | `L608836: .method private hidebysig instance void` |
### FileUploadResult.FileID
Classification: `confirmed_signature`; phase: `upload_result`; matches: 75.
| Source line | Kind | Snippet | Method context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Service.dll.il:982` | `method_header` | `.method private hidebysig instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult` | `L982: .method private hidebysig instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:1277` | `type_definition` | `.class public auto ansi serializable beforefieldinit IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult` | `L1236: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:1307` | `method_end` | `} // end of method FileUploadResult::.ctor` | `L1284: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:1318` | `method_end` | `} // end of method FileUploadResult::get_FileID` | `L1309: .method public hidebysig specialname instance string` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:1330` | `method_end` | `} // end of method FileUploadResult::set_FileID` | `L1320: .method private hidebysig specialname instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:1341` | `method_end` | `} // end of method FileUploadResult::get_Url` | `L1332: .method public hidebysig specialname instance string` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:1353` | `method_end` | `} // end of method FileUploadResult::set_Url` | `L1343: .method private hidebysig specialname instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:512182` | `callsite` | `IL_01d9: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:512315` | `callsite` | `IL_0322: callvirt instance string [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult::get_FileID()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608800` | `callsite` | `IL_00b2: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara)` | `L608722: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608819` | `callsite` | `IL_00e0: callvirt instance string [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult::get_FileID()` | `L608722: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608921` | `callsite` | `IL_00c5: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara)` | `L608836: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608940` | `callsite` | `IL_00f3: callvirt instance string [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult::get_FileID()` | `L608836: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:679721` | `callsite` | `IL_00bf: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara)` | `L679642: .method public hidebysig static void UploadGroupImage(string jid,` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:679747` | `callsite` | `IL_00f4: callvirt instance string [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult::get_FileID()` | `L679642: .method public hidebysig static void UploadGroupImage(string jid,` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:699952` | `callsite` | `IL_024c: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:699993` | `callsite` | `IL_02bf: callvirt instance string [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult::get_FileID()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:738959` | `callsite` | `IL_00bf: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara)` | `L738869: .method private hidebysig instance void` |
### MessageScheduling.SendFileMessage
Classification: `confirmed_signature`; phase: `message`; matches: 3.
| Source line | Kind | Snippet | Method context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1153803` | `signature_continuation` | `SendFileMessage(class IMPP.Client.Business.RosterContacts.RosterContactsArgs rosterArgs,` | `L1153802: .method public hidebysig static class [smack]com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1154125` | `method_end` | `} // end of method MessageScheduling::SendFileMessage` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:728711` | `callsite` | `IL_01fb: call class [smack]com.vision.smack.packet.XmppMessage IMPP.Client.Core.MessageEngine.MessageScheduling::SendFileMessage(class IMPP.Client.Business.RosterContacts.RosterContactsArgs,` | `` |
### Chat.sendFileMessage
Classification: `confirmed_signature`; phase: `message`; matches: 8.
| Source line | Kind | Snippet | Method context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:1235` | `signature_continuation` | `sendFileMessage(string p_message,` | `L1233: .method public hidebysig newslot abstract virtual` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:1244` | `method_end` | `} // end of method Chat::sendFileMessage` | `L1233: .method public hidebysig newslot abstract virtual` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:21442` | `signature_continuation` | `sendFileMessage(string p_message,` | `L21441: .method public hidebysig virtual instance class com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:21490` | `method_end` | `} // end of method P2PChat::sendFileMessage` | `L21441: .method public hidebysig virtual instance class com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:30070` | `signature_continuation` | `sendFileMessage(string p_message,` | `L30069: .method public hidebysig virtual instance class com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:30119` | `method_end` | `} // end of method ChatRoom::sendFileMessage` | `L30069: .method public hidebysig virtual instance class com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:827225` | `callsite` | `IL_034d: callvirt instance class [smack]com.vision.smack.packet.XmppMessage [smack]com.vision.smack.Chat::sendFileMessage(string,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1153922` | `callsite` | `IL_00f1: callvirt instance class [smack]com.vision.smack.packet.XmppMessage [smack]com.vision.smack.Chat::sendFileMessage(string,` | `L1153802: .method public hidebysig static class [smack]com.vision.smack.packet.XmppMessage` |
### Required values: path id size target jid
Classification: `confirmed_signature`; phase: `requirements`; matches: 550.
| Source line | Kind | Snippet | Method context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:611789` | `method_end` | `} // end of method RosterContactsArgs::get_RosterJid` | `L611780: .method public hidebysig specialname instance class [smack]com.vision.smack.Jid` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:670956` | `type_definition` | `.class public auto ansi beforefieldinit IMPP.Client.Business.Authentication.UnifiedAuthenticationCenter` | `L670876: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:671260` | `method_end` | `} // end of method UnifiedAuthenticationCenter::Authentication` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:671331` | `method_end` | `} // end of method UnifiedAuthenticationCenter::GetServerTimeSpan` | `L671262: .method public hidebysig instance valuetype [mscorlib]System.TimeSpan` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:671390` | `method_end` | `} // end of method UnifiedAuthenticationCenter::ConvertStringToDateTime` | `L671333: .method private hidebysig instance valuetype [mscorlib]System.DateTime` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:671406` | `method_end` | `} // end of method UnifiedAuthenticationCenter::InitServiceManager` | `L671392: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:671416` | `method_end` | `} // end of method UnifiedAuthenticationCenter::.ctor` | `L671408: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:723604` | `method_end` | `} // end of method FileTransferArgs::get_LocalFilePath` | `L723595: .method public hidebysig specialname instance string` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:723650` | `method_end` | `} // end of method FileTransferArgs::get_RemoteFolder` | `L723641: .method public hidebysig specialname instance string` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:723876` | `method_end` | `} // end of method RosterContactsGroupArgs::get_RosterJid` | `L723867: .method public hidebysig specialname instance class [smack]com.vision.smack.Jid` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:767951` | `method_end` | `} // end of method ServerInfo::set_HTTPFileServer` | `L767941: .method public hidebysig specialname instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:767962` | `method_end` | `} // end of method ServerInfo::get_HTTPFileServer` | `L767953: .method public hidebysig specialname instance class IMPP.Client.Server` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:768272` | `method_end` | `} // end of method BaseConfig::UnifiedAuthenticationAddress` | `L768241: .method public hidebysig instance string` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:826017` | `method_end` | `} // end of method OffLineFileSend::get__localFilePath` | `L826008: .method private hidebysig specialname instance string` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:826109` | `method_end` | `} // end of method OffLineFileSend::get__fileSize` | `L826100: .method private hidebysig specialname instance int64` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1339551` | `method_end` | `} // end of method OffLineFileRecv::get__fileSize` | `L1339542: .method private hidebysig specialname instance int64` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il:477` | `method_end` | `} // end of method FileTransferParaBase::get_LocalFilePath` | `L468: .method public hidebysig specialname instance string` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:13688` | `callsite` | `IL_0179: callvirt instance class [smack]com.vision.smack.Chat [smack]com.vision.smack.ChatManager::GetChat(class [smack]com.vision.smack.XMPPConnection,` | `` |
## Inference
- High confidence: upload and file-message finalization are separate steps.
- High confidence: `FileUploadPara` needs HTTP file server host/port/domain plus local file path and upload options.
- High confidence: `Chat.sendFileMessage` produces the XMPP file-message envelope after file metadata is available.
- Medium confidence: B-route file send must either call the same logged-in service/runtime or reproduce the authenticated HTTP upload plus XMPP file-message sequence.
- Low confidence until bridge evidence: an external sidecar can obtain the same service/auth/chat objects without being inside the logged-in client process.
## Decision
Offline static evidence supports B-route research, but file sending needs more than one method call: upload first, then chat file-message finalization. The next blocker is reachability: whether an IPC/plugin/in-process bridge can access the logged-in `IFileTransfer` service and smack `Chat` object.
## Next work
1. Extract bridge/IPC/plugin candidates before coding any file-send adapter.
2. If a bridge exists, prototype non-mutating discovery first: service availability, chat object lookup, and upload endpoint metadata only.
3. Keep A-route/RPA backup-only.

View File

@@ -0,0 +1,149 @@
# B-Route Text Send Static Map
Date: 2026-07-12
## Scope
This report uses offline IL only. It does not log in, send messages, replay traffic, inject into a process, or mutate the original iSphere binaries.
Machine-readable evidence: `runs/offline-broute-reverse/text-send-map.json`
## Sources
| Source | Role | Exists | Lines | Size bytes |
| --- | --- | --- | ---: | ---: |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il` | main managed client IL; chat UI, AppContextManager, scheduling call sites | yes | 1360035 | 74148460 |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il` | XMPP/smack managed IL; Chat and XMPPConnection implementation | yes | 87425 | 5019807 |
## Target classification
| Target | Intent | Classification | Matches |
| --- | --- | --- | ---: |
| `AppContextManager.SendTxtMessageByJid` | high-level text send entry exposed by AppContextManager | `confirmed_signature` | 4 |
| `MessageScheduling.SendChatMessage` | message scheduling text/chat send helper | `confirmed_signature` | 6 |
| `Chat.SendMessage` | smack Chat send API used by chat/UI code | `confirmed_signature` | 16 |
| `XMPPConnection.send` | lowest-level XMPP connection send primitive | `confirmed_signature` | 105 |
| `MessageCenter send-related callbacks` | MessageCenter or IMPPManager message-center callbacks touching send/message flow | `confirmed_signature` | 962 |
## Verified facts
- `AppContextManager.SendTxtMessageByJid` appears in the offline client IL and is not just a UIA/RPA artifact.
- `MessageScheduling.SendChatMessage` appears in the offline client IL and has call-site evidence around chat-message flow.
- `Chat.SendMessage` / `Chat.sendMessage` appears as a smack chat API used by client code.
- `XMPPConnection.send` appears as a lower-level connection send primitive in offline IL.
- `MessageCenter send-related callbacks` appear as MessageCenter/GetMessageCenter references, but offline static evidence alone does not prove an external bridge can call them.
## Evidence excerpts
### AppContextManager.SendTxtMessageByJid
Classification: `confirmed_signature`; matches: 4.
| Source line | Kind | Snippet | Method context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:585987` | `signature_continuation` | `instance void SendTxtMessageByJid(string jid,` | `L585986: .method public hidebysig newslot virtual final` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:586197` | `method_end` | `} // end of method AppContextManager::SendTxtMessageByJid` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:542112` | `string_literal` | `IL_09bf: ldstr "SendTxtMessageByJid"` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1358068` | `string_literal` | `IL_0c3f: ldstr "SendTxtMessageByJid"` | `` |
### MessageScheduling.SendChatMessage
Classification: `confirmed_signature`; matches: 6.
| Source line | Kind | Snippet | Method context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1153800` | `method_end` | `} // end of method MessageScheduling::SendChatMessage` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1154225` | `method_end` | `} // end of method MessageScheduling::SendChatMessage` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:728720` | `callsite` | `IL_0213: call class [smack]com.vision.smack.packet.XmppMessage IMPP.Client.Core.MessageEngine.MessageScheduling::SendChatMessage(class IMPP.Client.Business.RosterContacts.RosterContactsArgs,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1154187` | `callsite` | `IL_006e: call class [smack]com.vision.smack.packet.XmppMessage IMPP.Client.Core.MessageEngine.MessageScheduling::SendChatMessage(class [smack]com.vision.smack.Chat,` | `L1154127: .method public hidebysig static class [smack]com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1153541` | `reference` | `SendChatMessage(class [smack]com.vision.smack.Chat chat,` | `L1153540: .method public hidebysig static class [smack]com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1154128` | `reference` | `SendChatMessage(class IMPP.Client.Business.RosterContacts.RosterContactsArgs rosterArgs,` | `L1154127: .method public hidebysig static class [smack]com.vision.smack.packet.XmppMessage` |
### Chat.SendMessage
Classification: `confirmed_signature`; matches: 16.
| Source line | Kind | Snippet | Method context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:1220` | `method_end` | `} // end of method Chat::sendMessage` | `L1217: .method public hidebysig newslot abstract virtual` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:1231` | `method_end` | `} // end of method Chat::sendMessage` | `L1222: .method public hidebysig newslot abstract virtual` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:1425` | `method_end` | `} // end of method Chat::SendMessage` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:1266` | `callsite` | `IL_0021: call instance class com.vision.smack.packet.XmppMessage com.vision.smack.Chat::SendMessage(class com.vision.smack.packet.XmppMessage)` | `L1246: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:21393` | `callsite` | `IL_0047: call instance class com.vision.smack.packet.XmppMessage com.vision.smack.Chat::SendMessage(class com.vision.smack.packet.XmppMessage)` | `L21362: .method public hidebysig virtual instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:21431` | `callsite` | `IL_002b: call instance class com.vision.smack.packet.XmppMessage com.vision.smack.Chat::SendMessage(class com.vision.smack.packet.XmppMessage)` | `L21398: .method public hidebysig virtual instance class com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:21482` | `callsite` | `IL_003a: call instance class com.vision.smack.packet.XmppMessage com.vision.smack.Chat::SendMessage(class com.vision.smack.packet.XmppMessage)` | `L21441: .method public hidebysig virtual instance class com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:29958` | `callsite` | `IL_0047: call instance class com.vision.smack.packet.XmppMessage com.vision.smack.Chat::SendMessage(class com.vision.smack.packet.XmppMessage)` | `L29927: .method public hidebysig virtual instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:30063` | `callsite` | `IL_0064: call instance class com.vision.smack.packet.XmppMessage com.vision.smack.Chat::SendMessage(class com.vision.smack.packet.XmppMessage)` | `L30012: .method public hidebysig virtual instance class com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:30115` | `callsite` | `IL_0056: call instance class com.vision.smack.packet.XmppMessage com.vision.smack.Chat::SendMessage(class com.vision.smack.packet.XmppMessage)` | `L30069: .method public hidebysig virtual instance class com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:299997` | `callsite` | `IL_0096: callvirt instance class [smack]com.vision.smack.packet.XmppMessage [smack]com.vision.smack.Chat::SendMessage(class [smack]com.vision.smack.packet.XmppMessage)` | `L299937: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:412929` | `callsite` | `IL_00d2: callvirt instance class [smack]com.vision.smack.packet.XmppMessage [smack]com.vision.smack.Chat::SendMessage(class [smack]com.vision.smack.packet.XmppMessage)` | `L412858: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:430535` | `callsite` | `IL_0357: callvirt instance class [smack]com.vision.smack.packet.XmppMessage [smack]com.vision.smack.Chat::SendMessage(class [smack]com.vision.smack.packet.XmppMessage)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:739211` | `callsite` | `IL_012c: callvirt instance class [smack]com.vision.smack.packet.XmppMessage [smack]com.vision.smack.Chat::sendMessage(string,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:739789` | `callsite` | `IL_012c: callvirt instance class [smack]com.vision.smack.packet.XmppMessage [smack]com.vision.smack.Chat::sendMessage(string,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1153743` | `callsite` | `IL_01d0: callvirt instance class [smack]com.vision.smack.packet.XmppMessage [smack]com.vision.smack.Chat::SendMessage(class [smack]com.vision.smack.packet.XmppMessage)` | `` |
### XMPPConnection.send
Classification: `confirmed_signature`; matches: 105.
| Source line | Kind | Snippet | Method context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:86319` | `method_end` | `} // end of method XMPPConnection::send` | `L86263: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:1378` | `callsite` | `IL_00bc: callvirt instance void com.vision.smack.XMPPConnection::send(string)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:17710` | `callsite` | `IL_004a: callvirt instance void com.vision.smack.XMPPConnection::send(string)` | `L17649: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:23187` | `callsite` | `IL_004b: callvirt instance void com.vision.smack.XMPPConnection::send(string)` | `L23150: .method public hidebysig instance class com.vision.smack.disco.DiscoInfoResponse` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:23248` | `callsite` | `IL_002c: callvirt instance void com.vision.smack.XMPPConnection::send(string)` | `L23220: .method public hidebysig virtual instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:23962` | `callsite` | `IL_0110: callvirt instance void com.vision.smack.XMPPConnection::send(string)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:26786` | `callsite` | `IL_004e: callvirt instance void com.vision.smack.XMPPConnection::send(string)` | `L26752: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:26855` | `callsite` | `IL_008b: callvirt instance void com.vision.smack.XMPPConnection::send(string)` | `L26790: .method public hidebysig instance class [mscorlib]System.Collections.Generic.IList`1<class com.vision.smack.muc.BookMarkConfenerce>` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:26980` | `callsite` | `IL_008a: callvirt instance void com.vision.smack.XMPPConnection::send(string)` | `L26919: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:29230` | `callsite` | `IL_00a2: callvirt instance void com.vision.smack.XMPPConnection::send(string)` | `L29148: .method public hidebysig instance bool` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:29470` | `callsite` | `IL_007d: callvirt instance void com.vision.smack.XMPPConnection::send(string)` | `L29404: .method public hidebysig instance bool` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:29690` | `callsite` | `IL_0053: callvirt instance void com.vision.smack.XMPPConnection::send(string)` | `L29646: .method public hidebysig instance bool` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:29841` | `callsite` | `IL_00b2: callvirt instance void com.vision.smack.XMPPConnection::send(string)` | `L29766: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:29918` | `callsite` | `IL_0033: callvirt instance void com.vision.smack.XMPPConnection::send(string)` | `L29894: .method public hidebysig virtual instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:30152` | `callsite` | `IL_003c: callvirt instance void com.vision.smack.XMPPConnection::send(string)` | `L30121: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:30178` | `callsite` | `IL_0023: callvirt instance void com.vision.smack.XMPPConnection::send(string)` | `L30159: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:30221` | `callsite` | `IL_0046: callvirt instance void com.vision.smack.XMPPConnection::send(string)` | `L30182: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:30268` | `callsite` | `IL_004d: callvirt instance void com.vision.smack.XMPPConnection::send(string)` | `L30225: .method public hidebysig instance void` |
### MessageCenter send-related callbacks
Classification: `confirmed_signature`; matches: 962.
| Source line | Kind | Snippet | Method context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:74199` | `method_end` | `} // end of method MessageCenter::add_OnMessageSended` | `L74135: .method public hidebysig specialname instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:74265` | `method_end` | `} // end of method MessageCenter::remove_OnMessageSended` | `L74201: .method public hidebysig specialname instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:75658` | `method_end` | `} // end of method MessageCenter::pChat_OnMessageSended` | `L75587: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:82645` | `method_end` | `} // end of method MessageCenter::SendPluginsOffLineMessage` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:206380` | `method_end` | `} // end of method AVRoomMessageCenter::Send` | `L206369: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:945209` | `method_header` | `.method public hidebysig instance class IMPP.Client.control.MessageCenter` | `L945209: .method public hidebysig instance class IMPP.Client.control.MessageCenter` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:945695` | `method_header` | `.method public hidebysig specialname instance class IMPP.Client.control.MessageCenter` | `L945695: .method public hidebysig specialname instance class IMPP.Client.control.MessageCenter` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:72786` | `callsite` | `IL_0005: callvirt instance class IMPP.Client.control.MessageCenter IMPP.Client.IMPPManager::GetMessageCenter()` | `L72779: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:72787` | `callsite` | `IL_000a: callvirt instance int32 IMPP.Client.control.MessageCenter::GetChatMessageCount()` | `L72779: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:72814` | `callsite` | `IL_000b: callvirt instance class IMPP.Client.control.MessageCenter IMPP.Client.IMPPManager::GetMessageCenter()` | `L72806: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:72820` | `callsite` | `IL_001c: callvirt instance void IMPP.Client.control.MessageCenter::add_OnMessageArrived(class IMPP.Client.control.MessageCenter/MessageArrivedHandler)` | `L72806: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:72822` | `callsite` | `IL_0026: callvirt instance class IMPP.Client.control.MessageCenter IMPP.Client.IMPPManager::GetMessageCenter()` | `L72806: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:72827` | `callsite` | `IL_0037: callvirt instance void IMPP.Client.control.MessageCenter::add_OnMessageConsumed(class IMPP.Client.control.MessageCenter/MessageConsumedHandler)` | `L72806: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:72829` | `callsite` | `IL_0041: callvirt instance class IMPP.Client.control.MessageCenter IMPP.Client.IMPPManager::GetMessageCenter()` | `L72806: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:72835` | `callsite` | `IL_0052: callvirt instance void IMPP.Client.control.MessageCenter::add_UpdateUnreadMessageCount(class IMPP.Client.control.MessageCenter/UpdateUnreadMessageCountHandler)` | `L72806: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:72837` | `callsite` | `IL_005c: callvirt instance class IMPP.Client.control.MessageCenter IMPP.Client.IMPPManager::GetMessageCenter()` | `L72806: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:72842` | `callsite` | `IL_006d: callvirt instance void IMPP.Client.control.MessageCenter::add_TcpFileToOffline(class [mscorlib]System.Action`1<class [smack]com.vision.smack.packet.XmppMessage>)` | `L72806: .method public hidebysig specialname rtspecialname` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:72844` | `callsite` | `IL_0077: callvirt instance class IMPP.Client.control.MessageCenter IMPP.Client.IMPPManager::GetMessageCenter()` | `L72806: .method public hidebysig specialname rtspecialname` |
## Inference
- High confidence: text sending has an internal managed call path that reaches smack chat/connection send APIs.
- Medium confidence: the likely chain is high-level AppContextManager or UI chat code -> MessageScheduling/frmP2PChat -> smack Chat.SendMessage/sendMessage -> XMPPConnection.send.
- Low confidence until live/runtime evidence: an external sidecar can invoke this path without being inside the logged-in process.
## Decision
B-route text send remains plausible only if a bridge can enter the logged-in runtime or an existing IPC/API exposes the same call. Offline IL confirms call shape, but not runtime invocability.
## Next work
1. Extract file-send/upload call graph and separate upload from chat-message finalization.
2. Extract bridge/IPC/plugin candidates to see whether the send call path is reachable without RPA.
3. Keep A-route/RPA as backup-only; do not promote it unless B-route bridge evidence fails.

View File

@@ -0,0 +1,277 @@
# In-Process Adapter Static Map
Date: 2026-07-12
## Scope
This report uses offline IL/static evidence only. It does not log in, attach hooks, inject into a process, modify client binaries, upload files, send messages, or open network connections.
Machine-readable evidence: `runs\inprocess-adapter-research\inprocess-adapter-map.json`
## Decision
| Question | Answer |
| --- | --- |
| Selected next B-route branch | managed_in_process_adapter_contract_first |
| Can offline branch enable production send? | **No** |
| Go connector mode to expose now | in_process_contract |
| Required online proof later | logged-in adapter reachability plus sent-record/content-hash/ack evidence |
## Sources
| Source | Role | Exists | Lines | Size bytes |
| --- | --- | --- | ---: | ---: |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il` | main managed client; UI, AppContextManager, MessageScheduling, frmMain, login runtime | True | 1360035 | 74148460 |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il` | XMPP/smack managed library; Chat and XMPPConnection send primitives | True | 87425 | 5019807 |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Service.dll.il` | file transfer service implementation | True | 3351 | 207786 |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.ServiceBase.dll.il` | file transfer DTOs and FileUploadPara/FileUploadResult contracts | True | 1641 | 93585 |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Interface.dll.il` | service and network interface contracts | True | 4429 | 227335 |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Common.dll.il` | common helper and runtime DTO evidence | True | 118343 | 5703293 |
## Command contract for future in-process adapter
| Op | Current status | Purpose | Required evidence before production |
| --- | --- | --- | --- |
| `probe_runtime` | `contract_only` | report whether adapter is inside logged-in IMPP runtime and can see required types/singletons | process identity; loaded assemblies; IMPPManager.UserInfo presence; XMPP connection state |
| `send_text` | `blocked_until_logged_in_adapter` | invoke high-level text send path after target JID and content hash are validated | AppContextManager or MessageScheduling reachability; target JID; sent record or ack containing content hash/correlation |
| `upload_file` | `blocked_until_logged_in_adapter` | call file upload service and return server FileID/remote folder metadata | FileUploadPara values; HTTP file server/auth; FileUploadResult.FileID |
| `send_file_message` | `blocked_until_upload_evidence` | finalize file message after upload returns server id | uploaded FileID; file name/size; target JID/Chat; sent record/ack |
## Anchor summary
| Anchor | Command | Classification | Confidence | Evidence | Required runtime |
| --- | --- | --- | --- | ---: | --- |
| `AppContextManager.SendTxtMessageByJid` | `send_text` | `in_process_candidate_static_only` | `high_static` | 6 | logged-in IMPPManager/UserInfo; target JID; initialized AppContextManager; live XMPP connection |
| `MessageScheduling.SendChatMessage` | `send_text` | `in_process_candidate_static_only` | `high_static` | 16 | MessageScheduling instance or static caller; RosterContactsArgs/contact context; Chat object; live XMPP connection |
| `com.vision.smack.Chat.SendMessage / XMPPConnection.send` | `send_text` | `in_process_candidate_static_only` | `high_static` | 16 | Chat instance; XMPPConnection authenticated session; message payload format |
| `IMPP.Client.OffLineFileSend.sendFile` | `upload_file_then_send_file` | `in_process_candidate_static_only` | `high_static` | 6 | local file path; HTTP file server/auth state; target roster/chat args; upload completion callback |
| `IFileTransfer/FileTransfer.FileUpload + FileUploadPara` | `upload_file` | `in_process_candidate_static_only` | `high_static` | 16 | FileUploadPara host/port/domain; localFilePath; token/auth; FileUploadResult.FileID |
| `MessageScheduling.SendFileMessage / Chat.sendFileMessage` | `send_file_message` | `in_process_candidate_static_only` | `high_static` | 13 | uploaded file id; remote folder metadata; file name/size; target Chat/JID |
| `IMPPManager.UserInfo / UnifiedAuthentication / Auth token` | `runtime_context` | `runtime_dependency` | `medium_static` | 16 | UserInfo; UnifiedAuthentication; Auth token; HTTPFileServer; server resource/domain |
| `frmMain / MessageCenter / chat runtime ownership` | `runtime_context` | `runtime_dependency` | `medium_static` | 16 | running frmMain; initialized message center; contact/session state |
| `frmLogin.StartWinServer / HttpServerLib` | `not_selected_bridge` | `not_a_send_bridge` | `high_static_negative` | 6 | logged-in state; route module registration not found; send route not found |
## Verified facts
- Text send has static in-process candidates, but all require logged-in runtime objects and a live XMPP/Chat path.
- File send is split into upload and message-finalization; FileUploadResult.FileID is a required boundary value before Chat.sendFileMessage is meaningful.
- The earlier IPC/plugin/local HTTP scan did not find a confirmed external send bridge, so this branch must stay at in_process_contract until online reachability exists.
- in_process_contract is a Go-side contract and audit mode only; it must return blocked/no-side-effect metadata in this offline branch.
## Required runtime state
- logged-in IMPlatformClient.exe process
- loaded IMPP.Client/AppContextManager/MessageScheduling types
- initialized IMPPManager.UserInfo and UnifiedAuthentication/Auth token
- live XMPPConnection/Chat session
- target JID or group JID resolved by existing search tools
- file upload service parameters and FileUploadResult.FileID for file sends
## Anchor evidence
### AppContextManager.SendTxtMessageByJid
Classification: `in_process_candidate_static_only`; command: `send_text`; evidence count: 6.
Adapter role: preferred high-level managed entry if an in-process adapter can reach AppContextManager
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:542112` | `string_literal` | `IL_09bf: ldstr "SendTxtMessageByJid"` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:585987` | `signature_continuation` | `instance void SendTxtMessageByJid(string jid,` | `L585986: .method public hidebysig newslot virtual final instance void SendTxtMessageByJid(string jid,` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:586197` | `method_end` | `} // end of method AppContextManager::SendTxtMessageByJid` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1358068` | `string_literal` | `IL_0c3f: ldstr "SendTxtMessageByJid"` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Interface.dll.il:1920` | `signature_continuation` | `instance void SendTxtMessageByJid(string jid,` | `L1919: .method public hidebysig newslot abstract virtual instance void SendTxtMessageByJid(string jid,` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Interface.dll.il:1924` | `method_end` | `} // end of method IAppContextManager::SendTxtMessageByJid` | `L1919: .method public hidebysig newslot abstract virtual instance void SendTxtMessageByJid(string jid,` |
### MessageScheduling.SendChatMessage
Classification: `in_process_candidate_static_only`; command: `send_text`; evidence count: 16.
Adapter role: fallback managed entry when scheduling layer has chat and contact args
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:728720` | `callsite` | `IL_0213: call class [smack]com.vision.smack.packet.XmppMessage IMPP.Client.Core.MessageEngine.MessageScheduling::SendChatMessage(class IMPP.Client.Business.RosterContacts.RosterContactsArgs,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1153541` | `reference` | `SendChatMessage(class [smack]com.vision.smack.Chat chat,` | `L1153540: .method public hidebysig static class [smack]com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1153800` | `method_end` | `} // end of method MessageScheduling::SendChatMessage` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1154128` | `reference` | `SendChatMessage(class IMPP.Client.Business.RosterContacts.RosterContactsArgs rosterArgs,` | `L1154127: .method public hidebysig static class [smack]com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1154187` | `callsite` | `IL_006e: call class [smack]com.vision.smack.packet.XmppMessage IMPP.Client.Core.MessageEngine.MessageScheduling::SendChatMessage(class [smack]com.vision.smack.Chat,` | `L1154127: .method public hidebysig static class [smack]com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1154225` | `method_end` | `} // end of method MessageScheduling::SendChatMessage` | `L1154127: .method public hidebysig static class [smack]com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Common.dll.il:99274` | `reference` | `get_issendchatmessage() cil managed` | `L99273: .method public hidebysig specialname instance string` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Common.dll.il:99284` | `reference` | `set_issendchatmessage(string 'value') cil managed` | `L99283: .method public hidebysig specialname instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Common.dll.il:99582` | `reference` | `.property instance string issendchatmessage()` | `L99546: .method public hidebysig specialname rtspecialname instance void .ctor() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Common.dll.il:99586` | `reference` | `.set instance void Schedule::set_issendchatmessage(string)` | `L99546: .method public hidebysig specialname rtspecialname instance void .ctor() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Common.dll.il:99587` | `reference` | `.get instance string Schedule::get_issendchatmessage()` | `L99546: .method public hidebysig specialname rtspecialname instance void .ctor() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Common.dll.il:100662` | `reference` | `get_issendchatmessage() cil managed` | `L100661: .method public hidebysig specialname instance string` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Common.dll.il:100672` | `reference` | `set_issendchatmessage(string 'value') cil managed` | `L100671: .method public hidebysig specialname instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Common.dll.il:101019` | `reference` | `.property instance string issendchatmessage()` | `L100976: .method public hidebysig specialname rtspecialname instance void .ctor() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Common.dll.il:101023` | `reference` | `.get instance string ScheduleTaskDetailsDTO::get_issendchatmessage()` | `L100976: .method public hidebysig specialname rtspecialname instance void .ctor() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPP.Common.dll.il:101024` | `reference` | `.set instance void ScheduleTaskDetailsDTO::set_issendchatmessage(string)` | `L100976: .method public hidebysig specialname rtspecialname instance void .ctor() cil managed` |
### com.vision.smack.Chat.SendMessage / XMPPConnection.send
Classification: `in_process_candidate_static_only`; command: `send_text`; evidence count: 16.
Adapter role: lowest-level send target; requires already resolved Chat/XMPPConnection
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:80284` | `callsite` | `IL_34d2: callvirt instance void [smack]com.vision.smack.XMPPConnection::send(string)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:206378` | `callsite` | `IL_0010: callvirt instance void [smack]com.vision.smack.XMPPConnection::send(string)` | `L206369: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:249554` | `callsite` | `IL_0c1e: callvirt instance void [smack]com.vision.smack.XMPPConnection::send(string)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:249857` | `callsite` | `IL_0f27: callvirt instance void [smack]com.vision.smack.XMPPConnection::send(string)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:299997` | `callsite` | `IL_0096: callvirt instance class [smack]com.vision.smack.packet.XmppMessage [smack]com.vision.smack.Chat::SendMessage(class [smack]com.vision.smack.packet.XmppMessage)` | `L299937: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:410318` | `callsite` | `IL_2257: callvirt instance void [smack]com.vision.smack.XMPPConnection::send(string)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:412929` | `callsite` | `IL_00d2: callvirt instance class [smack]com.vision.smack.packet.XmppMessage [smack]com.vision.smack.Chat::SendMessage(class [smack]com.vision.smack.packet.XmppMessage)` | `L412858: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:430535` | `callsite` | `IL_0357: callvirt instance class [smack]com.vision.smack.packet.XmppMessage [smack]com.vision.smack.Chat::SendMessage(class [smack]com.vision.smack.packet.XmppMessage)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:451786` | `callsite` | `IL_00b1: callvirt instance void [smack]com.vision.smack.XMPPConnection::send(string)` | `L451702: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:451858` | `callsite` | `IL_018f: callvirt instance void [smack]com.vision.smack.XMPPConnection::send(string)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:454073` | `callsite` | `IL_0179: callvirt instance void [smack]com.vision.smack.XMPPConnection::send(string)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:454206` | `callsite` | `IL_00b9: callvirt instance void [smack]com.vision.smack.XMPPConnection::send(string)` | `L454118: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:454298` | `callsite` | `IL_00b9: callvirt instance void [smack]com.vision.smack.XMPPConnection::send(string)` | `L454210: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:520831` | `callsite` | `IL_017a: callvirt instance void [smack]com.vision.smack.XMPPConnection::send(string)` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:521914` | `callsite` | `IL_007a: callvirt instance void [smack]com.vision.smack.XMPPConnection::send(string)` | `L521860: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:521970` | `callsite` | `IL_0075: callvirt instance void [smack]com.vision.smack.XMPPConnection::send(string)` | `L521918: .method public hidebysig instance void` |
### IMPP.Client.OffLineFileSend.sendFile
Classification: `in_process_candidate_static_only`; command: `upload_file_then_send_file`; evidence count: 6.
Adapter role: UI-side upload orchestration and transition into chat file message
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:821640` | `reference` | `_tcpRecvInfo_RecvCancelSendFile() cil managed` | `L821639: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:824164` | `callsite` | `IL_026b: callvirt instance void IMPP.Client.OffLineFileSend::sendFile()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:826149` | `reference` | `sendFile() cil managed` | `L826148: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:826572` | `method_end` | `} // end of method OffLineFileSend::sendFile` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:826670` | `callsite` | `IL_0104: call instance void IMPP.Client.OffLineFileSend::trans_UploadCompleted(string)` | `L826574: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:827241` | `method_end` | `} // end of method OffLineFileSend::trans_UploadCompleted` | `` |
### IFileTransfer/FileTransfer.FileUpload + FileUploadPara
Classification: `in_process_candidate_static_only`; command: `upload_file`; evidence count: 16.
Adapter role: service upload entry that must return FileUploadResult before chat file finalization
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:511999` | `reference` | `class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara V_11,` | `L511981: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:512002` | `reference` | `class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult V_14,` | `L511981: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:512182` | `callsite` | `IL_01d9: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.Ser...` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:512315` | `callsite` | `IL_0322: callvirt instance string [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult::get_FileID()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:512459` | `constructor_call` | `IL_04a3: newobj instance void [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara::.ctor(string,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608732` | `reference` | `class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara V_4,` | `L608722: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608733` | `reference` | `class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult V_5,` | `L608722: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608787` | `constructor_call` | `IL_0092: newobj instance void [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara::.ctor(string,` | `L608722: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608795` | `callsite` | `IL_009c: callvirt instance void [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara::set_IsPublic(bool)` | `L608722: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608800` | `callsite` | `IL_00b2: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.Ser...` | `L608722: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608819` | `callsite` | `IL_00e0: callvirt instance string [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult::get_FileID()` | `L608722: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608847` | `reference` | `class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara V_5,` | `L608836: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608848` | `reference` | `class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult V_6,` | `L608836: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608908` | `constructor_call` | `IL_00a5: newobj instance void [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara::.ctor(string,` | `L608836: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608916` | `callsite` | `IL_00af: callvirt instance void [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadPara::set_IsPublic(bool)` | `L608836: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:608921` | `callsite` | `IL_00c5: callvirt instance class [IMPP.ServiceBase]IMPP.ServiceBase.ModelBase.FileServiceBase.FileUploadResult [IMPP.ServiceBase]IMPP.ServiceBase.Interface.IFileTransfer::FileUpload(class [IMPP.ServiceBase]IMPP.Ser...` | `L608836: .method private hidebysig instance void` |
### MessageScheduling.SendFileMessage / Chat.sendFileMessage
Classification: `in_process_candidate_static_only`; command: `send_file_message`; evidence count: 13.
Adapter role: chat file-message finalization after FileID/remote folder exists
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:728711` | `callsite` | `IL_01fb: call class [smack]com.vision.smack.packet.XmppMessage IMPP.Client.Core.MessageEngine.MessageScheduling::SendFileMessage(class IMPP.Client.Business.RosterContacts.RosterContactsArgs,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:827225` | `callsite` | `IL_034d: callvirt instance class [smack]com.vision.smack.packet.XmppMessage [smack]com.vision.smack.Chat::sendFileMessage(string,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1144766` | `callsite` | `IL_03e8: callvirt instance void [HYHC.IMPP.DAL]HYHC.IMPP.DAL.IMPPDAL::AddSendFileMessage(string,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1146020` | `callsite` | `IL_0237: callvirt instance void [HYHC.IMPP.DAL]HYHC.IMPP.DAL.IMPPDAL::AddSendFileMessage(string,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1150833` | `callsite` | `IL_14e8: callvirt instance void [HYHC.IMPP.DAL]HYHC.IMPP.DAL.IMPPDAL::AddSendFileMessage(string,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1153803` | `reference` | `SendFileMessage(class IMPP.Client.Business.RosterContacts.RosterContactsArgs rosterArgs,` | `L1153802: .method public hidebysig static class [smack]com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1153922` | `callsite` | `IL_00f1: callvirt instance class [smack]com.vision.smack.packet.XmppMessage [smack]com.vision.smack.Chat::sendFileMessage(string,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1154125` | `method_end` | `} // end of method MessageScheduling::SendFileMessage` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:1235` | `reference` | `sendFileMessage(string p_message,` | `L1233: .method public hidebysig newslot abstract virtual instance class com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:1244` | `method_end` | `} // end of method Chat::sendFileMessage` | `L1233: .method public hidebysig newslot abstract virtual instance class com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:21442` | `reference` | `sendFileMessage(string p_message,` | `L21441: .method public hidebysig virtual instance class com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:21490` | `method_end` | `} // end of method P2PChat::sendFileMessage` | `L21441: .method public hidebysig virtual instance class com.vision.smack.packet.XmppMessage` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\smack.dll.il:30070` | `reference` | `sendFileMessage(string p_message,` | `L30069: .method public hidebysig virtual instance class com.vision.smack.packet.XmppMessage` |
### IMPPManager.UserInfo / UnifiedAuthentication / Auth token
Classification: `runtime_dependency`; command: `runtime_context`; evidence count: 16.
Adapter role: runtime state required before any production send/upload can be meaningful
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:3533` | `callsite` | `IL_004c: callvirt instance class [IMPP.Common]IMPP.Common.UserInfo IMPP.Client.IMPPManager::get_UserInfo()` | `L3492: .method public hidebysig static void FillDataToDataGridView(class [IMPP.UI]IMPP.UI.SkinControl.SkinDataGridView dgv,` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:4359` | `callsite` | `IL_01ba: callvirt instance class [IMPP.Common]IMPP.Common.UserInfo IMPP.Client.IMPPManager::get_UserInfo()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:4393` | `callsite` | `IL_021a: callvirt instance class [IMPP.Common]IMPP.Common.UserInfo IMPP.Client.IMPPManager::get_UserInfo()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:4403` | `callsite` | `IL_0236: callvirt instance class [IMPP.Common]IMPP.Common.UserInfo IMPP.Client.IMPPManager::get_UserInfo()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:5267` | `callsite` | `IL_02ea: callvirt instance class [IMPP.Common]IMPP.Common.UserInfo IMPP.Client.IMPPManager::get_UserInfo()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:5752` | `callsite` | `IL_08ac: callvirt instance class [IMPP.Common]IMPP.Common.UserInfo IMPP.Client.IMPPManager::get_UserInfo()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:5772` | `callsite` | `IL_08ee: callvirt instance class [IMPP.Common]IMPP.Common.UserInfo IMPP.Client.IMPPManager::get_UserInfo()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:6283` | `callsite` | `IL_0ea6: callvirt instance class [IMPP.Common]IMPP.Common.UserInfo IMPP.Client.IMPPManager::get_UserInfo()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:6329` | `callsite` | `IL_0f2f: callvirt instance class [IMPP.Common]IMPP.Common.UserInfo IMPP.Client.IMPPManager::get_UserInfo()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:6399` | `callsite` | `IL_1006: callvirt instance class [IMPP.Common]IMPP.Common.UserInfo IMPP.Client.IMPPManager::get_UserInfo()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:7402` | `callsite` | `IL_0141: callvirt instance class [IMPP.Common]IMPP.Common.UserInfo IMPP.Client.IMPPManager::get_UserInfo()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:7504` | `callsite` | `IL_024f: callvirt instance class [IMPP.Common]IMPP.Common.UserInfo IMPP.Client.IMPPManager::get_UserInfo()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:7855` | `callsite` | `IL_00bf: callvirt instance class [IMPP.Common]IMPP.Common.UserInfo IMPP.Client.IMPPManager::get_UserInfo()` | `L7780: .method public hidebysig static void AddLinkID(class CSharpWin.ChatRichTextBox textBox,` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:7997` | `callsite` | `IL_023a: callvirt instance class [IMPP.Common]IMPP.Common.UserInfo IMPP.Client.IMPPManager::get_UserInfo()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:8222` | `callsite` | `IL_047a: callvirt instance class [IMPP.Common]IMPP.Common.UserInfo IMPP.Client.IMPPManager::get_UserInfo()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:8309` | `callsite` | `IL_0557: callvirt instance class [IMPP.Common]IMPP.Common.UserInfo IMPP.Client.IMPPManager::get_UserInfo()` | `` |
### frmMain / MessageCenter / chat runtime ownership
Classification: `runtime_dependency`; command: `runtime_context`; evidence count: 16.
Adapter role: likely object owner for initialized chat, reconnect, message center, and plugin runtime state
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1714` | `field` | `.field family class IMPP.Client.frmMain mainWin` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1744` | `reference` | `IL_001d: ldfld class IMPP.Client.frmMain IMPP.Client.VideoChat.SingleAVDispatcher::mainWin` | `L1721: .method family hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:1789` | `reference` | `IL_002a: ldfld class IMPP.Client.frmMain IMPP.Client.VideoChat.SingleAVDispatcher::mainWin` | `L1761: .method family hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:2777` | `reference` | `Init(class IMPP.Client.frmMain frmMain) cil managed` | `L2776: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:2791` | `reference` | `IL_000a: stfld class IMPP.Client.frmMain IMPP.Client.VideoChat.SingleAVDispatcher::mainWin` | `L2776: .method public hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:3005` | `reference` | `IL_001d: ldfld class IMPP.Client.frmMain IMPP.Client.VideoChat.SingleAVDispatcher::mainWin` | `L2981: .method family hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9039` | `type_definition` | `.class private auto ansi beforefieldinit IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication` | `L9012: .method public hidebysig specialname rtspecialname instance void .ctor() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9042` | `field` | `.field private static class IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication _instance` | `L9012: .method public hidebysig specialname rtspecialname instance void .ctor() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9058` | `constructor_call` | `IL_0000: newobj instance void IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication::.ctor()` | `L9054: .method public hidebysig static void Init() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9059` | `reference` | `IL_0005: stsfld class IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication::_instance` | `L9054: .method public hidebysig static void Init() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9060` | `reference` | `IL_000a: ldsfld class IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication::_instance` | `L9054: .method public hidebysig static void Init() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9061` | `callsite` | `IL_000f: callvirt instance void IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication::StartLightAppMultProssCommunication()` | `L9054: .method public hidebysig static void Init() cil managed` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:9081` | `reference` | `} // end of class IMPP.Client.Core.Plugins.MessageCenter.Classes.PluginLightAppMulProcessCommunication` | `L9073: .method private hidebysig specialname rtspecialname static` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:13688` | `callsite` | `IL_0179: callvirt instance class [smack]com.vision.smack.Chat [smack]com.vision.smack.ChatManager::GetChat(class [smack]com.vision.smack.XMPPConnection,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:14269` | `callsite` | `IL_00be: callvirt instance class [smack]com.vision.smack.Chat [smack]com.vision.smack.ChatManager::GetChat(class [smack]com.vision.smack.XMPPConnection,` | `L14190: .method public hidebysig static void OpenSetRoamMessageForm(valuetype [IMPP.Model]IMPP.Model.ChatRecord.MsgType msgSource,` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:15179` | `callsite` | `IL_0074: callvirt instance class [smack]com.vision.smack.Chat [smack]com.vision.smack.ChatManager::GetChat(class [smack]com.vision.smack.XMPPConnection,` | `L15134: .method public hidebysig static class [IMPP.Model]IMPP.Model.ChatRecord.tblMsgGroupPersonMsg` |
### frmLogin.StartWinServer / HttpServerLib
Classification: `not_a_send_bridge`; command: `not_selected_bridge`; evidence count: 6.
Adapter role: known local HTTP framework, but not a confirmed send bridge
| Source | Kind | Snippet | Context |
| --- | --- | --- | --- |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:223` | `reference` | `.assembly extern HttpServerLib` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:889253` | `reference` | `StartWinServer() cil managed` | `L889252: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:889272` | `reference` | `class [HttpServerLib]HTTPServerLib.HttpService V_15,` | `L889252: .method private hidebysig instance void` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:889554` | `constructor_call` | `IL_02dc: newobj instance void [HttpServerLib]HTTPServerLib.HttpService::.ctor(string,` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:889559` | `reference` | `IL_02e5: ldftn instance void [HttpServerLib]HTTPServerLib.HttpServer::Start()` | `` |
| `runs\offline-evidence-intake\zyl-qqfile-20260709\metadata\c28-il\IMPlatformClient.exe.il:889677` | `method_end` | `} // end of method frmLogin::StartWinServer` | `` |
## Stop conditions
- No logged-in process is available for runtime reachability validation.
- Adapter cannot see AppContextManager, MessageScheduling, Chat, or IFileTransfer in process.
- Every viable path requires unsupported binary patching instead of a replaceable managed adapter/harness.
- Online evidence cannot produce sent-record/content-hash/ack correlation for text send.
- File upload cannot return FileUploadResult.FileID or equivalent remote folder metadata.
## Next work
1. Add Go connector mode in_process_contract that validates request shape and returns blocked/no-side-effect metadata.
2. In a logged-in environment, build a recorder/probe that only checks reachability of the listed runtime objects before attempting any send.
3. Promote text send only after sent-record/content-hash/ack evidence exists.
4. Promote file send only after upload returns FileUploadResult.FileID and file-message finalization is proven online.

View File

@@ -0,0 +1,65 @@
# Offline B-Route Reverse Decision
Date: 2026-07-12
Branch: `codex/offline-broute-reverse`
## Current phase / 当前阶段
Offline reverse engineering for the primary B-route is complete for the current evidence set. The goal was to decide whether B-route can continue through an existing IPC/plugin/local API, or whether it must move to an in-process adapter research branch.
## Inputs / 输入证据
| Evidence | Path |
| --- | --- |
| Offline sample index | `docs/source-discovery/2026-07-12-offline-broute-reverse-index.md` |
| Text send static map | `docs/source-discovery/2026-07-12-broute-text-send-static-map.md` |
| File send static map | `docs/source-discovery/2026-07-12-broute-file-send-static-map.md` |
| Bridge/IPC/plugin static map | `docs/source-discovery/2026-07-12-broute-bridge-static-map.md` |
| Machine JSON outputs | `runs/offline-broute-reverse/*.json` |
## Verified facts / 已验证事实
1. The offline sample set is present and hash-matched against the recorded plan list; the analyzer scripts only read metadata/IL and did not copy or modify binaries.
2. Text send has confirmed static call-path evidence:
- `AppContextManager.SendTxtMessageByJid`
- `MessageScheduling.SendChatMessage`
- `Chat.SendMessage` / `Chat.sendMessage`
- `XMPPConnection.send`
3. File send has confirmed two-step evidence:
- upload first through `OffLineFileSend.sendFile`, `FileUploadPara`, and `IFileTransfer.FileUpload` / `IMPP.Service.BLL.FileTransfer.FileUpload`;
- then chat file-message finalization through `trans_UploadCompleted(fileId)`, `MessageScheduling.SendFileMessage`, and `Chat.sendFileMessage`.
4. `FileUploadResult.FileID` / remote-folder metadata is required before the chat file message is meaningful.
5. The static bridge scan found no confirmed existing IPC/plugin/local HTTP route that exposes text-send or file-send.
6. `HttpServerLib` exists, but the discovered `frmLogin.StartWinServer` path depends on logged-in runtime state and no send route was found.
7. `PluginLightAppMulProcessCommunication` declares a `NamedPipeServerStream`, but its start method returns immediately.
8. Returned live probe saw `\\.\pipe\zfpinject-msg-server`, but no matching iSphere static send contract was found.
## Decision / 决策
| Candidate | Decision | Reason |
| --- | --- | --- |
| `existing_ipc_first` | rejected for now | No concrete local HTTP/named-pipe/service send API was confirmed. |
| `plugin_extension_first` | rejected for now | Plugin evidence is UI/app-store/context-menu oriented; no local plugin load/send bridge is confirmed. |
| `in_process_adapter_research` | selected | The send and file-send call paths exist, but they need access to the logged-in `IMPlatformClient.exe` runtime objects. |
| `external_sidecar_preview_only` | allowed | External sidecar can validate contracts/probes, but cannot reuse logged-in static runtime by itself. |
| `fallback_rpa_only` | not selected | A-route/RPA remains backup-only; do not promote it unless B-route is explicitly blocked by a later decision. |
Final offline decision: **B-route stays primary, but the next real branch is `in_process_adapter_research`, not existing IPC/plugin and not production send.**
## Business impact / 业务影响
- Message receiving, file receiving/listing, contact search, and group search stay on the existing data/log-backed roadmap.
- Text send is technically mapped but not business-complete: the missing piece is a bridge into logged-in runtime state and later online ack/sent-record validation.
- File send is harder than text send: upload and chat-message finalization are separate, and upload needs HTTP file-service auth plus server-issued file id.
- RPA remains a practical backup for UI smoke, but it is not the product architecture.
## Next implementation slice / 下一轮
1. Create a dedicated in-process adapter research plan.
2. Keep any sidecar work preview/probe-only until an adapter path is selected.
3. Do not implement real `send_message`, `send_file`, or `upload_file` in this offline branch.
4. Online evidence later must prove sent-record/content-hash/ack before production send can be called complete.
## Stop conditions / 停止条件
Stop and ask for business decision if the next in-process research shows that every viable bridge requires invasive process mutation, unsupported injection, or cannot be validated without a logged-in test environment.

View File

@@ -0,0 +1,45 @@
# Offline B-Route Reverse Index
Date: 2026-07-12
## Scope
This index records the read-only offline samples for B-route reverse engineering. The script reads metadata and SHA256 hashes only; it does not copy or modify the original binaries.
## Summary
- Samples total: 12
- Samples present: 12
- Hash matches: 12
- Originals copied: false
- Originals modified: false
- Machine JSON: `runs/offline-broute-reverse/index.json`
## Sample table
| Sample | Role | Size | SHA256 match | SHA256 |
| --- | --- | ---: | --- | --- |
| `runs/offline-real-client-window/full/zyl/Impp/IMPlatformClient.exe` | main managed client; text send, chat window, plugin/IPC candidates | 8366592 | yes | `E2966E58360DAEEBF178410A961E2DC52748C63E9CCBD94BD6EC8434A1A09CB7` |
| `runs/offline-real-client-window/full/zyl/Impp/IMPP.Service.dll` | file upload service candidates | 21504 | yes | `F859DE2F34E024B5F372D95F22CBF8A018C780F24203E7A76D392E52BD90CADD` |
| `runs/offline-real-client-window/full/zyl/Impp/IMPP.Interface.dll` | service/interface contract candidates | 33792 | yes | `DD093CF61FAE85C2D2581F289B01AA477546712E098FEF81272FDD989E50D12D` |
| `runs/offline-real-client-window/full/zyl/Impp/IMPP.Model.dll` | model/parameter types | 35328 | yes | `7CBABDD23A7234D15E294C549EEEC78EFBAD6E957CD45A6E8A85309349A624A5` |
| `runs/offline-real-client-window/full/zyl/Impp/IMPP.UI.dll` | UI/plugin helpers and possible send controls | 2401792 | yes | `4C61212519C01D1B731ED4F20DF3411C491616F4ADA98A4529722A6AA3689E6D` |
| `runs/offline-real-client-window/full/zyl/Impp/IMPP.Common.dll` | shared utility and message types | 479744 | yes | `02A47C99C27C9BFE2BADC438389300C92220B07609BD87C48B4B5E1B4EE6AEB4` |
| `runs/offline-real-client-window/full/zyl/Impp/IMPP.Helper.dll` | helper abstractions | 53248 | yes | `30932D082B6678699C832C63F923E01EAD84674FAEDB613D631E034E03742FB9` |
| `runs/offline-real-client-window/full/zyl/Impp/smack.dll` | XMPP chat/send layer | 370688 | yes | `BAD0BB0591765DB153B17CECC1112B0BBDBF3B1D3370DDF973F91974E92CEC66` |
| `runs/offline-real-client-window/full/zyl/Impp/TcpFileTransfer.dll` | native/transfer candidate | 45056 | yes | `6C4874B46D1E7DC04C9B6784180603452400B881E04509D464A0D58814EFEDA7` |
| `runs/offline-real-client-window/full/zyl/Impp/HttpServerLib.dll` | local API/IPC candidate | 26624 | yes | `FFDB633216AE332B8EDFFC83E2AE546B7A80144C659FF4053FDFE4FE382A8D12` |
| `runs/offline-real-client-window/full/zyl/Impp/INetwork.dll` | network abstraction candidate | 87552 | yes | `E40BE4EE2439E4280461F4D2BADB318A5F4572428F069AB6D17B4C4F0E8CFAC9` |
| `runs/offline-real-client-window/full/zyl/Impp/IOClientNetwork.dll` | network implementation candidate | 145920 | yes | `64CA231A614771325741A5F098E52EBF20F7190E339B64962DE2EDEDCFFFF904` |
## Verified facts
- All metadata came from local filesystem reads under the repository workspace.
- The expected primary B-route samples are present if Samples present equals Samples total.
- Hash matching only proves local file identity against this plan's recorded sample list; it does not prove runtime invocability.
## Next reverse targets
1. Text-send static call graph: SendTxtMessageByJid, MessageScheduling.SendChatMessage, Chat.SendMessage, XMPPConnection.send.
2. File-send/upload static call graph: OffLineFileSend.sendFile, FileTransfer.FileUpload, AsynFileUpload, sendFileMessage.
3. Bridge/IPC/plugin map: HttpServerLib, plugin loaders, local HTTP, named pipes, command-line switches, services.

View File

@@ -17,6 +17,12 @@ R14 release candidate: `docs/reports/2026-07-10-r6f-r14-release-candidate.md`
Main status correction: `docs/reports/2026-07-12-main-business-status-correction.md`
A-route UIA send: `docs/source-discovery/2026-07-11-a-route-uia-send.md`
A-route real offline chat window: `docs/source-discovery/2026-07-11-a-route-open-real-chat-window.md`
Offline B-route reverse index: `docs/source-discovery/2026-07-12-offline-broute-reverse-index.md`
Offline B-route text-send map: `docs/source-discovery/2026-07-12-broute-text-send-static-map.md`
Offline B-route file-send map: `docs/source-discovery/2026-07-12-broute-file-send-static-map.md`
Offline B-route bridge map: `docs/source-discovery/2026-07-12-broute-bridge-static-map.md`
Offline B-route decision: `docs/source-discovery/2026-07-12-offline-broute-reverse-decision.md`
In-process adapter static map: `docs/source-discovery/2026-07-12-inprocess-adapter-static-map.md`
## Source priority
@@ -37,8 +43,8 @@ Route rule: UIA helper / A-route / RPA is a backup route only. It can preserve d
| `isphere_search_contacts` | bare sender/receiver JIDs extracted from normalized log-backed messages loaded from configured PacketReader file or directory source | validated copied `MsgLib.db` tables: `TD_Roster`, `TD_CustomEffigy`, `tblRecent`, `tblChatLevel`, `tblPersonMsg`; decrypted roster/contact stanzas from `Smark.SendReceive`; UIA helper source if display names are still missing | `docs/source-discovery/2026-07-10-msglib-readonly-schema-extraction.md`; `internal/isphere/contacts_test.go`; `internal/tools/isphere_contacts_test.go` | C34 documents optional MsgLib contact display enrichment; R2 adds deterministic exact-match-first ranking, case-insensitive de-duplication across log/MsgLib candidates, and preserves `source`/`raw_ref` | core contact search complete; optional richer fields later |
| `isphere_search_groups` | decrypted `PacketReader.ProcessPacket` `type="groupchat"` stanzas and conference/MUC JIDs loaded from configured PacketReader file or directory source | validated copied `MsgLib.db` tables: `tblMsgGroupPersonMsg`, `TD_WorkGroupAuth`, `tblRecent`; UIA helper source if group display names are still missing | `docs/source-discovery/2026-07-10-msglib-readonly-schema-extraction.md`; `internal/isphere/groups_test.go`; `internal/tools/isphere_groups_test.go`; C9 ignored-log scan: PacketReader 86 groupchat/86 conference hits; Smark 24 groupchat/658 conference/631 muc hits | C34 documents optional MsgLib group display enrichment; R2 adds deterministic exact-match-first ranking, case-insensitive de-duplication across log/MsgLib candidates, and preserves `source`/`raw_ref` | core group search complete; optional member/owner hierarchy later |
| `isphere_receive_files` | decrypted `PacketReader.ProcessPacket` file-transfer message stanzas via `internal/isphere.ListFilesFromMessages` and `isphere_receive_files` list mode; configured PacketReader file or directory source; `zyl\importal\<hash>` cache entries remain unlinked | MsgLib `TD_ReceiveFileRecord` safe metadata through explicit copied-DB path; decrypted `Smark.SendReceive` and `SaveToDB` traces for file-reference reconciliation; future UIA/client connector for download | `docs/source-discovery/2026-07-09-n12-pre-zyl-schema-notes.md#c12-file-transfer-evidence-precheck`; `docs/source-discovery/2026-07-10-file-download-mapping-precheck.md`; `docs/source-discovery/2026-07-10-file-cache-mapping-diagnostic.md`; `docs/source-discovery/2026-07-10-file-download-mapping-v2.md`; `docs/reports/2026-07-10-business-goals-smoke.md` | C22 verifies safe file-list contract args; R10 proves resolver scoring with fixture accepted matches; R11 adds structured download preview with `blocked`/`planned` status and side-effect flags false; R13/R14 confirms list is ready but real download is still blocked. | blocked for real download pending accepted real cache mapping and copy gate; list mode is complete |
| `isphere_send_message` | B-route selected: running-client sidecar / in-process connector, preferring `AppContextManager.SendTxtMessageByJid(...)` or `MessageScheduling.SendChatMessage(...)` over the unimplemented `SendP2PMessage(...)` interface path; default MCP tool still exposes preview/dry-run unless an explicit connector mode is configured | A-route fallback is now implemented for UI action: `ISPHERE_SEND_CONNECTOR_MODE=uia_rpa` calls WinHelper `uia_send_message` against a configured HWND, writes `rtbSendMessage`, and clicks `btnSend`; this stays backup-only and network/protocol replay remains deferred | `docs/source-discovery/2026-07-10-send-message-source-precheck.md`; `docs/source-discovery/2026-07-10-send-message-connector-selection.md`; `docs/source-discovery/2026-07-10-send-sidecar-b-first-plan.md`; `docs/source-discovery/2026-07-10-returned-live-probe-analysis.md`; `docs/source-discovery/2026-07-10-send-connector-preflight.md`; `docs/source-discovery/2026-07-10-send-sandbox-gate.md`; `docs/source-discovery/2026-07-10-returned-send-sandbox-analysis.md`; `docs/source-discovery/2026-07-10-returned-send-sandbox-analysis-v2.md`; `docs/source-discovery/2026-07-10-returned-send-sent-record-diagnostic.md`; `docs/source-discovery/2026-07-11-a-route-uia-send.md`; `docs/source-discovery/2026-07-11-a-route-open-real-chat-window.md`; `internal/tools/isphere_send_message_test.go`; `cmd/isphere-capability-smoke/main.go`; `docs/reports/2026-07-10-business-goals-smoke.md` | R6f-R6l define connector contract, audit/idempotency replay, production gate, B-route shell, strict-v2 package, and explicit production closure. R10a validates two returned sent-record packages as manual-only evidence. A-route adds local UI action readiness: synthetic window proof plus real offline `frmP2PChat` open/write/click target proof. Business delivery is still not verified because local runtime is offline and no success/ack or sent-record hash evidence has passed. | B-route evidence remains next priority; A-route UI action is backup-ready only; business send remains blocked until online sent-record/content-hash/ack evidence passes |
| `isphere_send_file` | B-route selected after send-message probe: managed offline-file path through `OffLineFileSend.sendFile()`, `IMPP.Service*.dll` `IFileTransfer.FileUpload(...)`, and `Chat.sendFileMessage(...)`; current MCP tool exposes preview/dry-run only | A-route file fallback is not implemented yet; real offline UIA dump did not expose stable `btnSendFile`, so the next fallback slice is toolbar/menu locator discovery; native `TcpFileTransfer.dll` is a later candidate only after managed path is rejected | `docs/source-discovery/2026-07-10-send-message-source-precheck.md`; `docs/source-discovery/2026-07-10-send-message-connector-selection.md`; `docs/source-discovery/2026-07-10-send-sidecar-b-first-plan.md`; `docs/source-discovery/2026-07-10-returned-live-probe-analysis.md`; `docs/source-discovery/2026-07-10-send-connector-preflight.md`; `docs/source-discovery/2026-07-10-send-file-sandbox-gate.md`; `docs/source-discovery/2026-07-11-a-route-open-real-chat-window.md`; `internal/tools/isphere_files_test.go`; `docs/reports/2026-07-10-business-goals-smoke.md` | R7 registers send-file preview as the tenth MCP tool; R8 adds audit/idempotency duplicate/conflict hardening without raw file paths/content; R9 builds and verifies the online send-file evidence package; R13/R14 confirms preview is ready and production upload remains blocked. A-route real-window work confirms file-button automation still needs a separate locator node. | blocked until file toolbar/menu locator is found and returned file-send package proves upload/sent evidence |
| `isphere_send_message` | B-route selected: `in_process_adapter_research` after offline reverse. Static call path is confirmed through `AppContextManager.SendTxtMessageByJid(...)`, `MessageScheduling.SendChatMessage(...)`, `Chat.SendMessage`, and `XMPPConnection.send`, but no existing IPC/plugin/local HTTP send bridge is confirmed; default MCP tool still exposes preview/dry-run unless an explicit connector mode is configured | A-route fallback is now implemented for UI action: `ISPHERE_SEND_CONNECTOR_MODE=uia_rpa` calls WinHelper `uia_send_message` against a configured HWND, writes `rtbSendMessage`, and clicks `btnSend`; this stays backup-only and network/protocol replay remains deferred | `docs/source-discovery/2026-07-10-send-message-source-precheck.md`; `docs/source-discovery/2026-07-10-send-message-connector-selection.md`; `docs/source-discovery/2026-07-10-send-sidecar-b-first-plan.md`; `docs/source-discovery/2026-07-10-returned-live-probe-analysis.md`; `docs/source-discovery/2026-07-10-send-connector-preflight.md`; `docs/source-discovery/2026-07-10-send-sandbox-gate.md`; `docs/source-discovery/2026-07-10-returned-send-sandbox-analysis.md`; `docs/source-discovery/2026-07-10-returned-send-sandbox-analysis-v2.md`; `docs/source-discovery/2026-07-10-returned-send-sent-record-diagnostic.md`; `docs/source-discovery/2026-07-11-a-route-uia-send.md`; `docs/source-discovery/2026-07-11-a-route-open-real-chat-window.md`; `docs/source-discovery/2026-07-12-broute-text-send-static-map.md`; `docs/source-discovery/2026-07-12-broute-bridge-static-map.md`; `docs/source-discovery/2026-07-12-offline-broute-reverse-decision.md`; `docs/source-discovery/2026-07-12-inprocess-adapter-static-map.md`; `internal/tools/isphere_send_message_test.go`; `cmd/isphere-capability-smoke/main.go`; `docs/reports/2026-07-10-business-goals-smoke.md` | R6f-R6l define connector contract, audit/idempotency replay, production gate, B-route shell, strict-v2 package, and explicit production closure. R10a validates two returned sent-record packages as manual-only evidence. A-route adds local UI action readiness: synthetic window proof plus real offline `frmP2PChat` open/write/click target proof. Offline B-route reverse confirms the send call path but rejects existing IPC/plugin-first for this evidence set; business delivery is still not verified because local runtime is offline and no success/ack or sent-record hash evidence has passed. | B-route now exposes only the `in_process_contract` connector mode for request-shape/audit validation; keep external sidecar preview/probe-only and A-route UI action backup-only; production remains blocked until logged-in adapter reachability plus online sent-record/content-hash/ack evidence passes |
| `isphere_send_file` | B-route selected after offline reverse: managed file send is upload-first through `OffLineFileSend.sendFile()`, `FileUploadPara`, `IMPP.Service*.dll` `IFileTransfer.FileUpload(...)`, then chat file-message finalization through `trans_UploadCompleted(fileId)`, `MessageScheduling.SendFileMessage`, and `Chat.sendFileMessage(...)`; current MCP tool exposes preview/dry-run only | A-route file fallback is not implemented yet; real offline UIA dump did not expose stable `btnSendFile`, so the fallback slice remains toolbar/menu locator discovery; native `TcpFileTransfer.dll` is not the first B-route bridge because managed upload/message flow is now mapped | `docs/source-discovery/2026-07-10-send-message-source-precheck.md`; `docs/source-discovery/2026-07-10-send-message-connector-selection.md`; `docs/source-discovery/2026-07-10-send-sidecar-b-first-plan.md`; `docs/source-discovery/2026-07-10-returned-live-probe-analysis.md`; `docs/source-discovery/2026-07-10-send-connector-preflight.md`; `docs/source-discovery/2026-07-10-send-file-sandbox-gate.md`; `docs/source-discovery/2026-07-11-a-route-open-real-chat-window.md`; `docs/source-discovery/2026-07-12-broute-file-send-static-map.md`; `docs/source-discovery/2026-07-12-broute-bridge-static-map.md`; `docs/source-discovery/2026-07-12-offline-broute-reverse-decision.md`; `docs/source-discovery/2026-07-12-inprocess-adapter-static-map.md`; `internal/tools/isphere_files_test.go`; `docs/reports/2026-07-10-business-goals-smoke.md` | R7 registers send-file preview as the tenth MCP tool; R8 adds audit/idempotency duplicate/conflict hardening without raw file paths/content; R9 builds and verifies the online send-file evidence package; R13/R14 confirms preview is ready and production upload remains blocked. Offline B-route reverse confirms upload-first/file-message-second and shows file id/auth/runtime reachability are the blockers. A-route real-window work confirms file-button automation still needs a separate locator node. | blocked until B-route in-process adapter research proves logged-in access to `IFileTransfer.FileUpload`, returned `FileUploadResult.FileID`, and `Chat.sendFileMessage` finalization; production file upload/send remains blocked until online evidence exists; A-route locator remains backup-only |
## Stage C entry rule
@@ -55,4 +61,4 @@ Start Stage C with a narrow log-backed `isphere_receive_messages` source abstrac
## Deferred source work
`MsgLib.db` has a validated copied read-only open path through the bundled 32-bit `System.Data.SQLite.dll` and password `123`. C27 adds `MsgLibReadSidecar` as the bounded x86 .NET reader boundary, C28 adds the Go `internal/msglib` process client, C29 adds bounded `display_entities` extraction, C30 wires it as optional contact/group MCP enrichment, C31 proves real copied-DB MCP enrichment with sanitized output, C32 reuses it for receive-message display fields, C33 proves that receive display path through a real copied-DB MCP smoke without printing entity values, C34 documents the operator setup/verification path, C35 maps MsgLib message tables to receive-message contract fields without reading row values, C36 adds metadata-only `message_sources` readiness, C37 defines the bounded DB-backed receive-source design, C38 implements sidecar/Go-wrapper `list_messages` with sanitized verification, C39 adds a Go adapter from MsgLib list results to the receive-message domain model, C40 adds explicit tool-level `msglib_readonly` source selection, C41 wires env-configured explicit MsgLib receive with optional sanitized smoke, R1 documents source reconciliation keys, and R2 hardens contact/group search ranking and de-duplication. R6j/R6k confirm the send-message strict-v2 production gate is still not passed; R10a confirms the returned sent-record packages are manual-only evidence and do not unlock production send; R10/R11 define file-download resolver/preview behavior while keeping real copy blocked; R12 adds receive-source reconciliation without changing default routing; R13/R14 publish business-goals smoke and the release-candidate status. A-route now proves UI write/click readiness against synthetic and real offline chat windows, but not online delivery. The active follow-up plan is `docs/superpowers/plans/2026-07-11-a-route-rpa-send.md`; next work is evidence-driven send/file verification, not local login-dependent.
`MsgLib.db` has a validated copied read-only open path through the bundled 32-bit `System.Data.SQLite.dll` and password `123`. C27 adds `MsgLibReadSidecar` as the bounded x86 .NET reader boundary, C28 adds the Go `internal/msglib` process client, C29 adds bounded `display_entities` extraction, C30 wires it as optional contact/group MCP enrichment, C31 proves real copied-DB MCP enrichment with sanitized output, C32 reuses it for receive-message display fields, C33 proves that receive display path through a real copied-DB MCP smoke without printing entity values, C34 documents the operator setup/verification path, C35 maps MsgLib message tables to receive-message contract fields without reading row values, C36 adds metadata-only `message_sources` readiness, C37 defines the bounded DB-backed receive-source design, C38 implements sidecar/Go-wrapper `list_messages` with sanitized verification, C39 adds a Go adapter from MsgLib list results to the receive-message domain model, C40 adds explicit tool-level `msglib_readonly` source selection, C41 wires env-configured explicit MsgLib receive with optional sanitized smoke, R1 documents source reconciliation keys, and R2 hardens contact/group search ranking and de-duplication. R6j/R6k confirm the send-message strict-v2 production gate is still not passed; R10a confirms the returned sent-record packages are manual-only evidence and do not unlock production send; R10/R11 define file-download resolver/preview behavior while keeping real copy blocked; R12 adds receive-source reconciliation without changing default routing; R13/R14 publish business-goals smoke and the release-candidate status. A-route now proves UI write/click readiness against synthetic and real offline chat windows, but not online delivery. The active B-route follow-up is now the in-process contract path in `docs/source-discovery/2026-07-12-inprocess-adapter-static-map.md`: validate logged-in adapter reachability before production send/file work. A-route RPA remains backup-only under `docs/superpowers/plans/2026-07-11-a-route-rpa-send.md`.

View File

@@ -2,9 +2,9 @@
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Push the primary B-route from a dry-run shell toward a verifiable sidecar/API bridge without enabling real send yet.
**Goal:** Push the primary B-route from offline reverse evidence into the selected `in_process_adapter_research` branch, while keeping any external sidecar work preview/probe-only and not enabling real send.
**Architecture:** Keep the Go MCP tool contracts stable. B-route remains the primary product route: reuse the logged-in `IMPlatformClient.exe` runtime through a narrow sidecar/API bridge if a safe bridge transport exists. A-route/RPA remains backup-only and should be used only for UI action smoke or when B-route is proven blocked.
**Architecture:** Keep the Go MCP tool contracts stable. B-route remains the primary product route: reuse the logged-in `IMPlatformClient.exe` runtime through a narrow bridge. Offline reverse now rules out existing IPC/plugin as the next first step, so a dedicated in-process adapter research plan is required before any production send. External sidecars may only do self-check/probe/preview. A-route/RPA remains backup-only and should be used only for UI action smoke or when B-route is proven blocked.
**Tech Stack:** Go 1.23.4, github.com/modelcontextprotocol/go-sdk, Windows PowerShell, .NET Framework C# helper/sidecar, stdin/stdout JSON protocols, Windows UI Automation only as fallback.
@@ -21,9 +21,17 @@
---
## Offline reverse amendment
## Offline reverse result amendment
Because the next working day has no logged-in iSphere environment, execute `docs/superpowers/plans/2026-07-12-offline-broute-reverse-plan.md` before the online evidence/package tasks. This keeps B-route primary while using offline static reverse evidence to decide IPC/plugin/in-process/preview-only feasibility. A-route/RPA remains backup-only.
`docs/superpowers/plans/2026-07-12-offline-broute-reverse-plan.md` has now produced the offline reverse decision set:
- `docs/source-discovery/2026-07-12-offline-broute-reverse-index.md`
- `docs/source-discovery/2026-07-12-broute-text-send-static-map.md`
- `docs/source-discovery/2026-07-12-broute-file-send-static-map.md`
- `docs/source-discovery/2026-07-12-broute-bridge-static-map.md`
- `docs/source-discovery/2026-07-12-offline-broute-reverse-decision.md`
Decision correction: B-route remains primary, but **existing IPC/local service** and **plugin extension** are not confirmed usable. The selected next branch is `in_process_adapter_research`. External sidecar work is allowed only as preview/probe plumbing until an in-process bridge is selected. A-route/RPA remains backup-only.
## Current evidence summary
@@ -36,7 +44,7 @@ The current `main` state already has:
- Offline real `frmP2PChat` opener for RPA backup validation.
- No B-route env wiring, no process-backed B-route sidecar client, no in-process bridge transport decision, and no real send/file-upload connector.
Important technical conclusion: an external C# process cannot automatically reuse the logged-in static runtime of `IMPlatformClient.exe`. Before building send invocation, the next B-route node must decide the bridge transport: existing API/IPC, plugin/extension loading, in-process adapter, or fallback.
Important technical conclusion: an external C# process cannot automatically reuse the logged-in static runtime of `IMPlatformClient.exe`. Offline reverse has now made the transport decision for this evidence set: existing API/IPC and plugin extension are not confirmed; the next B-route node is a separate `in_process_adapter_research` plan. Do not build production send/file upload in this plan.
---
@@ -72,11 +80,11 @@ B-route remains primary. The immediate next implementation is not production sen
| Candidate | Can reuse logged-in runtime? | Local feasibility | Next action |
| --- | --- | --- | --- |
| existing_ipc/local_service | unknown | inspect live probe named pipes/services/network metadata | continue if concrete API appears |
| plugin_extension | unknown | inspect install/plugin loader evidence | continue if client loads local plugin DLL/exe |
| in_process_adapter | possible but highest risk | requires explicit bridge mechanism | defer until IPC/plugin ruled out |
| external_dry_run_only | cannot reuse logged-in static runtime | useful for protocol/client tests only | implement as non-mutating sidecar boundary |
| fallback_rpa | can drive UI only | already backup-ready | keep as backup, not primary |
| existing_ipc/local_service | not confirmed | offline bridge map found no send/file API | park unless new online evidence appears |
| plugin_extension | not confirmed | plugin evidence is UI/app-store/context-menu oriented | park unless a concrete local load contract appears |
| in_process_adapter | possible but requires explicit bridge mechanism | selected by offline decision | create dedicated research plan before coding |
| external_dry_run_only | cannot reuse logged-in static runtime | useful for protocol/client tests only | keep preview/probe-only boundary |
| fallback_rpa | can drive UI only | backup-ready for UI action smoke | keep as backup, not primary |
```
- [ ] Update `capability-source-matrix.md` so the next slice says: “B-route bridge transport feasibility and dry-run sidecar boundary”, not “RPA send”.
@@ -91,6 +99,10 @@ git diff --check
Expected: exit 0.
### 2026-07-12 plan correction
Task 1 is now satisfied by the offline reverse reports listed above. Before executing Tasks 2-5, create or approve a new `in_process_adapter_research` plan. Tasks 2-4 may still be used later for non-mutating sidecar preview plumbing, but they do not solve production send by themselves.
## Task 2: Add B-route connector env selection without starting real send
**Files:**

View File

@@ -0,0 +1,285 @@
# In-Process Adapter Research Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Convert the offline B-route decision into a reproducible in-process adapter research slice that identifies reachable runtime objects, defines the minimum helper contract, and keeps production send blocked until logged-in evidence exists.
**Architecture:** This branch does not mutate the iSphere client and does not claim production send. It adds deterministic IL/static analysis for in-process anchors, then updates the Go connector with an explicit `in_process_contract` mode that validates the future bridge request/response shape while returning a blocked/no-side-effect result. Later online work can replace the contract stub with a logged-in managed adapter.
**Tech Stack:** PowerShell static analyzers over IL/text evidence, Markdown reports under `docs/source-discovery`, Go MCP tool connector code under `internal/tools`, and `go test ./...` for regression verification.
## Global Constraints
- Do not use ripgrep (`rg`); use `git ls-files`, `ag`, `grep -R`, PowerShell, or `Select-String`.
- Do not stage or commit `.codex-remote-attachments/`.
- Do not copy, patch, or modify original iSphere binaries.
- Do not enable real text send, file upload, or file send in this offline branch.
- A-route/RPA remains backup-only; do not promote it as the product path.
- B-route primary path for this branch is `in_process_adapter_research`.
- Every claimed completion must be backed by fresh command output.
---
## File Structure
- Create `scripts/extract-inprocess-adapter-map.ps1`: deterministic static analyzer for in-process anchors, object ownership, method accessibility, required runtime state, and stop conditions.
- Create `docs/source-discovery/2026-07-12-inprocess-adapter-static-map.md`: human-readable report generated by the script.
- Create ignored runtime JSON at `runs/inprocess-adapter-research/inprocess-adapter-map.json`: machine-readable evidence generated by the script; not committed unless the repo already tracks runs output.
- Modify `internal/tools/send_message_broute_adapter.go`: add `in_process_contract` mode that validates request shape and returns blocked/no-side-effect contract metadata.
- Modify `internal/tools/send_message_broute_adapter_test.go`: add tests for `in_process_contract` mode, including no accepted send and no side effects.
- Modify `internal/tools/send_message_uia_adapter.go`: extend the existing send connector env factory to route `ISPHERE_SEND_CONNECTOR_MODE=in_process_contract` to the B-route contract connector.
- Modify `internal/tools/send_message_uia_adapter_test.go`: prove the env factory builds the in-process contract connector.
- Modify `docs/source-discovery/capability-source-matrix.md`: point send-message/send-file next slices to the generated static map and keep production blocked.
---
### Task 1: Static In-Process Anchor Map
**Files:**
- Create: `scripts/extract-inprocess-adapter-map.ps1`
- Create: `docs/source-discovery/2026-07-12-inprocess-adapter-static-map.md`
**Interfaces:**
- Consumes: IL files under `runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c28-il/` and offline B-route reports.
- Produces: Markdown report and JSON with these top-level keys: `ok`, `decision`, `anchors`, `commands`, `required_runtime_state`, `stop_conditions`, `originals_modified`.
- [ ] **Step 1: Create the analyzer script**
Create `scripts/extract-inprocess-adapter-map.ps1` with these behaviors:
```powershell
param(
[string]$OutDir = "runs/inprocess-adapter-research",
[string]$ReportPath = "docs/source-discovery/2026-07-12-inprocess-adapter-static-map.md"
)
$ErrorActionPreference = 'Stop'
# Resolve repository root from the script location, not caller cwd.
# Read IL files only; never write into the sample directories.
# Extract anchors for AppContextManager, MessageScheduling, Chat, XMPPConnection,
# OffLineFileSend, FileUploadPara, FileUploadResult, FileTransfer, frmMain, and logged-in user/auth state.
# Emit JSON to $OutDir and Markdown to $ReportPath.
```
- [ ] **Step 2: Run the analyzer**
Run:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\extract-inprocess-adapter-map.ps1
```
Expected output contains:
```json
{
"ok": true,
"decision": "managed_in_process_adapter_contract_first",
"originals_modified": false
}
```
- [ ] **Step 3: Verify report content**
Run:
```powershell
Get-Content docs\source-discovery\2026-07-12-inprocess-adapter-static-map.md -Raw | Select-String -Pattern 'AppContextManager|MessageScheduling|Chat|FileUploadResult|in_process_contract|Stop conditions'
```
Expected: all listed terms are present.
---
### Task 2: Go Connector In-Process Contract Mode
**Files:**
- Modify: `internal/tools/send_message_broute_adapter.go`
- Modify: `internal/tools/send_message_broute_adapter_test.go`
- Modify: `internal/tools/send_message_uia_adapter.go`
- Modify: `internal/tools/send_message_uia_adapter_test.go`
**Interfaces:**
- Consumes: `SendMessageConnectorRequest` from `internal/tools/send_message_connector.go`.
- Produces: new connector mode string `in_process_contract` with blocked result:
- `Accepted: false`
- `Status: "blocked"`
- `ErrorCode: "broute_in_process_contract_only"`
- `ConnectorMode: "broute-in-process-contract"`
- `ProductionEnabled: false`
- `SideEffects["attached_hook"] == false`
- `SideEffects["sent_message"] == false`
- [ ] **Step 1: Add a failing test for contract mode**
Add this test to `internal/tools/send_message_broute_adapter_test.go`:
```go
func TestBRouteSendMessageConnectorInProcessContract(t *testing.T) {
connector := NewBRouteSendMessageConnector(BRouteSendAdapterConfig{Mode: "in_process_contract"})
result, err := connector.ExecuteSendMessage(context.Background(), SendMessageConnectorRequest{
TargetType: "direct",
TargetID: "u1",
TargetRef: "contact:u1",
ContentText: "hello",
ContentSHA256: strings.Repeat("a", 64),
ContentLength: 5,
IdempotencyKeySHA256: strings.Repeat("b", 64),
ExecutionMode: "production",
})
if err != nil {
t.Fatalf("in_process_contract should be a structured blocked result, not process error: %v", err)
}
if result.Accepted || result.ProductionEnabled {
t.Fatalf("contract mode must not accept production send: %+v", result)
}
if result.Status != "blocked" || result.ErrorCode != "broute_in_process_contract_only" {
t.Fatalf("unexpected contract result: %+v", result)
}
if result.ConnectorMode != "broute-in-process-contract" {
t.Fatalf("connector mode = %q", result.ConnectorMode)
}
if result.SideEffects["sent_message"] != false || result.SideEffects["attached_hook"] != false {
t.Fatalf("contract mode must report no side effects: %#v", result.SideEffects)
}
}
```
- [ ] **Step 2: Run the failing test**
Run:
```powershell
go test ./internal/tools -run TestBRouteSendMessageConnectorInProcessContract -count=1
```
Expected before implementation: FAIL because `in_process_contract` is not handled.
- [ ] **Step 3: Implement minimal mode branch**
In `internal/tools/send_message_broute_adapter.go`, add a `case "in_process_contract"` branch that calls `validateBRouteSendMessageRequest(request)` and returns a structured blocked result with no side effects.
- [ ] **Step 4: Add and run env factory coverage**
Add `TestSendMessageConnectorFromEnvBuildsInProcessContractConnector` to `internal/tools/send_message_uia_adapter_test.go` and update `NewSendMessageConnectorFromEnv()` so `ISPHERE_SEND_CONNECTOR_MODE=in_process_contract` returns `NewBRouteSendMessageConnector(BRouteSendAdapterConfig{Mode: "in_process_contract"})`.
Run:
```powershell
go test ./internal/tools -run 'Test(BRouteSendMessageConnector|SendMessageConnectorFromEnv)' -count=1
```
Expected: PASS.
- [ ] **Step 5: Run the targeted test again**
Run:
```powershell
go test ./internal/tools -run TestBRouteSendMessageConnectorInProcessContract -count=1
```
Expected: PASS.
---
### Task 3: Capability Matrix Correction
**Files:**
- Modify: `docs/source-discovery/capability-source-matrix.md`
**Interfaces:**
- Consumes: `docs/source-discovery/2026-07-12-inprocess-adapter-static-map.md`.
- Produces: updated business-facing capability status showing B-route next step is contract/in-process reachability, not production send.
- [ ] **Step 1: Update send-message and send-file rows**
Add the new report path to the evidence references and update next-slice language:
```markdown
- In-process adapter static map: `docs/source-discovery/2026-07-12-inprocess-adapter-static-map.md`
```
For send-message, state:
```markdown
Next slice: validate `in_process_contract` reachability in a logged-in runtime; production remains blocked until adapter invocation plus sent-record/content-hash/ack evidence exists.
```
For send-file, state:
```markdown
Next slice: validate logged-in access to `IFileTransfer.FileUpload` and returned `FileUploadResult.FileID`; production file upload/send remains blocked until online evidence exists.
```
- [ ] **Step 2: Verify diff contains no RPA promotion**
Run:
```powershell
git diff -- docs\source-discovery\capability-source-matrix.md | Select-String -Pattern 'RPA|in_process|production remains blocked|FileUploadResult'
```
Expected: in-process language appears and RPA remains backup-only.
---
### Task 4: Verification and Branch Closure
**Files:**
- All files from Tasks 1-3.
**Interfaces:**
- Consumes: scripts and tests from previous tasks.
- Produces: committed and pushed branch `codex/in-process-adapter-research`.
- [ ] **Step 1: Run static analyzer**
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\extract-inprocess-adapter-map.ps1
```
Expected: `ok=true`, `decision=managed_in_process_adapter_contract_first`, `originals_modified=false`.
- [ ] **Step 2: Run targeted tests**
```powershell
go test ./internal/tools -run TestBRouteSendMessageConnector -count=1
```
Expected: PASS.
- [ ] **Step 3: Run full tests**
```powershell
go test ./...
```
Expected: PASS.
- [ ] **Step 4: Run diff hygiene**
```powershell
git diff --check
git diff --cached --check
```
Expected: no output and exit code 0 after staging.
- [ ] **Step 5: Commit and push**
```powershell
git add scripts\extract-inprocess-adapter-map.ps1 docs\source-discovery\2026-07-12-inprocess-adapter-static-map.md docs\source-discovery\capability-source-matrix.md internal\tools\send_message_broute_adapter.go internal\tools\send_message_broute_adapter_test.go docs\superpowers\plans\2026-07-12-in-process-adapter-research.md
git commit -m "feat: add in-process adapter research contract"
git push -u gitea codex/in-process-adapter-research
```
Expected: branch pushed to `gitea/codex/in-process-adapter-research`.
---
## Self-Review
- Spec coverage: The plan covers B-route in-process research, static evidence, Go connector contract, capability matrix, verification, commit, and push.
- Placeholder scan: No task uses TBD/TODO/fill-in-later language; every implementation task names exact files and commands.
- Type consistency: `in_process_contract` maps to `broute-in-process-contract`; `SendMessageConnectorResult.SideEffects` reuses the existing `sendMessageNoSideEffects()` shape.

View File

@@ -52,6 +52,26 @@ func (c bRouteSendMessageConnector) ExecuteSendMessage(_ context.Context, reques
ErrorMessage: "B-route adapter dry_run_contract mode validates request shape only and does not start a sidecar",
ConnectorMode: "broute-dry-run-contract",
}, nil
case "in_process_contract":
if err := validateBRouteSendMessageRequest(request); err != nil {
return SendMessageConnectorResult{
Accepted: false,
Status: "failed",
ErrorCode: "broute_invalid_request",
ErrorMessage: err.Error(),
ConnectorMode: "broute-in-process-contract",
SideEffects: sendMessageNoSideEffects(),
}, nil
}
return SendMessageConnectorResult{
Accepted: false,
Status: "blocked",
ErrorCode: "broute_in_process_contract_only",
ErrorMessage: "B-route in_process_contract mode validates the future in-process adapter contract only; logged-in runtime reachability and sent-record evidence are still required",
ConnectorMode: "broute-in-process-contract",
ProductionEnabled: false,
SideEffects: sendMessageNoSideEffects(),
}, nil
default:
result := SendMessageConnectorResult{
Accepted: false,

View File

@@ -53,3 +53,32 @@ func TestBRouteSendMessageConnectorDryRunContract(t *testing.T) {
t.Fatalf("unexpected dry-run result: %+v", result)
}
}
func TestBRouteSendMessageConnectorInProcessContract(t *testing.T) {
connector := NewBRouteSendMessageConnector(BRouteSendAdapterConfig{Mode: "in_process_contract"})
result, err := connector.ExecuteSendMessage(context.Background(), SendMessageConnectorRequest{
TargetType: "direct",
TargetID: "u1",
TargetRef: "contact:u1",
ContentText: "hello",
ContentSHA256: strings.Repeat("a", 64),
ContentLength: 5,
IdempotencyKeySHA256: strings.Repeat("b", 64),
ExecutionMode: "production",
})
if err != nil {
t.Fatalf("in_process_contract should be a structured blocked result, not process error: %v", err)
}
if result.Accepted || result.ProductionEnabled {
t.Fatalf("contract mode must not accept production send: %+v", result)
}
if result.Status != "blocked" || result.ErrorCode != "broute_in_process_contract_only" {
t.Fatalf("unexpected contract result: %+v", result)
}
if result.ConnectorMode != "broute-in-process-contract" {
t.Fatalf("connector mode = %q", result.ConnectorMode)
}
if result.SideEffects["sent_message"] != false || result.SideEffects["attached_hook"] != false {
t.Fatalf("contract mode must report no side effects: %#v", result.SideEffects)
}
}

View File

@@ -53,6 +53,9 @@ type uiaSendMessageConnector struct {
func NewSendMessageConnectorFromEnv() SendMessageConnector {
mode := strings.TrimSpace(strings.ToLower(os.Getenv(EnvSendConnectorMode)))
if mode == "in_process_contract" || mode == "in-process-contract" {
return NewBRouteSendMessageConnector(BRouteSendAdapterConfig{Mode: "in_process_contract"})
}
if mode != "uia_rpa" && mode != "uia-rpa" {
return nil
}

View File

@@ -2,6 +2,7 @@ package tools
import (
"context"
"strings"
"testing"
)
@@ -103,6 +104,31 @@ func TestSendMessageConnectorFromEnvBuildsUiaRPAConnector(t *testing.T) {
}
}
func TestSendMessageConnectorFromEnvBuildsInProcessContractConnector(t *testing.T) {
t.Setenv(EnvSendConnectorMode, "in_process_contract")
connector := NewSendMessageConnectorFromEnv()
if connector == nil {
t.Fatalf("NewSendMessageConnectorFromEnv returned nil for in_process_contract config")
}
result, err := connector.ExecuteSendMessage(context.Background(), SendMessageConnectorRequest{
TargetType: "direct",
TargetID: "u1",
TargetRef: "contact:u1",
ContentText: "hello",
ContentSHA256: strings.Repeat("a", 64),
ContentLength: 5,
IdempotencyKeySHA256: strings.Repeat("b", 64),
ExecutionMode: sendMessageProductionMode,
})
if err != nil {
t.Fatalf("in_process_contract should return structured blocked result, got err=%v", err)
}
if result.Accepted || result.ProductionEnabled || result.ErrorCode != "broute_in_process_contract_only" {
t.Fatalf("unexpected in-process contract result: %+v", result)
}
}
type fakeUiaHelperCaller struct {
response uiaHelperResponse
err error

View File

@@ -0,0 +1,168 @@
param(
[string]$OutputDir = "runs/offline-broute-reverse",
[string]$ReportPath = "docs/source-discovery/2026-07-12-offline-broute-reverse-index.md"
)
$ErrorActionPreference = "Stop"
$repo = (Resolve-Path -LiteralPath (Join-Path $PSScriptRoot "..")).Path
$outDir = Join-Path $repo $OutputDir
$reportFullPath = Join-Path $repo $ReportPath
New-Item -ItemType Directory -Force -Path $outDir | Out-Null
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $reportFullPath) | Out-Null
$samples = @(
@{
path = "runs/offline-real-client-window/full/zyl/Impp/IMPlatformClient.exe"
role = "main managed client; text send, chat window, plugin/IPC candidates"
expected_sha256 = "E2966E58360DAEEBF178410A961E2DC52748C63E9CCBD94BD6EC8434A1A09CB7"
},
@{
path = "runs/offline-real-client-window/full/zyl/Impp/IMPP.Service.dll"
role = "file upload service candidates"
expected_sha256 = "F859DE2F34E024B5F372D95F22CBF8A018C780F24203E7A76D392E52BD90CADD"
},
@{
path = "runs/offline-real-client-window/full/zyl/Impp/IMPP.Interface.dll"
role = "service/interface contract candidates"
expected_sha256 = "DD093CF61FAE85C2D2581F289B01AA477546712E098FEF81272FDD989E50D12D"
},
@{
path = "runs/offline-real-client-window/full/zyl/Impp/IMPP.Model.dll"
role = "model/parameter types"
expected_sha256 = "7CBABDD23A7234D15E294C549EEEC78EFBAD6E957CD45A6E8A85309349A624A5"
},
@{
path = "runs/offline-real-client-window/full/zyl/Impp/IMPP.UI.dll"
role = "UI/plugin helpers and possible send controls"
expected_sha256 = "4C61212519C01D1B731ED4F20DF3411C491616F4ADA98A4529722A6AA3689E6D"
},
@{
path = "runs/offline-real-client-window/full/zyl/Impp/IMPP.Common.dll"
role = "shared utility and message types"
expected_sha256 = "02A47C99C27C9BFE2BADC438389300C92220B07609BD87C48B4B5E1B4EE6AEB4"
},
@{
path = "runs/offline-real-client-window/full/zyl/Impp/IMPP.Helper.dll"
role = "helper abstractions"
expected_sha256 = "30932D082B6678699C832C63F923E01EAD84674FAEDB613D631E034E03742FB9"
},
@{
path = "runs/offline-real-client-window/full/zyl/Impp/smack.dll"
role = "XMPP chat/send layer"
expected_sha256 = "BAD0BB0591765DB153B17CECC1112B0BBDBF3B1D3370DDF973F91974E92CEC66"
},
@{
path = "runs/offline-real-client-window/full/zyl/Impp/TcpFileTransfer.dll"
role = "native/transfer candidate"
expected_sha256 = "6C4874B46D1E7DC04C9B6784180603452400B881E04509D464A0D58814EFEDA7"
},
@{
path = "runs/offline-real-client-window/full/zyl/Impp/HttpServerLib.dll"
role = "local API/IPC candidate"
expected_sha256 = "FFDB633216AE332B8EDFFC83E2AE546B7A80144C659FF4053FDFE4FE382A8D12"
},
@{
path = "runs/offline-real-client-window/full/zyl/Impp/INetwork.dll"
role = "network abstraction candidate"
expected_sha256 = "E40BE4EE2439E4280461F4D2BADB318A5F4572428F069AB6D17B4C4F0E8CFAC9"
},
@{
path = "runs/offline-real-client-window/full/zyl/Impp/IOClientNetwork.dll"
role = "network implementation candidate"
expected_sha256 = "64CA231A614771325741A5F098E52EBF20F7190E339B64962DE2EDEDCFFFF904"
}
)
$entries = foreach ($sample in $samples) {
$fullPath = Join-Path $repo $sample.path
$exists = Test-Path -LiteralPath $fullPath -PathType Leaf
$item = $null
$sha256 = ""
$matches = $false
if ($exists) {
$item = Get-Item -LiteralPath $fullPath
$sha256 = (Get-FileHash -LiteralPath $fullPath -Algorithm SHA256).Hash.ToUpperInvariant()
$matches = ($sha256 -eq $sample.expected_sha256)
}
[pscustomobject]@{
path = $sample.path
file_name = Split-Path -Leaf $sample.path
role = $sample.role
exists = $exists
size_bytes = if ($item) { $item.Length } else { $null }
last_write_time = if ($item) { $item.LastWriteTime.ToString("o") } else { $null }
sha256 = $sha256
expected_sha256 = $sample.expected_sha256
sha256_matches_expected = $matches
}
}
$summary = [pscustomobject]@{
generated_at = (Get-Date).ToUniversalTime().ToString("o")
repository = $repo
output_dir = $OutputDir
samples_total = @($entries).Count
samples_present = @($entries | Where-Object { $_.exists }).Count
hash_matches = @($entries | Where-Object { $_.sha256_matches_expected }).Count
originals_copied = $false
originals_modified = $false
entries = $entries
}
$jsonPath = Join-Path $outDir "index.json"
$summary | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath $jsonPath -Encoding UTF8
$lines = New-Object System.Collections.Generic.List[string]
$lines.Add("# Offline B-Route Reverse Index")
$lines.Add("")
$lines.Add("Date: 2026-07-12")
$lines.Add("")
$lines.Add("## Scope")
$lines.Add("")
$lines.Add("This index records the read-only offline samples for B-route reverse engineering. The script reads metadata and SHA256 hashes only; it does not copy or modify the original binaries.")
$lines.Add("")
$lines.Add("## Summary")
$lines.Add("")
$lines.Add("- Samples total: $($summary.samples_total)")
$lines.Add("- Samples present: $($summary.samples_present)")
$lines.Add("- Hash matches: $($summary.hash_matches)")
$lines.Add("- Originals copied: false")
$lines.Add("- Originals modified: false")
$lines.Add("- Machine JSON: ``$OutputDir/index.json``")
$lines.Add("")
$lines.Add("## Sample table")
$lines.Add("")
$lines.Add("| Sample | Role | Size | SHA256 match | SHA256 |")
$lines.Add("| --- | --- | ---: | --- | --- |")
foreach ($entry in $entries) {
$size = if ($null -ne $entry.size_bytes) { [string]$entry.size_bytes } else { "missing" }
$match = if ($entry.sha256_matches_expected) { "yes" } else { "no" }
$sha = if ($entry.sha256) { $entry.sha256 } else { "missing" }
$lines.Add("| ``$($entry.path)`` | $($entry.role) | $size | $match | ``$sha`` |")
}
$lines.Add("")
$lines.Add("## Verified facts")
$lines.Add("")
$lines.Add("- All metadata came from local filesystem reads under the repository workspace.")
$lines.Add("- The expected primary B-route samples are present if `Samples present` equals `Samples total`.")
$lines.Add("- Hash matching only proves local file identity against this plan's recorded sample list; it does not prove runtime invocability.")
$lines.Add("")
$lines.Add("## Next reverse targets")
$lines.Add("")
$lines.Add("1. Text-send static call graph: `SendTxtMessageByJid`, `MessageScheduling.SendChatMessage`, `Chat.SendMessage`, `XMPPConnection.send`.")
$lines.Add("2. File-send/upload static call graph: `OffLineFileSend.sendFile`, `FileTransfer.FileUpload`, `AsynFileUpload`, `sendFileMessage`.")
$lines.Add("3. Bridge/IPC/plugin map: `HttpServerLib`, plugin loaders, local HTTP, named pipes, command-line switches, services.")
($lines -join "`n") + "`n" | Set-Content -LiteralPath $reportFullPath -Encoding UTF8
[pscustomobject]@{
ok = $true
json_path = $jsonPath
report_path = $reportFullPath
samples_total = $summary.samples_total
samples_present = $summary.samples_present
hash_matches = $summary.hash_matches
originals_copied = $false
originals_modified = $false
} | ConvertTo-Json -Depth 4

View File

@@ -0,0 +1,537 @@
param(
[string]$IlDir = "runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c28-il",
[string]$BinaryDir = "runs/offline-real-client-window/full/zyl/Impp",
[string]$OutputDir = "runs/offline-broute-reverse",
[string]$ReportPath = "docs/source-discovery/2026-07-12-broute-bridge-static-map.md",
[int]$WindowRadius = 4,
[int]$MaxEvidencePerCandidate = 18
)
$ErrorActionPreference = "Stop"
$repo = (Resolve-Path -LiteralPath (Join-Path $PSScriptRoot "..")).Path
$ilDirFull = Join-Path $repo $IlDir
$binaryDirFull = Join-Path $repo $BinaryDir
$outDir = Join-Path $repo $OutputDir
$reportFullPath = Join-Path $repo $ReportPath
New-Item -ItemType Directory -Force -Path $outDir | Out-Null
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $reportFullPath) | Out-Null
$textSources = @(
@{ path = "IMPlatformClient.exe.il"; role = "main client IL; login, plugin manager, local HTTP starter, chat/runtime" },
@{ path = "IMPP.Common.dll.il"; role = "common helpers; WinCommand, ProcessComm, DTOs" },
@{ path = "IMPP.ISphere.exe.il"; role = "ISphere companion app IL; CEF and command helpers" },
@{ path = "IMPP.UI.dll.il"; role = "UI/browser support IL" },
@{ path = "IMPP.Service.dll.il"; role = "file service implementation IL" },
@{ path = "smack.dll.il"; role = "XMPP/socks5/network IL" }
)
$binarySources = @(
@{ path = "HttpServerLib.dll"; role = "local HTTP server framework binary" },
@{ path = "IMPlatformClient.Web.exe"; role = "CEF/web helper process binary" },
@{ path = "INetwork.dll"; role = "native network abstraction" },
@{ path = "IOClientNetwork.dll"; role = "native network implementation" },
@{ path = "IMPlatformClient.exe"; role = "main client binary" }
)
$liveProbeSources = @(
"runs/returned-live-probe/isphere-live-probe-20260710-121958/isphere-live-probe-20260710-121958/services_registry_shortcuts.json",
"runs/returned-live-probe/isphere-live-probe-20260710-121958/isphere-live-probe-20260710-121958/network_inventory.json"
)
$candidates = @(
@{
key = "local_http_win_server"
display = "frmLogin.StartWinServer / HttpServerLib.HttpService"
category = "localhost_http"
classification = "requires_logged_in_process"
usable_for_broute_send = $false
recommendation = "do_not_pursue_before_in_process_adapter"
reason = "Static IL builds a local HTTP service from logged-in user/auth state, but no send route or active live local listener was confirmed."
patterns = @("StartWinServer", "HttpServerLib", "HttpService::\.ctor", "HttpServer::Start", "GetFreePort", "0\.0\.0\.0", "messageAuth", "RepairDatabase")
},
@{
key = "http_route_framework"
display = "HttpServerLib route/module framework"
category = "localhost_http"
classification = "static_only_unknown"
usable_for_broute_send = $false
recommendation = "no_existing_ipc_first"
reason = "HttpServerLib has ServiceModule/RouteAttribute primitives, but client IL does not show RegisterModule or send-message routes."
patterns = @("RouteAttribute", "RouteMethod", "ServiceModule", "ServiceRoute", "RegisterModule", "OnGet\s*\(", "OnPost\s*\(", "ExecuteRoute", "SearchRoute")
},
@{
key = "plugin_named_pipe_stub"
display = "PluginLightAppMulProcessCommunication NamedPipeServerStream"
category = "named_pipe"
classification = "not_a_bridge"
usable_for_broute_send = $false
recommendation = "do_not_use"
reason = "A NamedPipeServerStream field exists, but StartLightAppMultProssCommunication has a one-instruction ret body."
patterns = @("NamedPipeServerStream", "PluginLightAppMulProcessCommunication", "StartLightAppMultProssCommunication", "MulProcess", "LightApp")
},
@{
key = "process_comm_wm_copydata"
display = "IMPP.Common.Helper.ProcessComm WM_COPYDATA helper"
category = "window_message"
classification = "static_only_unknown"
usable_for_broute_send = $false
recommendation = "not_a_send_bridge"
reason = "ProcessComm can send WM_COPYDATA to a foreground or titled window, but no receive handler or send-command contract is confirmed."
patterns = @("IMPP\.Common\.Helper\.ProcessComm", "\bProcessComm\b", "COPYDATASTRUCT", "WM_COPYDATA", "SendMessageToTargetWindow", "FindWindow\(string lpClassName", "GetForegroundWindow\(\)")
},
@{
key = "plugin_manager_command_surface"
display = "PluginManager / IMPlugin command surface"
category = "plugin"
classification = "requires_logged_in_process"
usable_for_broute_send = $false
recommendation = "plugin_extension_not_first"
reason = "Plugin evidence is UI/app-store/context-menu oriented and depends on logged-in PluginManager state; no Assembly.Load/LoadFrom or send API bridge was confirmed."
patterns = @("PluginManager", "IMPlugin::get_Command", "LoadPluginContextMenu", "FrmAppStore", "FrmCefHomePage", "ShowPlugins", "Assembly\.Load", "LoadFrom", "AddPluginInfo")
},
@{
key = "cef_web_helper"
display = "IMPlatformClient.Web / CEF helper"
category = "child_process"
classification = "requires_logged_in_process"
usable_for_broute_send = $false
recommendation = "preview_only_not_send"
reason = "The web helper/CEF surface exists, but static evidence points to UI/plugin browser support, not an external send/file API."
patterns = @("IMPlatformClient\.Web", "CefProcessName", "CefRuntime", "WinCefBrowser", "NavigateTo", "SendProcessMessage", "V8Context")
},
@{
key = "native_network_stack"
display = "INetwork / IOClientNetwork native stack"
category = "native_network"
classification = "not_a_bridge"
usable_for_broute_send = $false
recommendation = "do_not_pursue_as_ipc"
reason = "Native NETIO send/recv symbols are low-level transport, not a local command bridge into logged-in chat objects."
patterns = @("INetwork", "IOClientNetwork", "NETIO_", "NETIO_C_", "StreamClient", "RegistRecvCallback", "SendPacket", "BasePipe")
},
@{
key = "live_probe_named_pipe"
display = "returned live-probe named pipe inventory"
category = "named_pipe"
classification = "static_only_unknown"
usable_for_broute_send = $false
recommendation = "do_not_assume_isphere_api"
reason = "Live probe saw \\.\\pipe\\zfpinject-msg-server, but no matching iSphere static string or send contract was found in the configured samples."
patterns = @("zfpinject-msg-server", "named_pipes", "connections", "remote_port", "10088")
},
@{
key = "local_tcp_listener_candidates"
display = "local TcpListener candidates"
category = "tcp_listener"
classification = "not_a_bridge"
usable_for_broute_send = $false
recommendation = "not_existing_ipc"
reason = "TcpListener evidence is tied to TCP file manage or smack socks5, not a command API for text/file send. Returned live probe had only one remote XMPP connection."
patterns = @("TcpListener", "TCPFileManager::_listener", "TCPSocks5Server", "GetActiveTcpListeners", "BeginAcceptSocket", "remote_port")
}
)
function Get-RelativePath([string]$Path) {
if ($Path.StartsWith($repo, [System.StringComparison]::OrdinalIgnoreCase)) {
return $Path.Substring($repo.Length).TrimStart('\', '/')
}
return $Path
}
function Get-TextEvidenceKind([string]$Line) {
if ($Line -match "^\s*\.class\b") { return "type_definition" }
if ($Line -match "^\s*\.method\b") { return "method_header" }
if ($Line -match "\bend of method\b") { return "method_end" }
if ($Line -match "\bcall(?:virt)?\b") { return "callsite" }
if ($Line -match "\bnewobj\b") { return "constructor_call" }
if ($Line -match "\bldstr\b") { return "string_literal" }
if ($Line -match "^\s*(instance|static|StartWinServer|GetFreePort|SendMessageToTargetWindow)\b.*\(") { return "signature_continuation" }
return "reference"
}
function Get-MethodContext($Lines, [int]$Index) {
$start = [Math]::Max(0, $Index - 120)
$methodHeader = $null
$classHeader = $null
for ($i = $Index; $i -ge $start; $i--) {
$line = $Lines[$i]
if ($null -eq $methodHeader -and $line -match "^\s*\.method\b") {
$methodHeader = [pscustomobject]@{ line_number = $i + 1; text = $line.Trim() }
}
if ($null -eq $classHeader -and $line -match "^\s*\.class\b") {
$classHeader = [pscustomobject]@{ line_number = $i + 1; text = $line.Trim() }
}
if ($methodHeader -and $classHeader) { break }
}
[pscustomobject]@{ method_header = $methodHeader; class_header = $classHeader }
}
function New-TextEvidence($Lines, [int]$Index, [string]$SourceRel) {
$from = [Math]::Max(0, $Index - $WindowRadius)
$to = [Math]::Min($Lines.Count - 1, $Index + $WindowRadius)
$window = New-Object System.Collections.Generic.List[object]
for ($i = $from; $i -le $to; $i++) {
$window.Add([pscustomobject]@{ line_number = $i + 1; text = $Lines[$i].TrimEnd() })
}
$context = Get-MethodContext -Lines $Lines -Index $Index
[pscustomobject]@{
source = $SourceRel
source_type = "text_il"
line_number = $Index + 1
string_index = $null
kind = Get-TextEvidenceKind -Line $Lines[$Index]
text = $Lines[$Index].Trim()
method_header = $context.method_header
class_header = $context.class_header
window = $window
}
}
function Get-PrintableStrings([string]$Path, [int]$MinLength = 4) {
$bytes = [System.IO.File]::ReadAllBytes($Path)
$strings = New-Object System.Collections.Generic.List[string]
$sb = New-Object System.Text.StringBuilder
foreach ($b in $bytes) {
if ($b -ge 32 -and $b -le 126) {
[void]$sb.Append([char]$b)
} else {
if ($sb.Length -ge $MinLength) { $strings.Add($sb.ToString()) }
$sb.Clear() | Out-Null
}
}
if ($sb.Length -ge $MinLength) { $strings.Add($sb.ToString()) }
$sb = New-Object System.Text.StringBuilder
for ($i = 0; $i -lt ($bytes.Length - 1); $i += 2) {
$b = $bytes[$i]
$z = $bytes[$i + 1]
if ($z -eq 0 -and $b -ge 32 -and $b -le 126) {
[void]$sb.Append([char]$b)
} else {
if ($sb.Length -ge $MinLength) { $strings.Add($sb.ToString()) }
$sb.Clear() | Out-Null
}
}
if ($sb.Length -ge $MinLength) { $strings.Add($sb.ToString()) }
return $strings.ToArray()
}
function Get-HttpServerReflection([string]$Path) {
$result = [ordered]@{ path = Get-RelativePath -Path $Path; ok = $false; error = ""; types = @() }
try {
$asm = [System.Reflection.Assembly]::LoadFile($Path)
$types = New-Object System.Collections.Generic.List[object]
foreach ($type in $asm.GetTypes()) {
if ($type.FullName -notmatch "HTTPServerLib\.(HttpServer|HttpService|ServiceModule|ServiceRoute|RouteAttribute|IServer|ActionResult)") { continue }
$ctors = @($type.GetConstructors([System.Reflection.BindingFlags]'Public,NonPublic,Instance') | ForEach-Object {
$params = @($_.GetParameters() | ForEach-Object { $_.ParameterType.Name + " " + $_.Name })
[pscustomobject]@{ is_public = $_.IsPublic; signature = "$($type.Name)($([string]::Join(', ', $params)))" }
})
$methods = @($type.GetMethods([System.Reflection.BindingFlags]'Public,NonPublic,Instance,Static,DeclaredOnly') | ForEach-Object {
$params = @($_.GetParameters() | ForEach-Object { $_.ParameterType.Name + " " + $_.Name })
[pscustomobject]@{ name = $_.Name; signature = "$($_.ReturnType.Name) $($_.Name)($([string]::Join(', ', $params)))" }
})
$types.Add([pscustomobject]@{ full_name = $type.FullName; constructors = $ctors; methods = $methods })
}
$result.ok = $true
$result.types = $types.ToArray()
} catch {
$result.error = $_.Exception.Message
}
return [pscustomobject]$result
}
$textSourceResults = New-Object System.Collections.Generic.List[object]
$binarySourceResults = New-Object System.Collections.Generic.List[object]
$candidateBuckets = @{}
foreach ($candidate in $candidates) {
$candidateBuckets[[string]$candidate['key']] = New-Object System.Collections.Generic.List[object]
}
foreach ($source in $textSources) {
$sourceFullPath = Join-Path $ilDirFull ([string]$source['path'])
$sourceRel = Get-RelativePath -Path $sourceFullPath
if (-not (Test-Path -LiteralPath $sourceFullPath -PathType Leaf)) {
$textSourceResults.Add([pscustomobject]@{ path = $sourceRel; role = $source['role']; exists = $false; line_count = 0; size_bytes = $null })
continue
}
$item = Get-Item -LiteralPath $sourceFullPath
$lines = [System.IO.File]::ReadAllLines($sourceFullPath)
$textSourceResults.Add([pscustomobject]@{ path = $sourceRel; role = $source['role']; exists = $true; line_count = $lines.Count; size_bytes = $item.Length })
foreach ($candidate in $candidates) {
$key = [string]$candidate['key']
$compiled = @($candidate['patterns'] | ForEach-Object { [regex]::new($_, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase) })
for ($i = 0; $i -lt $lines.Count; $i++) {
$line = $lines[$i]
foreach ($rx in $compiled) {
if ($rx.IsMatch($line)) {
$candidateBuckets[$key].Add((New-TextEvidence -Lines $lines -Index $i -SourceRel $sourceRel))
break
}
}
}
}
}
foreach ($source in $binarySources) {
$sourceFullPath = Join-Path $binaryDirFull ([string]$source['path'])
$sourceRel = Get-RelativePath -Path $sourceFullPath
if (-not (Test-Path -LiteralPath $sourceFullPath -PathType Leaf)) {
$binarySourceResults.Add([pscustomobject]@{ path = $sourceRel; role = $source['role']; exists = $false; string_count = 0; size_bytes = $null })
continue
}
$item = Get-Item -LiteralPath $sourceFullPath
$strings = Get-PrintableStrings -Path $sourceFullPath -MinLength 4
$binarySourceResults.Add([pscustomobject]@{ path = $sourceRel; role = $source['role']; exists = $true; string_count = $strings.Count; size_bytes = $item.Length })
foreach ($candidate in $candidates) {
$key = [string]$candidate['key']
$compiled = @($candidate['patterns'] | ForEach-Object { [regex]::new($_, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase) })
for ($i = 0; $i -lt $strings.Count; $i++) {
$s = $strings[$i]
foreach ($rx in $compiled) {
if ($rx.IsMatch($s)) {
$candidateBuckets[$key].Add([pscustomobject]@{
source = $sourceRel
source_type = "binary_string"
line_number = $null
string_index = $i
kind = "binary_string"
text = $s
method_header = $null
class_header = $null
window = @()
})
break
}
}
}
}
}
$liveProbe = New-Object System.Collections.Generic.List[object]
foreach ($relPath in $liveProbeSources) {
$fullPath = Join-Path $repo $relPath
if (Test-Path -LiteralPath $fullPath -PathType Leaf) {
$raw = Get-Content -LiteralPath $fullPath -Raw
$liveProbe.Add([pscustomobject]@{ path = $relPath; exists = $true; length = $raw.Length; data = ($raw | ConvertFrom-Json) })
foreach ($candidate in $candidates) {
$key = [string]$candidate['key']
$compiled = @($candidate['patterns'] | ForEach-Object { [regex]::new($_, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase) })
foreach ($rx in $compiled) {
if ($rx.IsMatch($raw)) {
$candidateBuckets[$key].Add([pscustomobject]@{
source = $relPath
source_type = "live_probe_json"
line_number = $null
string_index = $null
kind = "live_probe_json"
text = ($raw -replace "\s+", " ").Trim()
method_header = $null
class_header = $null
window = @()
})
break
}
}
}
} else {
$liveProbe.Add([pscustomobject]@{ path = $relPath; exists = $false; length = 0; data = $null })
}
}
$httpServerPath = Join-Path $binaryDirFull "HttpServerLib.dll"
$httpReflection = if (Test-Path -LiteralPath $httpServerPath -PathType Leaf) { Get-HttpServerReflection -Path $httpServerPath } else { [pscustomobject]@{ path = Get-RelativePath -Path $httpServerPath; ok = $false; error = "missing"; types = @() } }
$httpReflectionPath = Join-Path $outDir "httpserverlib-reflection.json"
$httpReflection | ConvertTo-Json -Depth 10 | Set-Content -LiteralPath $httpReflectionPath -Encoding UTF8
if ($httpReflection.ok) {
$reflectionText = ($httpReflection.types | ConvertTo-Json -Depth 8 -Compress)
foreach ($candidate in $candidates) {
$key = [string]$candidate['key']
$compiled = @($candidate['patterns'] | ForEach-Object { [regex]::new($_, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase) })
foreach ($rx in $compiled) {
if ($rx.IsMatch($reflectionText)) {
$candidateBuckets[$key].Add([pscustomobject]@{
source = Get-RelativePath -Path $httpReflectionPath
source_type = "reflection"
line_number = $null
string_index = $null
kind = "reflection_metadata"
text = "HttpServerLib reflection exposes matching types/methods; see httpserverlib-reflection.json"
method_header = $null
class_header = $null
window = @()
})
break
}
}
}
}
$candidateResults = New-Object System.Collections.Generic.List[object]
foreach ($candidate in $candidates) {
$key = [string]$candidate['key']
$allEvidence = $candidateBuckets[$key].ToArray()
$evidenceForReport = @(
$allEvidence |
Sort-Object @{ Expression = { if ($_.source_type -eq "text_il") { 0 } elseif ($_.source_type -eq "reflection") { 1 } elseif ($_.source_type -eq "live_probe_json") { 2 } else { 3 } } }, source, line_number, string_index |
Select-Object -First $MaxEvidencePerCandidate
)
$classification = if ($allEvidence.Count -eq 0) { "not_found" } else { [string]$candidate['classification'] }
$candidateResults.Add([pscustomobject]@{
key = $key
display = $candidate['display']
category = $candidate['category']
classification = $classification
usable_for_broute_send = [bool]$candidate['usable_for_broute_send']
recommendation = $candidate['recommendation']
reason = $candidate['reason']
match_count = $allEvidence.Count
evidence = $evidenceForReport
})
}
$recommendation = [pscustomobject]@{
pursue_existing_ipc_or_plugin_first = $false
decision = "in_process_adapter_research"
fallback_boundary = "external_sidecar_preview_only_until_bridge_exists"
rationale = "Offline static evidence found no existing local IPC/plugin route that exposes send-message or send-file. HttpServerLib and plugin surfaces either require logged-in runtime state or are UI/framework-only; the named-pipe stub is empty."
}
$summary = [pscustomobject]@{
generated_at = (Get-Date).ToUniversalTime().ToString("o")
repository = $repo
il_dir = $IlDir
binary_dir = $BinaryDir
text_sources = $textSourceResults
binary_sources = $binarySourceResults
live_probe = $liveProbe
httpserverlib_reflection = Get-RelativePath -Path $httpReflectionPath
candidates = $candidateResults
recommendation = $recommendation
originals_copied = $false
originals_modified = $false
}
$jsonPath = Join-Path $outDir "bridge-map.json"
$summary | ConvertTo-Json -Depth 14 | Set-Content -LiteralPath $jsonPath -Encoding UTF8
$linesOut = New-Object System.Collections.Generic.List[string]
$linesOut.Add("# B-Route Bridge/IPC/Plugin Static Map")
$linesOut.Add("")
$linesOut.Add("Date: 2026-07-12")
$linesOut.Add("")
$linesOut.Add("## Scope")
$linesOut.Add("")
$linesOut.Add("This report uses offline IL, binary string metadata, reflection metadata for ``HttpServerLib.dll``, and returned live-probe JSON. It does not log in, open sockets, attach hooks, inject into a process, replay traffic, or mutate client binaries.")
$linesOut.Add("")
$linesOut.Add("Machine-readable evidence: ``$OutputDir/bridge-map.json``")
$linesOut.Add("Reflection metadata: ``$OutputDir/httpserverlib-reflection.json``")
$linesOut.Add("")
$linesOut.Add("## Recommendation")
$linesOut.Add("")
$linesOut.Add("| Question | Answer |")
$linesOut.Add("| --- | --- |")
$linesOut.Add("| Should B-route pursue existing IPC/plugin before an in-process adapter? | **No** |")
$linesOut.Add("| Offline decision | ``$($recommendation.decision)`` |")
$linesOut.Add("| External sidecar boundary | ``$($recommendation.fallback_boundary)`` |")
$linesOut.Add("| Reason | $($recommendation.rationale) |")
$linesOut.Add("")
$linesOut.Add("## Sources")
$linesOut.Add("")
$linesOut.Add("### Text/IL sources")
$linesOut.Add("")
$linesOut.Add("| Source | Role | Exists | Lines | Size bytes |")
$linesOut.Add("| --- | --- | --- | ---: | ---: |")
foreach ($sourceResult in $textSourceResults) {
$exists = if ($sourceResult.exists) { "yes" } else { "no" }
$sizeText = if ($null -ne $sourceResult.size_bytes) { [string]$sourceResult.size_bytes } else { "" }
$linesOut.Add("| ``$($sourceResult.path)`` | $($sourceResult.role) | $exists | $($sourceResult.line_count) | $sizeText |")
}
$linesOut.Add("")
$linesOut.Add("### Binary/string sources")
$linesOut.Add("")
$linesOut.Add("| Source | Role | Exists | Strings | Size bytes |")
$linesOut.Add("| --- | --- | --- | ---: | ---: |")
foreach ($sourceResult in $binarySourceResults) {
$exists = if ($sourceResult.exists) { "yes" } else { "no" }
$sizeText = if ($null -ne $sourceResult.size_bytes) { [string]$sourceResult.size_bytes } else { "" }
$linesOut.Add("| ``$($sourceResult.path)`` | $($sourceResult.role) | $exists | $($sourceResult.string_count) | $sizeText |")
}
$linesOut.Add("")
$linesOut.Add("## Candidate classification")
$linesOut.Add("")
$linesOut.Add("| Candidate | Category | Classification | Usable for B-route send | Recommendation | Matches |")
$linesOut.Add("| --- | --- | --- | --- | --- | ---: |")
foreach ($candidateResult in $candidateResults) {
$usable = if ($candidateResult.usable_for_broute_send) { "yes" } else { "no" }
$linesOut.Add("| ``$($candidateResult.display)`` | ``$($candidateResult.category)`` | ``$($candidateResult.classification)`` | $usable | ``$($candidateResult.recommendation)`` | $($candidateResult.match_count) |")
}
$linesOut.Add("")
$linesOut.Add("## Verified facts")
$linesOut.Add("")
$linesOut.Add("- ``frmLogin.StartWinServer`` constructs ``HTTPServerLib.HttpService`` on ``0.0.0.0`` and starts ``HttpServer.Start`` in a thread, but it depends on ``IMPPManager.UserInfo`` and ``ServiceManager.UnifiedAuthentication`` state.")
$linesOut.Add("- ``HttpServerLib.dll`` exposes route/module primitives such as ``HttpService.RegisterModule``, ``ServiceModule``, ``ServiceRoute``, ``RouteAttribute``, ``OnGet``, and ``OnPost``.")
$linesOut.Add("- Main client IL does not show a concrete ``RegisterModule`` call or send-message/send-file HTTP route registration.")
$linesOut.Add("- ``PluginLightAppMulProcessCommunication`` declares a ``NamedPipeServerStream`` field, but ``StartLightAppMultProssCommunication`` returns immediately.")
$linesOut.Add("- Returned live probe showed one remote TCP connection to port ``10088`` and a named pipe ``\\.\\pipe\\zfpinject-msg-server``; neither proves an iSphere send API.")
$linesOut.Add("- ``PluginManager``/``IMPlugin`` evidence is UI/app-store/context-menu oriented; no local assembly-load plugin bridge or send route was confirmed.")
$linesOut.Add("")
$linesOut.Add("## Candidate evidence")
foreach ($candidateResult in $candidateResults) {
$linesOut.Add("")
$linesOut.Add("### $($candidateResult.display)")
$linesOut.Add("")
$linesOut.Add("Classification: ``$($candidateResult.classification)``; usable for B-route send: ``$($candidateResult.usable_for_broute_send)``; matches: $($candidateResult.match_count).")
$linesOut.Add("")
$linesOut.Add("Reason: $($candidateResult.reason)")
if (@($candidateResult.evidence).Count -eq 0) {
$linesOut.Add("")
$linesOut.Add("No evidence found in configured offline sources.")
continue
}
$linesOut.Add("")
$linesOut.Add("| Source | Kind | Snippet | Context |")
$linesOut.Add("| --- | --- | --- | --- |")
foreach ($evidence in $candidateResult.evidence) {
$sourceLoc = if ($evidence.line_number) { "$($evidence.source):$($evidence.line_number)" } elseif ($null -ne $evidence.string_index) { "$($evidence.source)#str$($evidence.string_index)" } else { $evidence.source }
$method = if ($evidence.method_header) { "L$($evidence.method_header.line_number): $($evidence.method_header.text)" } else { "" }
$snippet = (($evidence.text -replace "\|", "\\|") -replace "`r?`n", " ")
if ($snippet.Length -gt 220) { $snippet = $snippet.Substring(0, 220) + "..." }
$method = ($method -replace "\|", "\\|")
$linesOut.Add("| ``$sourceLoc`` | ``$($evidence.kind)`` | ``$snippet`` | ``$method`` |")
}
}
$linesOut.Add("")
$linesOut.Add("## Decision")
$linesOut.Add("")
$linesOut.Add("No existing IPC/plugin/local HTTP bridge is confirmed usable for B-route text send or file send. The next B-route branch should be ``in_process_adapter_research``. Until that exists, an external sidecar can only do preview/probe work, while A-route/RPA remains backup-only.")
$linesOut.Add("")
$linesOut.Add("## Next work")
$linesOut.Add("")
$linesOut.Add("1. Update the B-route next plan and capability source matrix with ``in_process_adapter_research`` as the offline decision.")
$linesOut.Add("2. Create a separate plan before implementing any in-process adapter work.")
$linesOut.Add("3. Do not promote RPA beyond backup in this branch.")
($linesOut -join "`n") + "`n" | Set-Content -LiteralPath $reportFullPath -Encoding UTF8
$requiredNames = @("HttpServerLib", "NamedPipe", "Plugin", "IMPlatformClient.Web", "ProcessComm", "INetwork", "IOClientNetwork", "in_process_adapter_research")
$reportText = Get-Content -LiteralPath $reportFullPath -Raw
$missing = @($requiredNames | Where-Object { $reportText -notlike "*$_*" })
if ($missing.Count -gt 0) {
throw "Report missing required names: $($missing -join ', ')"
}
[pscustomobject]@{
ok = $true
json_path = $jsonPath
report_path = $reportFullPath
reflection_path = $httpReflectionPath
candidates = $candidateResults.Count
decision = $recommendation.decision
pursue_existing_ipc_or_plugin_first = $false
originals_copied = $false
originals_modified = $false
} | ConvertTo-Json -Depth 6

View File

@@ -0,0 +1,342 @@
param(
[string]$IlDir = "runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c28-il",
[string]$OutputDir = "runs/offline-broute-reverse",
[string]$ReportPath = "docs/source-discovery/2026-07-12-broute-file-send-static-map.md",
[int]$WindowRadius = 5,
[int]$MaxEvidencePerTarget = 18
)
$ErrorActionPreference = "Stop"
$repo = (Resolve-Path -LiteralPath (Join-Path $PSScriptRoot "..")).Path
$ilDirFull = Join-Path $repo $IlDir
$outDir = Join-Path $repo $OutputDir
$reportFullPath = Join-Path $repo $ReportPath
New-Item -ItemType Directory -Force -Path $outDir | Out-Null
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $reportFullPath) | Out-Null
$sources = @(
@{ path = "IMPlatformClient.exe.il"; role = "main client IL; UC_FileSend, OffLineFileSend, MessageScheduling" },
@{ path = "IMPP.Service.dll.il"; role = "file transfer service implementation" },
@{ path = "IMPP.ServiceBase.dll.il"; role = "file transfer contracts, parameters, and result DTOs" },
@{ path = "IMPP.Interface.dll.il"; role = "transport/event interface contracts" },
@{ path = "smack.dll.il"; role = "Chat.sendFileMessage and XMPP message construction" },
@{ path = "TcpFileTransfer.dll.il"; role = "native TCP transfer candidate; IL may be unavailable" },
@{ path = "IMPP.Model.dll.il"; role = "chat record models if extracted" }
)
$targets = @(
@{
key = "IMPP.Client.OffLineFileSend.sendFile"
display = "IMPP.Client.OffLineFileSend.sendFile"
phase = "upload"
intent = "offline file upload orchestration from UI file sender"
patterns = @("OffLineFileSend::sendFile", "^\s*sendFile\(\) cil managed")
},
@{
key = "IMPP.Client.OffLineFileSend.trans_UploadCompleted"
display = "IMPP.Client.OffLineFileSend.trans_UploadCompleted"
phase = "upload_to_message_boundary"
intent = "upload-completed handler that converts FileUploadResult.FileID into a chat file message"
patterns = @("OffLineFileSend::trans_UploadCompleted", "trans_UploadCompleted\(string fileId\)")
},
@{
key = "IMPP.Service.BLL.FileTransfer.FileUpload"
display = "IMPP.Service.BLL.FileTransfer.FileUpload"
phase = "upload"
intent = "synchronous service upload entry returning FileUploadResult"
patterns = @("FileTransfer::FileUpload", "FileUpload\(class \[IMPP\.ServiceBase\].*FileUploadPara")
},
@{
key = "IMPP.Service.BLL.FileTransfer.AsynFileUpload"
display = "IMPP.Service.BLL.FileTransfer.AsynFileUpload"
phase = "upload"
intent = "asynchronous upload queue entry"
patterns = @("FileTransfer::AsynFileUpload", "AsynFileUpload\(class \[IMPP\.ServiceBase\].*FileUploadPara")
},
@{
key = "FileUploadPara"
display = "FileUploadPara"
phase = "upload_parameters"
intent = "host/port/domain/local file path/cache/timeout/upload flags"
patterns = @("FileUploadPara", "FileUploadPara::\.ctor")
},
@{
key = "FileUploadResult.FileID"
display = "FileUploadResult.FileID"
phase = "upload_result"
intent = "server-side file id and URL returned by upload"
patterns = @("FileUploadResult::get_FileID", "FileUploadResult::set_FileID", "FileUploadResult", "get_FileID\(\) cil managed")
},
@{
key = "MessageScheduling.SendFileMessage"
display = "MessageScheduling.SendFileMessage"
phase = "message"
intent = "scheduled/file-message finalization path using RosterContactsArgs and FileTransferArgs"
patterns = @("MessageScheduling::SendFileMessage", "SendFileMessage\(class IMPP\.Client\.Business\.RosterContacts\.RosterContactsArgs")
},
@{
key = "Chat.sendFileMessage"
display = "Chat.sendFileMessage"
phase = "message"
intent = "smack API that sends the XMPP file message after upload metadata is known"
patterns = @("Chat::sendFileMessage", "P2PChat::sendFileMessage", "ChatRoom::sendFileMessage", "sendFileMessage\(string p_message")
},
@{
key = "Required values: path id size target jid"
display = "Required values: path id size target jid"
phase = "requirements"
intent = "static evidence for local file path, remote folder/file id, file size/name, target JID/chat, and server auth"
patterns = @("get_LocalFilePath", "get_RemoteFolder", "get__localFilePath", "get__fileSize", "FileInfo::get_Length", "FileSystemInfo::get_Name", "get_RosterJid", "GetChat\(", "HTTPFileServer", "UnifiedAuthentication", "Auth::get_token")
}
)
function Get-RelativePath([string]$Path) {
if ($Path.StartsWith($repo, [System.StringComparison]::OrdinalIgnoreCase)) {
return $Path.Substring($repo.Length).TrimStart('\', '/')
}
return $Path
}
function Get-EvidenceKind([string]$Line) {
if ($Line -match "^\s*\.class\b") { return "type_definition" }
if ($Line -match "^\s*\.method\b") { return "method_header" }
if ($Line -match "\bend of method\b") { return "method_end" }
if ($Line -match "\bcall(?:virt)?\b") { return "callsite" }
if ($Line -match "\bnewobj\b") { return "constructor_call" }
if ($Line -match "\bldstr\b") { return "string_literal" }
if ($Line -match "^\s*(instance|static|FileUpload|SendFileMessage|sendFileMessage|sendFile|trans_UploadCompleted)\b.*\(") { return "signature_continuation" }
return "reference"
}
function Get-MethodContext($Lines, [int]$Index) {
$start = [Math]::Max(0, $Index - 120)
$methodHeader = $null
$classHeader = $null
for ($i = $Index; $i -ge $start; $i--) {
$line = $Lines[$i]
if ($null -eq $methodHeader -and $line -match "^\s*\.method\b") {
$methodHeader = [pscustomobject]@{ line_number = $i + 1; text = $line.Trim() }
}
if ($null -eq $classHeader -and $line -match "^\s*\.class\b") {
$classHeader = [pscustomobject]@{ line_number = $i + 1; text = $line.Trim() }
}
if ($methodHeader -and $classHeader) { break }
}
[pscustomobject]@{ method_header = $methodHeader; class_header = $classHeader }
}
function New-Evidence($Lines, [int]$Index, [string]$SourceRel) {
$from = [Math]::Max(0, $Index - $WindowRadius)
$to = [Math]::Min($Lines.Count - 1, $Index + $WindowRadius)
$window = New-Object System.Collections.Generic.List[object]
for ($i = $from; $i -le $to; $i++) {
$window.Add([pscustomobject]@{ line_number = $i + 1; text = $Lines[$i].TrimEnd() })
}
$context = Get-MethodContext -Lines $Lines -Index $Index
[pscustomobject]@{
source = $SourceRel
line_number = $Index + 1
kind = Get-EvidenceKind -Line $Lines[$Index]
text = $Lines[$Index].Trim()
method_header = $context.method_header
class_header = $context.class_header
window = $window
}
}
function Get-Classification($Evidence) {
$kinds = @($Evidence | ForEach-Object { $_.kind })
if ($kinds -contains "type_definition" -or $kinds -contains "method_header" -or $kinds -contains "signature_continuation" -or $kinds -contains "method_end") { return "confirmed_signature" }
if ($kinds -contains "callsite" -or $kinds -contains "constructor_call") { return "confirmed_callsite" }
if ($kinds.Count -gt 0 -and @($kinds | Where-Object { $_ -ne "string_literal" }).Count -eq 0) { return "string_only" }
if ($kinds.Count -gt 0) { return "confirmed_callsite" }
return "not_found"
}
$sourceResults = New-Object System.Collections.Generic.List[object]
$targetBuckets = @{}
foreach ($target in $targets) {
$targetKey = [string]$target['key']
$targetBuckets[$targetKey] = New-Object System.Collections.Generic.List[object]
}
foreach ($source in $sources) {
$sourcePath = [string]$source['path']
$sourceFullPath = Join-Path $ilDirFull $sourcePath
$sourceRel = Get-RelativePath -Path $sourceFullPath
if (-not (Test-Path -LiteralPath $sourceFullPath -PathType Leaf)) {
$sourceResults.Add([pscustomobject]@{ path = $sourceRel; role = $source['role']; exists = $false; line_count = 0; size_bytes = $null })
continue
}
$item = Get-Item -LiteralPath $sourceFullPath
$lines = [System.IO.File]::ReadAllLines($sourceFullPath)
$sourceResults.Add([pscustomobject]@{ path = $sourceRel; role = $source['role']; exists = $true; line_count = $lines.Count; size_bytes = $item.Length })
foreach ($target in $targets) {
$targetKey = [string]$target['key']
$compiled = @($target['patterns'] | ForEach-Object { [regex]::new($_, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase) })
for ($i = 0; $i -lt $lines.Count; $i++) {
$line = $lines[$i]
foreach ($rx in $compiled) {
if ($rx.IsMatch($line)) {
$targetBuckets[$targetKey].Add((New-Evidence -Lines $lines -Index $i -SourceRel $sourceRel))
break
}
}
}
}
}
$targetResults = New-Object System.Collections.Generic.List[object]
foreach ($target in $targets) {
$targetKey = [string]$target['key']
$allEvidence = $targetBuckets[$targetKey].ToArray()
$evidenceForReport = @(
$allEvidence |
Sort-Object @{ Expression = { if ($_.kind -in @("type_definition", "method_header", "signature_continuation", "method_end")) { 0 } elseif ($_.kind -in @("callsite", "constructor_call")) { 1 } elseif ($_.kind -eq "string_literal") { 2 } else { 3 } } }, source, line_number |
Select-Object -First $MaxEvidencePerTarget
)
$targetResults.Add([pscustomobject]@{
key = $targetKey
display = $target['display']
phase = $target['phase']
intent = $target['intent']
classification = Get-Classification -Evidence $allEvidence
match_count = $allEvidence.Count
evidence = $evidenceForReport
})
}
$requirements = @(
[pscustomobject]@{ value = "local file path"; evidence = "OffLineFileSend constructor receives localFilePath; sendFile uses get__localFilePath; MessageScheduling.SendFileMessage uses FileTransferArgs.get_LocalFilePath."; status = "required_confirmed" },
[pscustomobject]@{ value = "server file id / remote folder"; evidence = "Upload returns FileUploadResult.FileID; trans_UploadCompleted(fileId) passes it to Chat.sendFileMessage and Packet.set_id. MessageScheduling path uses FileTransferArgs.get_RemoteFolder."; status = "required_confirmed" },
[pscustomobject]@{ value = "file name and file size"; evidence = "SendFileMessage builds OFFLINE_FILE_TRANSFER payload from FileInfo/FileSystemInfo name and length; OffLineFileSend keeps _fileSize."; status = "required_confirmed" },
[pscustomobject]@{ value = "target JID / chat object"; evidence = "UC_FileSend and MessageScheduling both require a live smack Chat; scheduled path derives it from RosterContactsArgs.get_RosterJid + UtilsChat.GetChat."; status = "required_confirmed" },
[pscustomobject]@{ value = "HTTP file server and auth"; evidence = "FileUploadPara construction uses Config.ServerInfo.HTTPFileServer IP/Port/domain; service upload builds /FS/auth/resource/upload URL with UnifiedAuthentication token/app key/client secret/time/user id."; status = "required_confirmed" },
[pscustomobject]@{ value = "file hash"; evidence = "No file-transfer-path MD5/SHA/checksum requirement was confirmed in the configured IL. MD5 hits belong to image/RTF or auth digest areas, not the offline file-send path."; status = "not_confirmed_in_file_send_path" }
)
$summary = [pscustomobject]@{
generated_at = (Get-Date).ToUniversalTime().ToString("o")
repository = $repo
il_dir = $IlDir
sources = $sourceResults
targets = $targetResults
phase_decision = "Offline static evidence shows upload first, then chat file-message finalization. Direct Chat.sendFileMessage alone is not enough unless a valid uploaded file id/remote folder already exists."
requirements = $requirements
originals_copied = $false
originals_modified = $false
}
$jsonPath = Join-Path $outDir "file-send-map.json"
$summary | ConvertTo-Json -Depth 12 | Set-Content -LiteralPath $jsonPath -Encoding UTF8
$linesOut = New-Object System.Collections.Generic.List[string]
$linesOut.Add("# B-Route File Send Static Map")
$linesOut.Add("")
$linesOut.Add("Date: 2026-07-12")
$linesOut.Add("")
$linesOut.Add("## Scope")
$linesOut.Add("")
$linesOut.Add("This report uses offline IL only. It does not upload files, send file messages, replay traffic, inject into a process, or mutate the original iSphere binaries.")
$linesOut.Add("")
$linesOut.Add("Machine-readable evidence: ``$OutputDir/file-send-map.json``")
$linesOut.Add("")
$linesOut.Add("## Sources")
$linesOut.Add("")
$linesOut.Add("| Source | Role | Exists | Lines | Size bytes |")
$linesOut.Add("| --- | --- | --- | ---: | ---: |")
foreach ($sourceResult in $sourceResults) {
$exists = if ($sourceResult.exists) { "yes" } else { "no" }
$sizeText = if ($null -ne $sourceResult.size_bytes) { [string]$sourceResult.size_bytes } else { "" }
$linesOut.Add("| ``$($sourceResult.path)`` | $($sourceResult.role) | $exists | $($sourceResult.line_count) | $sizeText |")
}
$linesOut.Add("")
$linesOut.Add("## Target classification")
$linesOut.Add("")
$linesOut.Add("| Target | Phase | Intent | Classification | Matches |")
$linesOut.Add("| --- | --- | --- | --- | ---: |")
foreach ($targetResult in $targetResults) {
$linesOut.Add("| ``$($targetResult.display)`` | ``$($targetResult.phase)`` | $($targetResult.intent) | ``$($targetResult.classification)`` | $($targetResult.match_count) |")
}
$linesOut.Add("")
$linesOut.Add("## Upload step vs chat-message step")
$linesOut.Add("")
$linesOut.Add("| Step | Static evidence | Business meaning |")
$linesOut.Add("| --- | --- | --- |")
$linesOut.Add("| 1. Upload | ``IMPP.Client.OffLineFileSend.sendFile`` constructs ``FileUploadPara`` and calls ``IFileTransfer.FileUpload``; ``IMPP.Service.BLL.FileTransfer.FileUpload`` delegates to ``SyncFileTransfer`` and private ``Upload``. | The local file must be uploaded to the HTTP file service first. |")
$linesOut.Add("| 2. Upload result | ``FileUploadResult.FileID`` is read; upload notification calls ``IMPP.Client.OffLineFileSend.trans_UploadCompleted(fileId)``. | The server-issued file id becomes the durable reference. |")
$linesOut.Add("| 3. Chat file message | ``trans_UploadCompleted`` and ``MessageScheduling.SendFileMessage`` build ``OFFLINE_FILE_TRANSFER;...`` payloads and call ``Chat.sendFileMessage``. | The chat send step publishes metadata/reference, not raw file bytes. |")
$linesOut.Add("")
$linesOut.Add("Conclusion: file send is upload-first, chat-message-second. A direct chat message is insufficient without a valid uploaded file id or remote folder reference.")
$linesOut.Add("")
$linesOut.Add("## Required values")
$linesOut.Add("")
$linesOut.Add("| Value | Status | Evidence |")
$linesOut.Add("| --- | --- | --- |")
foreach ($req in $requirements) {
$linesOut.Add("| $($req.value) | ``$($req.status)`` | $($req.evidence) |")
}
$linesOut.Add("")
$linesOut.Add("## Evidence excerpts")
foreach ($targetResult in $targetResults) {
$linesOut.Add("")
$linesOut.Add("### $($targetResult.display)")
$linesOut.Add("")
$linesOut.Add("Classification: ``$($targetResult.classification)``; phase: ``$($targetResult.phase)``; matches: $($targetResult.match_count).")
if (@($targetResult.evidence).Count -eq 0) {
$linesOut.Add("")
$linesOut.Add("No evidence found in configured offline IL sources.")
continue
}
$linesOut.Add("")
$linesOut.Add("| Source line | Kind | Snippet | Method context |")
$linesOut.Add("| --- | --- | --- | --- |")
foreach ($evidence in $targetResult.evidence) {
$method = if ($evidence.method_header) { "L$($evidence.method_header.line_number): $($evidence.method_header.text)" } else { "" }
$snippet = ($evidence.text -replace "\|", "\\|")
$method = ($method -replace "\|", "\\|")
$linesOut.Add("| ``$($evidence.source):$($evidence.line_number)`` | ``$($evidence.kind)`` | ``$snippet`` | ``$method`` |")
}
}
$linesOut.Add("")
$linesOut.Add("## Inference")
$linesOut.Add("")
$linesOut.Add("- High confidence: upload and file-message finalization are separate steps.")
$linesOut.Add("- High confidence: ``FileUploadPara`` needs HTTP file server host/port/domain plus local file path and upload options.")
$linesOut.Add("- High confidence: ``Chat.sendFileMessage`` produces the XMPP file-message envelope after file metadata is available.")
$linesOut.Add("- Medium confidence: B-route file send must either call the same logged-in service/runtime or reproduce the authenticated HTTP upload plus XMPP file-message sequence.")
$linesOut.Add("- Low confidence until bridge evidence: an external sidecar can obtain the same service/auth/chat objects without being inside the logged-in client process.")
$linesOut.Add("")
$linesOut.Add("## Decision")
$linesOut.Add("")
$linesOut.Add("Offline static evidence supports B-route research, but file sending needs more than one method call: upload first, then chat file-message finalization. The next blocker is reachability: whether an IPC/plugin/in-process bridge can access the logged-in ``IFileTransfer`` service and smack ``Chat`` object.")
$linesOut.Add("")
$linesOut.Add("## Next work")
$linesOut.Add("")
$linesOut.Add("1. Extract bridge/IPC/plugin candidates before coding any file-send adapter.")
$linesOut.Add("2. If a bridge exists, prototype non-mutating discovery first: service availability, chat object lookup, and upload endpoint metadata only.")
$linesOut.Add("3. Keep A-route/RPA backup-only.")
($linesOut -join "`n") + "`n" | Set-Content -LiteralPath $reportFullPath -Encoding UTF8
$requiredNames = @("IMPP.Client.OffLineFileSend.sendFile", "IMPP.Client.OffLineFileSend.trans_UploadCompleted", "IMPP.Service.BLL.FileTransfer.FileUpload", "IMPP.Service.BLL.FileTransfer.AsynFileUpload", "FileUploadPara", "sendFileMessage", "Upload step vs chat-message step")
$reportText = Get-Content -LiteralPath $reportFullPath -Raw
$missing = @($requiredNames | Where-Object { $reportText -notlike "*$_*" })
if ($missing.Count -gt 0) {
throw "Report missing required names: $($missing -join ', ')"
}
[pscustomobject]@{
ok = $true
json_path = $jsonPath
report_path = $reportFullPath
sources = $sourceResults.Count
targets = $targetResults.Count
classifications = @($targetResults | ForEach-Object { "$($_.display)=$($_.classification)" })
phase_decision = $summary.phase_decision
originals_copied = $false
originals_modified = $false
} | ConvertTo-Json -Depth 6

View File

@@ -0,0 +1,285 @@
param(
[string]$IlDir = "runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c28-il",
[string]$OutputDir = "runs/offline-broute-reverse",
[string]$ReportPath = "docs/source-discovery/2026-07-12-broute-text-send-static-map.md",
[int]$WindowRadius = 4,
[int]$MaxEvidencePerTarget = 18
)
$ErrorActionPreference = "Stop"
$repo = (Resolve-Path -LiteralPath (Join-Path $PSScriptRoot "..")).Path
$ilDirFull = Join-Path $repo $IlDir
$outDir = Join-Path $repo $OutputDir
$reportFullPath = Join-Path $repo $ReportPath
New-Item -ItemType Directory -Force -Path $outDir | Out-Null
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $reportFullPath) | Out-Null
$sources = @(
@{
path = "IMPlatformClient.exe.il"
role = "main managed client IL; chat UI, AppContextManager, scheduling call sites"
},
@{
path = "smack.dll.il"
role = "XMPP/smack managed IL; Chat and XMPPConnection implementation"
}
)
$targets = @(
@{
key = "AppContextManager.SendTxtMessageByJid"
display = "AppContextManager.SendTxtMessageByJid"
intent = "high-level text send entry exposed by AppContextManager"
patterns = @("AppContextManager::SendTxtMessageByJid", "\bSendTxtMessageByJid\b")
},
@{
key = "MessageScheduling.SendChatMessage"
display = "MessageScheduling.SendChatMessage"
intent = "message scheduling text/chat send helper"
patterns = @("MessageScheduling::SendChatMessage", "\bSendChatMessage\s*\(")
},
@{
key = "Chat.SendMessage"
display = "Chat.SendMessage"
intent = "smack Chat send API used by chat/UI code"
patterns = @("com\.vision\.smack\.Chat::SendMessage", "com\.vision\.smack\.Chat::sendMessage", "\bChat::SendMessage\b", "\bChat::sendMessage\b")
},
@{
key = "XMPPConnection.send"
display = "XMPPConnection.send"
intent = "lowest-level XMPP connection send primitive"
patterns = @("XMPPConnection::send\b", "\bXMPPConnection\.send\b")
},
@{
key = "MessageCenter send-related callbacks"
display = "MessageCenter send-related callbacks"
intent = "MessageCenter or IMPPManager message-center callbacks touching send/message flow"
patterns = @("GetMessageCenter\s*\(\)", "MessageCenter::.*Send", "MessageCenter.*Send", "class IMPP\.Client\.control\.MessageCenter", "IMPP\.Client\.control\.MessageCenter")
}
)
function Get-RelativePath([string]$Path) {
if ($Path.StartsWith($repo, [System.StringComparison]::OrdinalIgnoreCase)) {
return $Path.Substring($repo.Length).TrimStart('\', '/')
}
return $Path
}
function Get-EvidenceKind([string]$Line) {
if ($Line -match "^\s*\.class\b") { return "type_definition" }
if ($Line -match "^\s*\.method\b") { return "method_header" }
if ($Line -match "\bend of method\b") { return "method_end" }
if ($Line -match "\bcall(?:virt)?\b") { return "callsite" }
if ($Line -match "\bldstr\b") { return "string_literal" }
if ($Line -match "^\s*(instance|static)\b.*\(") { return "signature_continuation" }
return "reference"
}
function Get-MethodContext($Lines, [int]$Index) {
$start = [Math]::Max(0, $Index - 90)
$methodHeader = $null
$classHeader = $null
for ($i = $Index; $i -ge $start; $i--) {
$line = $Lines[$i]
if ($null -eq $methodHeader -and $line -match "^\s*\.method\b") {
$methodHeader = [pscustomobject]@{ line_number = $i + 1; text = $line.Trim() }
}
if ($null -eq $classHeader -and $line -match "^\s*\.class\b") {
$classHeader = [pscustomobject]@{ line_number = $i + 1; text = $line.Trim() }
}
if ($methodHeader -and $classHeader) { break }
}
[pscustomobject]@{ method_header = $methodHeader; class_header = $classHeader }
}
function New-Evidence($Lines, [int]$Index, [string]$SourceRel) {
$from = [Math]::Max(0, $Index - $WindowRadius)
$to = [Math]::Min($Lines.Count - 1, $Index + $WindowRadius)
$window = New-Object System.Collections.Generic.List[object]
for ($i = $from; $i -le $to; $i++) {
$window.Add([pscustomobject]@{ line_number = $i + 1; text = $Lines[$i].TrimEnd() })
}
$context = Get-MethodContext -Lines $Lines -Index $Index
[pscustomobject]@{
source = $SourceRel
line_number = $Index + 1
kind = Get-EvidenceKind -Line $Lines[$Index]
text = $Lines[$Index].Trim()
method_header = $context.method_header
class_header = $context.class_header
window = $window
}
}
function Get-Classification($Evidence) {
$kinds = @($Evidence | ForEach-Object { $_.kind })
if ($kinds -contains "method_header" -or $kinds -contains "signature_continuation" -or $kinds -contains "method_end") { return "confirmed_signature" }
if ($kinds -contains "callsite") { return "confirmed_callsite" }
if ($kinds.Count -gt 0 -and @($kinds | Where-Object { $_ -ne "string_literal" }).Count -eq 0) { return "string_only" }
if ($kinds.Count -gt 0) { return "confirmed_callsite" }
return "not_found"
}
$sourceResults = New-Object System.Collections.Generic.List[object]
$targetBuckets = @{}
foreach ($target in $targets) {
$targetKey = [string]$target['key']
$targetBuckets[$targetKey] = New-Object System.Collections.Generic.List[object]
}
foreach ($source in $sources) {
$sourcePath = [string]$source['path']
$sourceFullPath = Join-Path $ilDirFull $sourcePath
$sourceRel = Get-RelativePath -Path $sourceFullPath
if (-not (Test-Path -LiteralPath $sourceFullPath -PathType Leaf)) {
$sourceResults.Add([pscustomobject]@{ path = $sourceRel; role = $source['role']; exists = $false; line_count = 0; size_bytes = $null })
continue
}
$item = Get-Item -LiteralPath $sourceFullPath
$lines = [System.IO.File]::ReadAllLines($sourceFullPath)
$sourceResults.Add([pscustomobject]@{ path = $sourceRel; role = $source['role']; exists = $true; line_count = $lines.Count; size_bytes = $item.Length })
foreach ($target in $targets) {
$targetKey = [string]$target['key']
$compiled = @($target['patterns'] | ForEach-Object { [regex]::new($_, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase) })
for ($i = 0; $i -lt $lines.Count; $i++) {
$line = $lines[$i]
foreach ($rx in $compiled) {
if ($rx.IsMatch($line)) {
$targetBuckets[$targetKey].Add((New-Evidence -Lines $lines -Index $i -SourceRel $sourceRel))
break
}
}
}
}
}
$targetResults = New-Object System.Collections.Generic.List[object]
foreach ($target in $targets) {
$targetKey = [string]$target['key']
$allEvidence = $targetBuckets[$targetKey].ToArray()
$evidenceForReport = @(
$allEvidence |
Sort-Object @{ Expression = { if ($_.kind -in @("method_header", "signature_continuation", "method_end")) { 0 } elseif ($_.kind -eq "callsite") { 1 } elseif ($_.kind -eq "string_literal") { 2 } else { 3 } } }, line_number |
Select-Object -First $MaxEvidencePerTarget
)
$targetResults.Add([pscustomobject]@{
key = $targetKey
display = $target['display']
intent = $target['intent']
classification = Get-Classification -Evidence $allEvidence
match_count = $allEvidence.Count
evidence = $evidenceForReport
})
}
$summary = [pscustomobject]@{
generated_at = (Get-Date).ToUniversalTime().ToString("o")
repository = $repo
il_dir = $IlDir
sources = $sourceResults
targets = $targetResults
decision = "B-route text send remains plausible only if a bridge can enter the logged-in runtime or an existing IPC/API exposes the same call. Offline IL confirms call shape, but not runtime invocability."
originals_copied = $false
originals_modified = $false
}
$jsonPath = Join-Path $outDir "text-send-map.json"
$summary | ConvertTo-Json -Depth 12 | Set-Content -LiteralPath $jsonPath -Encoding UTF8
$linesOut = New-Object System.Collections.Generic.List[string]
$linesOut.Add("# B-Route Text Send Static Map")
$linesOut.Add("")
$linesOut.Add("Date: 2026-07-12")
$linesOut.Add("")
$linesOut.Add("## Scope")
$linesOut.Add("")
$linesOut.Add("This report uses offline IL only. It does not log in, send messages, replay traffic, inject into a process, or mutate the original iSphere binaries.")
$linesOut.Add("")
$linesOut.Add("Machine-readable evidence: ``$OutputDir/text-send-map.json``")
$linesOut.Add("")
$linesOut.Add("## Sources")
$linesOut.Add("")
$linesOut.Add("| Source | Role | Exists | Lines | Size bytes |")
$linesOut.Add("| --- | --- | --- | ---: | ---: |")
foreach ($sourceResult in $sourceResults) {
$exists = if ($sourceResult.exists) { "yes" } else { "no" }
$sizeText = if ($null -ne $sourceResult.size_bytes) { [string]$sourceResult.size_bytes } else { "" }
$linesOut.Add("| ``$($sourceResult.path)`` | $($sourceResult.role) | $exists | $($sourceResult.line_count) | $sizeText |")
}
$linesOut.Add("")
$linesOut.Add("## Target classification")
$linesOut.Add("")
$linesOut.Add("| Target | Intent | Classification | Matches |")
$linesOut.Add("| --- | --- | --- | ---: |")
foreach ($targetResult in $targetResults) {
$linesOut.Add("| ``$($targetResult.display)`` | $($targetResult.intent) | ``$($targetResult.classification)`` | $($targetResult.match_count) |")
}
$linesOut.Add("")
$linesOut.Add("## Verified facts")
$linesOut.Add("")
$linesOut.Add("- ``AppContextManager.SendTxtMessageByJid`` appears in the offline client IL and is not just a UIA/RPA artifact.")
$linesOut.Add("- ``MessageScheduling.SendChatMessage`` appears in the offline client IL and has call-site evidence around chat-message flow.")
$linesOut.Add("- ``Chat.SendMessage`` / ``Chat.sendMessage`` appears as a smack chat API used by client code.")
$linesOut.Add("- ``XMPPConnection.send`` appears as a lower-level connection send primitive in offline IL.")
$linesOut.Add("- ``MessageCenter send-related callbacks`` appear as MessageCenter/GetMessageCenter references, but offline static evidence alone does not prove an external bridge can call them.")
$linesOut.Add("")
$linesOut.Add("## Evidence excerpts")
foreach ($targetResult in $targetResults) {
$linesOut.Add("")
$linesOut.Add("### $($targetResult.display)")
$linesOut.Add("")
$linesOut.Add("Classification: ``$($targetResult.classification)``; matches: $($targetResult.match_count).")
if (@($targetResult.evidence).Count -eq 0) {
$linesOut.Add("")
$linesOut.Add("No evidence found in configured offline IL sources.")
continue
}
$linesOut.Add("")
$linesOut.Add("| Source line | Kind | Snippet | Method context |")
$linesOut.Add("| --- | --- | --- | --- |")
foreach ($evidence in $targetResult.evidence) {
$method = if ($evidence.method_header) { "L$($evidence.method_header.line_number): $($evidence.method_header.text)" } else { "" }
$snippet = ($evidence.text -replace "\|", "\\|")
$method = ($method -replace "\|", "\\|")
$linesOut.Add("| ``$($evidence.source):$($evidence.line_number)`` | ``$($evidence.kind)`` | ``$snippet`` | ``$method`` |")
}
}
$linesOut.Add("")
$linesOut.Add("## Inference")
$linesOut.Add("")
$linesOut.Add("- High confidence: text sending has an internal managed call path that reaches smack chat/connection send APIs.")
$linesOut.Add("- Medium confidence: the likely chain is high-level AppContextManager or UI chat code -> MessageScheduling/frmP2PChat -> smack Chat.SendMessage/sendMessage -> XMPPConnection.send.")
$linesOut.Add("- Low confidence until live/runtime evidence: an external sidecar can invoke this path without being inside the logged-in process.")
$linesOut.Add("")
$linesOut.Add("## Decision")
$linesOut.Add("")
$linesOut.Add("B-route text send remains plausible only if a bridge can enter the logged-in runtime or an existing IPC/API exposes the same call. Offline IL confirms call shape, but not runtime invocability.")
$linesOut.Add("")
$linesOut.Add("## Next work")
$linesOut.Add("")
$linesOut.Add("1. Extract file-send/upload call graph and separate upload from chat-message finalization.")
$linesOut.Add("2. Extract bridge/IPC/plugin candidates to see whether the send call path is reachable without RPA.")
$linesOut.Add("3. Keep A-route/RPA as backup-only; do not promote it unless B-route bridge evidence fails.")
($linesOut -join "`n") + "`n" | Set-Content -LiteralPath $reportFullPath -Encoding UTF8
$requiredNames = @("AppContextManager.SendTxtMessageByJid", "MessageScheduling.SendChatMessage", "Chat.SendMessage", "XMPPConnection.send", "MessageCenter send-related callbacks")
$reportText = Get-Content -LiteralPath $reportFullPath -Raw
$missing = @($requiredNames | Where-Object { $reportText -notlike "*$_*" })
if ($missing.Count -gt 0) {
throw "Report missing required target names: $($missing -join ', ')"
}
[pscustomobject]@{
ok = $true
json_path = $jsonPath
report_path = $reportFullPath
sources = $sourceResults.Count
targets = $targetResults.Count
classifications = @($targetResults | ForEach-Object { "$($_.display)=$($_.classification)" })
originals_copied = $false
originals_modified = $false
} | ConvertTo-Json -Depth 6

View File

@@ -0,0 +1,410 @@
param(
[string]$IlDir = "runs/offline-evidence-intake/zyl-qqfile-20260709/metadata/c28-il",
[string]$OutputDir = "runs/inprocess-adapter-research",
[string]$ReportPath = "docs/source-discovery/2026-07-12-inprocess-adapter-static-map.md",
[int]$WindowRadius = 4,
[int]$MaxEvidencePerAnchor = 16
)
$ErrorActionPreference = "Stop"
$repo = (Resolve-Path -LiteralPath (Join-Path $PSScriptRoot "..")).Path
$ilDirFull = Join-Path $repo $IlDir
$outDir = Join-Path $repo $OutputDir
$reportFullPath = Join-Path $repo $ReportPath
New-Item -ItemType Directory -Force -Path $outDir | Out-Null
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $reportFullPath) | Out-Null
$sources = @(
@{ path = "IMPlatformClient.exe.il"; role = "main managed client; UI, AppContextManager, MessageScheduling, frmMain, login runtime" },
@{ path = "smack.dll.il"; role = "XMPP/smack managed library; Chat and XMPPConnection send primitives" },
@{ path = "IMPP.Service.dll.il"; role = "file transfer service implementation" },
@{ path = "IMPP.ServiceBase.dll.il"; role = "file transfer DTOs and FileUploadPara/FileUploadResult contracts" },
@{ path = "IMPP.Interface.dll.il"; role = "service and network interface contracts" },
@{ path = "IMPP.Common.dll.il"; role = "common helper and runtime DTO evidence" }
)
$anchors = @(
@{
key = "text_high_level_entry"
display = "AppContextManager.SendTxtMessageByJid"
command = "send_text"
adapter_role = "preferred high-level managed entry if an in-process adapter can reach AppContextManager"
confidence = "high_static"
usable_offline = $false
required_runtime = @("logged-in IMPPManager/UserInfo", "target JID", "initialized AppContextManager", "live XMPP connection")
patterns = @("AppContextManager::SendTxtMessageByJid", "\bSendTxtMessageByJid\b")
},
@{
key = "text_scheduling_entry"
display = "MessageScheduling.SendChatMessage"
command = "send_text"
adapter_role = "fallback managed entry when scheduling layer has chat and contact args"
confidence = "high_static"
usable_offline = $false
required_runtime = @("MessageScheduling instance or static caller", "RosterContactsArgs/contact context", "Chat object", "live XMPP connection")
patterns = @("MessageScheduling::SendChatMessage", "SendChatMessage\(", "SendChatMessage\(class IMPP\.Client")
},
@{
key = "text_low_level_chat"
display = "com.vision.smack.Chat.SendMessage / XMPPConnection.send"
command = "send_text"
adapter_role = "lowest-level send target; requires already resolved Chat/XMPPConnection"
confidence = "high_static"
usable_offline = $false
required_runtime = @("Chat instance", "XMPPConnection authenticated session", "message payload format")
patterns = @("com\.vision\.smack\.Chat::SendMessage", "com\.vision\.smack\.Chat::sendMessage", "XMPPConnection::send\b")
},
@{
key = "file_upload_orchestrator"
display = "IMPP.Client.OffLineFileSend.sendFile"
command = "upload_file_then_send_file"
adapter_role = "UI-side upload orchestration and transition into chat file message"
confidence = "high_static"
usable_offline = $false
required_runtime = @("local file path", "HTTP file server/auth state", "target roster/chat args", "upload completion callback")
patterns = @("OffLineFileSend::sendFile", "sendFile\(\) cil managed", "OffLineFileSend::trans_UploadCompleted")
},
@{
key = "file_upload_service"
display = "IFileTransfer/FileTransfer.FileUpload + FileUploadPara"
command = "upload_file"
adapter_role = "service upload entry that must return FileUploadResult before chat file finalization"
confidence = "high_static"
usable_offline = $false
required_runtime = @("FileUploadPara host/port/domain", "localFilePath", "token/auth", "FileUploadResult.FileID")
patterns = @("FileTransfer::FileUpload", "FileUploadPara", "FileUploadResult::get_FileID", "FileUploadResult")
},
@{
key = "file_message_finalizer"
display = "MessageScheduling.SendFileMessage / Chat.sendFileMessage"
command = "send_file_message"
adapter_role = "chat file-message finalization after FileID/remote folder exists"
confidence = "high_static"
usable_offline = $false
required_runtime = @("uploaded file id", "remote folder metadata", "file name/size", "target Chat/JID")
patterns = @("MessageScheduling::SendFileMessage", "Chat::sendFileMessage", "sendFileMessage\(")
},
@{
key = "logged_in_identity_auth"
display = "IMPPManager.UserInfo / UnifiedAuthentication / Auth token"
command = "runtime_context"
adapter_role = "runtime state required before any production send/upload can be meaningful"
confidence = "medium_static"
usable_offline = $false
required_runtime = @("UserInfo", "UnifiedAuthentication", "Auth token", "HTTPFileServer", "server resource/domain")
patterns = @("IMPPManager::get_UserInfo", "IMPPManager.UserInfo", "UnifiedAuthentication", "HTTPFileServer", "Auth::get_token", "get_token")
},
@{
key = "main_window_runtime_owner"
display = "frmMain / MessageCenter / chat runtime ownership"
command = "runtime_context"
adapter_role = "likely object owner for initialized chat, reconnect, message center, and plugin runtime state"
confidence = "medium_static"
usable_offline = $false
required_runtime = @("running frmMain", "initialized message center", "contact/session state")
patterns = @("class IMPP\.Client\.frmMain", "frmMain::", "GetMessageCenter\(\)", "MessageCenter", "OnReConnectionSucceed", "GetChat\(")
},
@{
key = "existing_http_not_bridge"
display = "frmLogin.StartWinServer / HttpServerLib"
command = "not_selected_bridge"
adapter_role = "known local HTTP framework, but not a confirmed send bridge"
confidence = "high_static_negative"
usable_offline = $false
required_runtime = @("logged-in state", "route module registration not found", "send route not found")
patterns = @("StartWinServer", "HttpServerLib", "HttpService::\.ctor", "RegisterModule", "RouteAttribute")
}
)
function Get-RelativePath([string]$Path) {
if ($Path.StartsWith($repo, [System.StringComparison]::OrdinalIgnoreCase)) {
return $Path.Substring($repo.Length).TrimStart([char[]]@('\', '/'))
}
return $Path
}
function Write-Utf8NoBomLf([string]$Path, [string]$Text) {
$utf8NoBom = [System.Text.UTF8Encoding]::new($false)
$normalized = $Text -replace "`r`n", "`n"
$normalized = $normalized -replace "`r", "`n"
$normalized = $normalized.TrimEnd() + "`n"
[System.IO.File]::WriteAllText($Path, $normalized, $utf8NoBom)
}
function Get-EvidenceKind([string]$Line) {
if ($Line -match "^\s*\.class\b") { return "type_definition" }
if ($Line -match "^\s*\.method\b") { return "method_header" }
if ($Line -match "\bend of method\b") { return "method_end" }
if ($Line -match "\bnewobj\b") { return "constructor_call" }
if ($Line -match "\bcall(?:virt)?\b") { return "callsite" }
if ($Line -match "\bldstr\b") { return "string_literal" }
if ($Line -match "^\s*(instance|static)\b.*\(") { return "signature_continuation" }
if ($Line -match "^\s*\.field\b") { return "field" }
return "reference"
}
function Get-MethodContext($Lines, [int]$Index) {
$start = [Math]::Max(0, $Index - 100)
for ($i = $Index; $i -ge $start; $i--) {
if ($Lines[$i] -match "^\s*\.method\b") {
$header = $Lines[$i].Trim()
if (($i + 1) -lt $Lines.Count -and $Lines[$i + 1] -match "^\s+(instance|static|default)\b") {
$header = ($header + " " + $Lines[$i + 1].Trim())
}
return "L$($i + 1): $header"
}
}
return ""
}
function Get-WindowSnippet($Lines, [int]$Index, [int]$Radius) {
$start = [Math]::Max(0, $Index - $Radius)
$end = [Math]::Min($Lines.Count - 1, $Index + $Radius)
$parts = New-Object System.Collections.Generic.List[string]
for ($i = $start; $i -le $end; $i++) {
$parts.Add(("L{0}: {1}" -f ($i + 1), $Lines[$i].Trim()))
}
return ($parts -join "`n")
}
function Find-AnchorEvidence($Anchor) {
$items = New-Object System.Collections.Generic.List[object]
foreach ($source in $sources) {
$sourcePath = Join-Path $ilDirFull $source.path
if (-not (Test-Path -LiteralPath $sourcePath)) { continue }
$lines = [System.IO.File]::ReadAllLines($sourcePath)
for ($i = 0; $i -lt $lines.Count; $i++) {
$line = $lines[$i]
foreach ($pattern in $Anchor.patterns) {
if ($line -match $pattern) {
$items.Add([pscustomobject]@{
source = Get-RelativePath $sourcePath
source_role = $source.role
line = $i + 1
kind = Get-EvidenceKind $line
pattern = $pattern
snippet = $line.Trim()
context = Get-MethodContext $lines $i
window = Get-WindowSnippet $lines $i $WindowRadius
})
break
}
}
if ($items.Count -ge $MaxEvidencePerAnchor) { break }
}
if ($items.Count -ge $MaxEvidencePerAnchor) { break }
}
return $items.ToArray()
}
function Classify-Anchor($Anchor, $Evidence) {
if ($Evidence.Count -eq 0) { return "missing_static_evidence" }
if ($Anchor.command -eq "not_selected_bridge") { return "not_a_send_bridge" }
if ($Anchor.command -eq "runtime_context") { return "runtime_dependency" }
return "in_process_candidate_static_only"
}
$sourceSummary = foreach ($source in $sources) {
$path = Join-Path $ilDirFull $source.path
$exists = Test-Path -LiteralPath $path
$lineCount = 0
$size = 0
if ($exists) {
$item = Get-Item -LiteralPath $path
$size = $item.Length
$lineCount = ([System.IO.File]::ReadLines($path) | Measure-Object).Count
}
[pscustomobject]@{
path = Get-RelativePath $path
role = $source.role
exists = $exists
lines = $lineCount
size_bytes = $size
}
}
$anchorResults = foreach ($anchor in $anchors) {
$evidence = Find-AnchorEvidence $anchor
[pscustomobject]@{
key = $anchor.key
display = $anchor.display
command = $anchor.command
adapter_role = $anchor.adapter_role
classification = Classify-Anchor $anchor $evidence
confidence = $anchor.confidence
usable_offline = $anchor.usable_offline
required_runtime = $anchor.required_runtime
evidence_count = $evidence.Count
evidence = $evidence
}
}
$commands = @(
[pscustomobject]@{
op = "probe_runtime"
status = "contract_only"
purpose = "report whether adapter is inside logged-in IMPP runtime and can see required types/singletons"
required_evidence = @("process identity", "loaded assemblies", "IMPPManager.UserInfo presence", "XMPP connection state")
},
[pscustomobject]@{
op = "send_text"
status = "blocked_until_logged_in_adapter"
purpose = "invoke high-level text send path after target JID and content hash are validated"
required_evidence = @("AppContextManager or MessageScheduling reachability", "target JID", "sent record or ack containing content hash/correlation")
},
[pscustomobject]@{
op = "upload_file"
status = "blocked_until_logged_in_adapter"
purpose = "call file upload service and return server FileID/remote folder metadata"
required_evidence = @("FileUploadPara values", "HTTP file server/auth", "FileUploadResult.FileID")
},
[pscustomobject]@{
op = "send_file_message"
status = "blocked_until_upload_evidence"
purpose = "finalize file message after upload returns server id"
required_evidence = @("uploaded FileID", "file name/size", "target JID/Chat", "sent record/ack")
}
)
$requiredRuntimeState = @(
"logged-in IMPlatformClient.exe process",
"loaded IMPP.Client/AppContextManager/MessageScheduling types",
"initialized IMPPManager.UserInfo and UnifiedAuthentication/Auth token",
"live XMPPConnection/Chat session",
"target JID or group JID resolved by existing search tools",
"file upload service parameters and FileUploadResult.FileID for file sends"
)
$stopConditions = @(
"No logged-in process is available for runtime reachability validation.",
"Adapter cannot see AppContextManager, MessageScheduling, Chat, or IFileTransfer in process.",
"Every viable path requires unsupported binary patching instead of a replaceable managed adapter/harness.",
"Online evidence cannot produce sent-record/content-hash/ack correlation for text send.",
"File upload cannot return FileUploadResult.FileID or equivalent remote folder metadata."
)
$result = [pscustomobject]@{
ok = $true
generated_at = (Get-Date).ToUniversalTime().ToString("o")
decision = "managed_in_process_adapter_contract_first"
sources = $sourceSummary
anchors = $anchorResults
commands = $commands
required_runtime_state = $requiredRuntimeState
stop_conditions = $stopConditions
originals_copied = $false
originals_modified = $false
}
$jsonPath = Join-Path $outDir "inprocess-adapter-map.json"
$jsonText = $result | ConvertTo-Json -Depth 8
Write-Utf8NoBomLf $jsonPath $jsonText
$md = New-Object System.Collections.Generic.List[string]
$md.Add("# In-Process Adapter Static Map")
$md.Add("")
$md.Add("Date: 2026-07-12")
$md.Add("")
$md.Add("## Scope")
$md.Add("")
$md.Add("This report uses offline IL/static evidence only. It does not log in, attach hooks, inject into a process, modify client binaries, upload files, send messages, or open network connections.")
$md.Add("")
$md.Add("Machine-readable evidence: ``$(Get-RelativePath $jsonPath)``")
$md.Add("")
$md.Add("## Decision")
$md.Add("")
$md.Add("| Question | Answer |")
$md.Add("| --- | --- |")
$md.Add("| Selected next B-route branch | `managed_in_process_adapter_contract_first` |")
$md.Add("| Can offline branch enable production send? | **No** |")
$md.Add("| Go connector mode to expose now | `in_process_contract` |")
$md.Add("| Required online proof later | logged-in adapter reachability plus sent-record/content-hash/ack evidence |")
$md.Add("")
$md.Add("## Sources")
$md.Add("")
$md.Add("| Source | Role | Exists | Lines | Size bytes |")
$md.Add("| --- | --- | --- | ---: | ---: |")
foreach ($source in $sourceSummary) {
$md.Add("| ``$($source.path)`` | $($source.role) | $($source.exists) | $($source.lines) | $($source.size_bytes) |")
}
$md.Add("")
$md.Add("## Command contract for future in-process adapter")
$md.Add("")
$md.Add("| Op | Current status | Purpose | Required evidence before production |")
$md.Add("| --- | --- | --- | --- |")
foreach ($cmd in $commands) {
$required = ($cmd.required_evidence -join "; ")
$md.Add("| ``$($cmd.op)`` | ``$($cmd.status)`` | $($cmd.purpose) | $required |")
}
$md.Add("")
$md.Add("## Anchor summary")
$md.Add("")
$md.Add("| Anchor | Command | Classification | Confidence | Evidence | Required runtime |")
$md.Add("| --- | --- | --- | --- | ---: | --- |")
foreach ($anchor in $anchorResults) {
$required = ($anchor.required_runtime -join "; ")
$md.Add("| ``$($anchor.display)`` | ``$($anchor.command)`` | ``$($anchor.classification)`` | ``$($anchor.confidence)`` | $($anchor.evidence_count) | $required |")
}
$md.Add("")
$md.Add("## Verified facts")
$md.Add("")
$md.Add("- Text send has static in-process candidates, but all require logged-in runtime objects and a live XMPP/Chat path.")
$md.Add("- File send is split into upload and message-finalization; `FileUploadResult.FileID` is a required boundary value before `Chat.sendFileMessage` is meaningful.")
$md.Add("- The earlier IPC/plugin/local HTTP scan did not find a confirmed external send bridge, so this branch must stay at `in_process_contract` until online reachability exists.")
$md.Add("- `in_process_contract` is a Go-side contract and audit mode only; it must return blocked/no-side-effect metadata in this offline branch.")
$md.Add("")
$md.Add("## Required runtime state")
$md.Add("")
foreach ($state in $requiredRuntimeState) {
$md.Add("- $state")
}
$md.Add("")
$md.Add("## Anchor evidence")
foreach ($anchor in $anchorResults) {
$md.Add("")
$md.Add("### $($anchor.display)")
$md.Add("")
$md.Add("Classification: ``$($anchor.classification)``; command: ``$($anchor.command)``; evidence count: $($anchor.evidence_count).")
$md.Add("")
$md.Add("Adapter role: $($anchor.adapter_role)")
$md.Add("")
if ($anchor.evidence_count -eq 0) {
$md.Add("No static evidence found for this anchor in the configured IL set.")
continue
}
$md.Add("| Source | Kind | Snippet | Context |")
$md.Add("| --- | --- | --- | --- |")
foreach ($e in $anchor.evidence) {
$snippet = ($e.snippet -replace "\|", "\\|" )
if ($snippet.Length -gt 220) { $snippet = $snippet.Substring(0, 217) + "..." }
$context = ($e.context -replace "\|", "\\|" )
if ($context.Length -gt 180) { $context = $context.Substring(0, 177) + "..." }
$md.Add("| ``$($e.source):$($e.line)`` | ``$($e.kind)`` | ``$snippet`` | ``$context`` |")
}
}
$md.Add("")
$md.Add("## Stop conditions")
$md.Add("")
foreach ($condition in $stopConditions) {
$md.Add("- $condition")
}
$md.Add("")
$md.Add("## Next work")
$md.Add("")
$md.Add("1. Add Go connector mode `in_process_contract` that validates request shape and returns blocked/no-side-effect metadata.")
$md.Add("2. In a logged-in environment, build a recorder/probe that only checks reachability of the listed runtime objects before attempting any send.")
$md.Add("3. Promote text send only after sent-record/content-hash/ack evidence exists.")
$md.Add("4. Promote file send only after upload returns `FileUploadResult.FileID` and file-message finalization is proven online.")
Write-Utf8NoBomLf $reportFullPath ($md -join "`n")
[pscustomobject]@{
ok = $true
json_path = $jsonPath
report_path = $reportFullPath
anchors = $anchorResults.Count
decision = $result.decision
originals_copied = $false
originals_modified = $false
} | ConvertTo-Json -Depth 5