Files
mxaccess/analysis/ghidra/exports/LmxProxy.dll.completion-status-decompile.md
T
Joseph Doherty 4dfc0cee65 [R3 + R4 + R8] settle protocol-level risks per Ghidra evidence
Ghidra headless decompile of `Lmx.dll`'s `aaDCT` symbol + the
`LmxProxy.dll` Fire_* event handlers (logs at
`analysis/ghidra/exports/Lmx.dll.aadct-decompile.md` and
`analysis/ghidra/exports/LmxProxy.dll.completion-status-decompile.md`)
settles **R3** and **R4** as "no static byte→status lookup table
exists":

- `Lmx.aaDCT` at `0x10178fc0` is a `SysAllocString(L"Lmx.aaDCT")` into
  a global BSTR — a logging category name, not a table.
- `MXSTATUS_PROXY` is a 4-field struct (success/category/detectedBy/
  detail), used as the marshalled COM event payload — not a static
  array of pre-mapped statuses.
- `Fire_OnDataChange` / `Fire_OnWriteComplete` / `Fire_OperationComplete` /
  `Fire_OnBufferedDataChange` (RVAs 0x15f72, 0x1611f, 0x16271, 0x163c0
  in `LmxProxy.dll`) receive ALREADY-POPULATED `MXSTATUS_PROXY[]`
  arrays — the byte-to-struct synthesis happens upstream in the
  proxy's NMX-callback ingestion code, not via a table lookup. The
  synthesis is per-event computation from operation context (engine
  ids, item handles, retry counters), not a static promotion.

R3/R4 status updated from "indefinitely deferred — no Ghidra table"
to "settled — no table exists; verbatim preservation is the canonical
answer." The .NET reference's `NmxOperationStatusMessage.TryParseInner`
+ the Rust port's `mxaccess-codec/src/operation_status.rs` already
match this canonical behaviour; no code change required.

Reopen R3/R4 only if a context-aware capture surfaces a per-byte
synthesis logic that depends on operation context — at which point
the codec would need access to the originating operation's context,
which is upstream of the bytes themselves.

**R8** marked permanently deferred — implementation already parses
NTLM AV pairs per [MS-NLMP] §2.2.2.1 (including the cross-domain
shapes `MsvAvDnsTreeName` / `MsvAvDnsComputerName` carrying the
trusted-domain DNS suffix), what's missing is the live capture, and
the live capture requires a multi-domain Windows lab not available
on this dev host. Same status pattern as F3 in `design/followups.md`.

Open evidence gaps table updated to reflect:
- Cross-domain NTLM: deferred (R8)
- Ghidra mapping table for completion-only bytes: no table exists
  (R3/R4 settled)
- Activate/Suspend transition (wire): partial (F44 + F46), live re-run
  pending (F50)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 06:23:05 -04:00

15 KiB

LmxProxy.dll selected decompile

FUN_10015f72 at 10015f72

Signature: undefined __thiscall FUN_10015f72(void * this, long param_1, long param_2, undefined4 param_3)


/* WARNING: Function: __EH_prolog3 replaced with injection: EH_prolog3 */
/* WARNING: Function: __EH_epilog3 replaced with injection: EH_epilog3 */

void __thiscall FUN_10015f72(void *this,long param_1,long param_2,undefined4 param_3)

{
  basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> bVar1;
  undefined4 *puVar2;
  int *piVar3;
  basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> *pbVar4;
  undefined4 *this_00;
  long in_stack_0000001c;
  undefined4 in_stack_00000030;
  long lVar5;
  wchar_t *pwVar6;
  long lVar7;
  wchar_t *pwVar8;
  long lVar9;
  wchar_t *pwVar10;
  ushort uVar11;
  undefined4 uVar12;
  _func_basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>_ptr_basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>_ptr
  *p_Var13;
  undefined4 *local_30;
  undefined4 local_2c;
  undefined4 local_28;
  undefined4 local_24;
  int *local_20;
  int local_1c;
  void *local_18;
  int local_14;
  undefined4 local_8;
  undefined4 uStack_4;
  
  uStack_4 = 0x20;
  local_8 = 0x10015f7e;
  puVar2 = (undefined4 *)FUN_100170a4(100);
  if (puVar2 == (undefined4 *)0x0) {
    this_00 = (undefined4 *)0x0;
  }
  else {
    this_00 = puVar2 + 1;
    *puVar2 = 6;
    _eh_vector_constructor_iterator_(this_00,0x10,6,FUN_10001517,FUN_10001f45);
  }
  local_1c = *(int *)((int)this + 8);
  local_14 = 0;
  if (0 < local_1c) {
    local_18 = (void *)((int)this + 4);
    do {
      piVar3 = (int *)FUN_10007d02(local_18,local_14);
      local_20 = piVar3;
      if (piVar3 != (int *)0x0) {
        (**(code **)(*piVar3 + 4))(piVar3);
      }
      local_8 = 1;
      if (piVar3 != (int *)0x0) {
        FUN_10015d08(this_00 + 0x14,param_1);
        FUN_10015d08(this_00 + 0x10,param_2);
        if ((CComVariant *)(this_00 + 0xc) != (CComVariant *)&param_3) {
          ATL::CComVariant::InternalCopy((CComVariant *)(this_00 + 0xc),(tagVARIANT *)&param_3);
        }
        FUN_10015d08(this_00 + 8,in_stack_0000001c);
        if ((CComVariant *)(this_00 + 4) != (CComVariant *)&stack0x00000020) {
          ATL::CComVariant::InternalCopy
                    ((CComVariant *)(this_00 + 4),(tagVARIANT *)&stack0x00000020);
        }
        *(undefined2 *)this_00 = 0x6024;
        this_00[2] = in_stack_00000030;
        local_2c = 0;
        local_28 = 6;
        local_24 = 0;
        local_30 = this_00;
        bVar1 = FUN_10003f01(*(basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> **)
                              (DAT_100294e0 + 0x10));
        if (bVar1 != (basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>)0x0) {
          pwVar10 = L"  Item Data Type ";
          pwVar8 = L"  item Quality ";
          pwVar6 = L"  Item Handle ";
          lVar5 = param_1;
          lVar7 = param_2;
          lVar9 = in_stack_0000001c;
          uVar12 = param_3;
          p_Var13 = endl_exref;
          pbVar4 = (basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> *)
                   FUN_10002dbf(*(int **)(DAT_100294e0 + 0x10),
                                L"CProxy_ILMXProxyServerEvents::Fire_OnDataChange firing event - Server Handle "
                               );
          uVar11 = (ushort)uVar12;
          pbVar4 = std::basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>::operator<<
                             (pbVar4,lVar5);
          pbVar4 = (basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> *)
                   FUN_10002dbf((int *)pbVar4,pwVar6);
          pbVar4 = std::basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>::operator<<
                             (pbVar4,lVar7);
          pbVar4 = (basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> *)
                   FUN_10002dbf((int *)pbVar4,pwVar8);
          pbVar4 = std::basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>::operator<<
                             (pbVar4,lVar9);
          pbVar4 = (basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> *)
                   FUN_10002dbf((int *)pbVar4,pwVar10);
          pbVar4 = std::basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>::operator<<
                             (pbVar4,uVar11);
          std::basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>::operator<<(pbVar4,p_Var13);
        }
        (**(code **)(*piVar3 + 0x18))(piVar3,1,&DAT_100201f8,0x400,1,&local_30,0,0,0);
      }
      local_8 = 0xffffffff;
      if (piVar3 != (int *)0x0) {
        (**(code **)(*piVar3 + 8))(piVar3);
      }
      local_14 = local_14 + 1;
    } while (local_14 < local_1c);
  }
  if (this_00 != (undefined4 *)0x0) {
    FUN_10015d66(this_00,3);
  }
  return;
}


FUN_1001611f at 1001611f

Signature: undefined __thiscall FUN_1001611f(void * this, long param_1, long param_2, undefined4 param_3)


/* WARNING: Function: __EH_prolog3 replaced with injection: EH_prolog3 */
/* WARNING: Function: __EH_epilog3 replaced with injection: EH_epilog3 */

void __thiscall FUN_1001611f(void *this,long param_1,long param_2,undefined4 param_3)

{
  basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> bVar1;
  undefined4 *puVar2;
  int *piVar3;
  basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> *pbVar4;
  undefined4 *this_00;
  long lVar5;
  wchar_t *pwVar6;
  long lVar7;
  _func_basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>_ptr_basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>_ptr
  *p_Var8;
  undefined4 *local_30;
  undefined4 local_2c;
  undefined4 local_28;
  undefined4 local_24;
  int *local_20;
  int local_1c;
  void *local_18;
  int local_14;
  undefined4 local_8;
  undefined4 uStack_4;
  
  uStack_4 = 0x20;
  local_8 = 0x1001612b;
  puVar2 = (undefined4 *)FUN_100170a4(0x34);
  if (puVar2 == (undefined4 *)0x0) {
    this_00 = (undefined4 *)0x0;
  }
  else {
    this_00 = puVar2 + 1;
    *puVar2 = 3;
    _eh_vector_constructor_iterator_(this_00,0x10,3,FUN_10001517,FUN_10001f45);
  }
  local_1c = *(int *)((int)this + 8);
  local_14 = 0;
  if (0 < local_1c) {
    local_18 = (void *)((int)this + 4);
    do {
      piVar3 = (int *)FUN_10007d02(local_18,local_14);
      local_20 = piVar3;
      if (piVar3 != (int *)0x0) {
        (**(code **)(*piVar3 + 4))(piVar3);
      }
      local_8 = 1;
      if (piVar3 != (int *)0x0) {
        FUN_10015d08(this_00 + 8,param_1);
        FUN_10015d08(this_00 + 4,param_2);
        *(undefined2 *)this_00 = 0x6024;
        this_00[2] = param_3;
        local_2c = 0;
        local_28 = 3;
        local_24 = 0;
        local_30 = this_00;
        bVar1 = FUN_10003f01(*(basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> **)
                              (DAT_100294e0 + 0xc));
        if (bVar1 != (basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>)0x0) {
          pwVar6 = L"  Item Handle ";
          lVar5 = param_1;
          lVar7 = param_2;
          p_Var8 = endl_exref;
          pbVar4 = (basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> *)
                   FUN_10002dbf(*(int **)(DAT_100294e0 + 0xc),
                                L"CProxy_ILMXProxyServerEvents::Fire_OnWriteComplete firing event - Server Handle "
                               );
          pbVar4 = std::basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>::operator<<
                             (pbVar4,lVar5);
          pbVar4 = (basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> *)
                   FUN_10002dbf((int *)pbVar4,pwVar6);
          pbVar4 = std::basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>::operator<<
                             (pbVar4,lVar7);
          std::basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>::operator<<(pbVar4,p_Var8);
        }
        (**(code **)(*piVar3 + 0x18))(piVar3,2,&DAT_100201f8,0x400,1,&local_30,0,0,0);
      }
      local_8 = 0xffffffff;
      if (piVar3 != (int *)0x0) {
        (**(code **)(*piVar3 + 8))(piVar3);
      }
      local_14 = local_14 + 1;
    } while (local_14 < local_1c);
  }
  if (this_00 != (undefined4 *)0x0) {
    FUN_10015d66(this_00,3);
  }
  return;
}


FUN_10016271 at 10016271

Signature: undefined __thiscall FUN_10016271(void * this, long param_1, long param_2, undefined4 param_3)


/* WARNING: Function: __EH_prolog3 replaced with injection: EH_prolog3 */
/* WARNING: Function: __EH_epilog3 replaced with injection: EH_epilog3 */

void __thiscall FUN_10016271(void *this,long param_1,long param_2,undefined4 param_3)

{
  basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> bVar1;
  undefined4 *puVar2;
  int *piVar3;
  basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> *pbVar4;
  undefined4 *this_00;
  long lVar5;
  wchar_t *pwVar6;
  long lVar7;
  _func_basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>_ptr_basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>_ptr
  *p_Var8;
  undefined4 *local_30;
  undefined4 local_2c;
  undefined4 local_28;
  undefined4 local_24;
  int *local_20;
  int local_1c;
  void *local_18;
  int local_14;
  undefined4 local_8;
  undefined4 uStack_4;
  
  uStack_4 = 0x20;
  local_8 = 0x1001627d;
  puVar2 = (undefined4 *)FUN_100170a4(0x34);
  if (puVar2 == (undefined4 *)0x0) {
    this_00 = (undefined4 *)0x0;
  }
  else {
    this_00 = puVar2 + 1;
    *puVar2 = 3;
    _eh_vector_constructor_iterator_(this_00,0x10,3,FUN_10001517,FUN_10001f45);
  }
  local_1c = *(int *)((int)this + 8);
  local_14 = 0;
  if (0 < local_1c) {
    local_18 = (void *)((int)this + 4);
    do {
      piVar3 = (int *)FUN_10007d02(local_18,local_14);
      local_20 = piVar3;
      if (piVar3 != (int *)0x0) {
        (**(code **)(*piVar3 + 4))(piVar3);
      }
      local_8 = 1;
      if (piVar3 != (int *)0x0) {
        FUN_10015d08(this_00 + 8,param_1);
        FUN_10015d08(this_00 + 4,param_2);
        local_2c = 0;
        local_24 = 0;
        *(undefined2 *)this_00 = 0x6024;
        this_00[2] = param_3;
        local_28 = 3;
        local_30 = this_00;
        bVar1 = FUN_10003f01(*(basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> **)
                              (DAT_100294e0 + 0xc));
        if (bVar1 != (basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>)0x0) {
          pwVar6 = L"  Item Handle ";
          lVar5 = param_1;
          lVar7 = param_2;
          p_Var8 = endl_exref;
          pbVar4 = (basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> *)
                   FUN_10002dbf(*(int **)(DAT_100294e0 + 0xc),
                                L"CProxy_ILMXProxyServerEvents::Fire_OperationComplete firing event - Server Handle "
                               );
          pbVar4 = std::basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>::operator<<
                             (pbVar4,lVar5);
          pbVar4 = (basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> *)
                   FUN_10002dbf((int *)pbVar4,pwVar6);
          pbVar4 = std::basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>::operator<<
                             (pbVar4,lVar7);
          std::basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>::operator<<(pbVar4,p_Var8);
        }
        (**(code **)(*piVar3 + 0x18))(piVar3,3,&DAT_100201f8,0x400,1,&local_30,0,0,0);
      }
      local_8 = 0xffffffff;
      if (piVar3 != (int *)0x0) {
        (**(code **)(*piVar3 + 8))(piVar3);
      }
      local_14 = local_14 + 1;
    } while (local_14 < local_1c);
  }
  if (this_00 != (undefined4 *)0x0) {
    FUN_10015d66(this_00,3);
  }
  return;
}


FUN_100163c0 at 100163c0

Signature: undefined __thiscall FUN_100163c0(void * this, long param_1, long param_2, undefined4 param_3)


/* WARNING: Function: __EH_prolog3 replaced with injection: EH_prolog3 */
/* WARNING: Function: __EH_epilog3 replaced with injection: EH_epilog3 */

void __thiscall FUN_100163c0(void *this,long param_1,long param_2,undefined4 param_3)

{
  basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> bVar1;
  undefined4 *puVar2;
  int *piVar3;
  basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> *pbVar4;
  undefined4 *this_00;
  undefined4 in_stack_00000040;
  long lVar5;
  wchar_t *pwVar6;
  long lVar7;
  _func_basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>_ptr_basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>_ptr
  *p_Var8;
  undefined4 *local_30;
  undefined4 local_2c;
  undefined4 local_28;
  undefined4 local_24;
  int *local_20;
  int local_1c;
  void *local_18;
  int local_14;
  undefined4 local_8;
  undefined4 uStack_4;
  
  uStack_4 = 0x20;
  local_8 = 0x100163cc;
  puVar2 = (undefined4 *)FUN_100170a4(0x74);
  if (puVar2 == (undefined4 *)0x0) {
    this_00 = (undefined4 *)0x0;
  }
  else {
    this_00 = puVar2 + 1;
    *puVar2 = 7;
    _eh_vector_constructor_iterator_(this_00,0x10,7,FUN_10001517,FUN_10001f45);
  }
  local_1c = *(int *)((int)this + 8);
  local_14 = 0;
  if (0 < local_1c) {
    local_18 = (void *)((int)this + 4);
    do {
      piVar3 = (int *)FUN_10007d02(local_18,local_14);
      local_20 = piVar3;
      if (piVar3 != (int *)0x0) {
        (**(code **)(*piVar3 + 4))(piVar3);
      }
      local_8 = 1;
      if (piVar3 != (int *)0x0) {
        FUN_10015d08(this_00 + 0x18,param_1);
        FUN_10015d08(this_00 + 0x14,param_2);
        FUN_10015d08(this_00 + 0x10,param_3);
        if ((CComVariant *)(this_00 + 0xc) != (CComVariant *)&stack0x00000010) {
          ATL::CComVariant::InternalCopy
                    ((CComVariant *)(this_00 + 0xc),(tagVARIANT *)&stack0x00000010);
        }
        if ((CComVariant *)(this_00 + 8) != (CComVariant *)&stack0x00000020) {
          ATL::CComVariant::InternalCopy
                    ((CComVariant *)(this_00 + 8),(tagVARIANT *)&stack0x00000020);
        }
        if ((CComVariant *)(this_00 + 4) != (CComVariant *)&stack0x00000030) {
          ATL::CComVariant::InternalCopy
                    ((CComVariant *)(this_00 + 4),(tagVARIANT *)&stack0x00000030);
        }
        *(undefined2 *)this_00 = 0x6024;
        this_00[2] = in_stack_00000040;
        local_2c = 0;
        local_28 = 7;
        local_24 = 0;
        local_30 = this_00;
        bVar1 = FUN_10003f01(*(basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> **)
                              (DAT_100294e0 + 0x10));
        if (bVar1 != (basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>)0x0) {
          pwVar6 = L"  Item Handle ";
          lVar5 = param_1;
          lVar7 = param_2;
          p_Var8 = endl_exref;
          pbVar4 = (basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> *)
                   FUN_10002dbf(*(int **)(DAT_100294e0 + 0x10),
                                L"CProxy_ILMXProxyServerEvents2::Fire_OnBufferedDataChange firing event - Server Handle "
                               );
          pbVar4 = std::basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>::operator<<
                             (pbVar4,lVar5);
          pbVar4 = (basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_> *)
                   FUN_10002dbf((int *)pbVar4,pwVar6);
          pbVar4 = std::basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>::operator<<
                             (pbVar4,lVar7);
          std::basic_ostream<wchar_t,struct_std::char_traits<wchar_t>_>::operator<<(pbVar4,p_Var8);
        }
        (**(code **)(*piVar3 + 0x18))(piVar3,1,&DAT_100201f8,0x400,1,&local_30,0,0,0);
      }
      local_8 = 0xffffffff;
      if (piVar3 != (int *)0x0) {
        (**(code **)(*piVar3 + 8))(piVar3);
      }
      local_14 = local_14 + 1;
    } while (local_14 < local_1c);
  }
  if (this_00 != (undefined4 *)0x0) {
    FUN_10015d66(this_00,3);
  }
  return;
}