docs: add offline b-route reverse decision
This commit is contained in:
309
docs/source-discovery/2026-07-12-broute-bridge-static-map.md
Normal file
309
docs/source-discovery/2026-07-12-broute-bridge-static-map.md
Normal 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.
|
||||||
230
docs/source-discovery/2026-07-12-broute-file-send-static-map.md
Normal file
230
docs/source-discovery/2026-07-12-broute-file-send-static-map.md
Normal 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.
|
||||||
149
docs/source-discovery/2026-07-12-broute-text-send-static-map.md
Normal file
149
docs/source-discovery/2026-07-12-broute-text-send-static-map.md
Normal 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.
|
||||||
@@ -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.
|
||||||
@@ -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.
|
||||||
@@ -17,6 +17,11 @@ 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`
|
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 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`
|
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`
|
||||||
|
|
||||||
## Source priority
|
## Source priority
|
||||||
|
|
||||||
@@ -37,8 +42,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_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_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_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_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`; `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. | Create a dedicated B-route `in_process_adapter_research` plan; keep external sidecar preview/probe-only and A-route UI action backup-only; business send remains blocked until adapter reachability plus 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_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`; `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 access to logged-in `IFileTransfer`/`Chat` objects and returned file-send package proves upload/sent evidence; A-route locator remains backup-only |
|
||||||
|
|
||||||
## Stage C entry rule
|
## Stage C entry rule
|
||||||
|
|
||||||
@@ -55,4 +60,4 @@ Start Stage C with a narrow log-backed `isphere_receive_messages` source abstrac
|
|||||||
|
|
||||||
## Deferred source work
|
## 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 offline decision path in `docs/source-discovery/2026-07-12-offline-broute-reverse-decision.md`: create a dedicated `in_process_adapter_research` plan before production send/file work. A-route RPA remains backup-only under `docs/superpowers/plans/2026-07-11-a-route-rpa-send.md`.
|
||||||
|
|||||||
@@ -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.
|
> **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.
|
**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
|
## Current evidence summary
|
||||||
|
|
||||||
@@ -36,7 +44,7 @@ The current `main` state already has:
|
|||||||
- Offline real `frmP2PChat` opener for RPA backup validation.
|
- 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.
|
- 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 |
|
| 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 |
|
| existing_ipc/local_service | not confirmed | offline bridge map found no send/file API | park unless new online evidence appears |
|
||||||
| plugin_extension | unknown | inspect install/plugin loader evidence | continue if client loads local plugin DLL/exe |
|
| 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 highest risk | requires explicit bridge mechanism | defer until IPC/plugin ruled out |
|
| 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 | implement as non-mutating sidecar boundary |
|
| 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 | already backup-ready | keep as backup, not primary |
|
| 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”.
|
- [ ] 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.
|
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
|
## Task 2: Add B-route connector env selection without starting real send
|
||||||
|
|
||||||
**Files:**
|
**Files:**
|
||||||
|
|||||||
168
scripts/build-offline-broute-reverse-index.ps1
Normal file
168
scripts/build-offline-broute-reverse-index.ps1
Normal 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
|
||||||
537
scripts/extract-broute-bridge-map.ps1
Normal file
537
scripts/extract-broute-bridge-map.ps1
Normal 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
|
||||||
342
scripts/extract-broute-file-send-map.ps1
Normal file
342
scripts/extract-broute-file-send-map.ps1
Normal 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
|
||||||
285
scripts/extract-broute-text-send-map.ps1
Normal file
285
scripts/extract-broute-text-send-map.ps1
Normal 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
|
||||||
Reference in New Issue
Block a user