460c61df43
Five-stage Ghidra headless decompile traces the byte-to-MXSTATUS_PROXY synthesis path end-to-end across LmxProxy.dll and Lmx.dll. New evidence files committed alongside R3/R4 verdict update: - analysis/ghidra/exports/LmxProxy.dll.fire-event-xrefs.md - analysis/ghidra/exports/LmxProxy.dll.status-synthesis-decompile.md - analysis/ghidra/exports/LmxProxy.dll.mxstatus-safearray-decompile.md - analysis/ghidra/exports/Lmx.dll.set-attribute-result-decompile.md Layer-by-layer findings (bytes flow inward; synthesis flows outward): 1. `Lmx.aaDCT` at 0x10178fc0 is `SysAllocString(L"Lmx.aaDCT")` — a tracing category BSTR, not a table. 2. `MXSTATUS_PROXY` is a 16-byte marshalled struct (4 × i16 padded to i32 boundaries with Pack=4) — the OUTPUT of synthesis, not a lookup entry. 3. `LmxProxy.dll` Fire_* event handlers receive already-populated `MXSTATUS_PROXY[]` and forward through ATL dispatch — no synthesis. 4. `LmxProxy.dll` Fire_* CALLERS (FUN_1001657f / FUN_10016b50 / FUN_10016d4b) call FUN_10003f60(out_safearray, in_status_ptr, count=1) which is a VERBATIM memcpy of an existing 14-byte buffer into the SAFEARRAY — no transformation. 5. `Lmx.dll`'s `PreboundReference::OnSetAttributeResult` (FUN_10114a90) receives an already-populated `short *param_7` status buffer. Log line confirms the layout: `<success %d category %d detectedBy %d detail %d>`. Dispatches on typed values — synthesis is upstream of this function too. The synthesizer is the NMX-frame decoder in Lmx.dll that calls OnSetAttributeResult / OnGetAttributeResult / equivalent OperationComplete handler. The decoder takes raw NMX bytes plus operation context (item handle, engine state, retry state, correlation id) and computes the populated MXSTATUS_PROXY. There is NO static lookup table — synthesis is per-message contextual. Two viable paths to typed promotion (both substantial; neither a small codec patch): - Path A: port the synthesizer. ~1-2 weeks. Requires extending the Rust session to track per-operation context (handles, retries, correlation ids). Out of V1 scope. - Path B: empirical capture pairs. ~30 min × 6-10 scenarios. Output is a (byte, context → status) mapping that approximates without re-implementing. Risk: mapping is only valid for captured contexts. R3/R4 stay settled at verbatim-preserve. The .NET reference does the same for the same reason: the synthesizer is too context- dependent to mirror without porting the entire operation-tracking state machine. Reopen criteria sharpened: either (a) a consumer files a concrete use case for typed promotion of a specific byte+context combination (Path B's empirical capture for that one combination is the cheapest answer); or (b) a major-version bump justifies the state-machine port (Path A). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
17 KiB
17 KiB
Lmx.dll selected decompile
FUN_10114a90 at 10114a90
Signature: undefined FUN_10114a90(void)
void __thiscall
FUN_10114a90(undefined4 *param_1,int param_2,int *param_3,ushort param_4,undefined4 param_5,
void *param_6,short *param_7)
{
char cVar1;
uint uVar2;
undefined4 uVar3;
basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_> *pbVar4;
int iVar5;
undefined4 *puVar6;
wchar_t *pwVar7;
wchar_t *pwVar8;
size_t _MaxCount;
DWORD DVar9;
int iVar10;
int *piVar11;
undefined2 uVar12;
wchar_t _Ch;
_func_basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_>_ptr_basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_>_ptr
*p_Var13;
undefined4 uVar14;
undefined1 local_ba4 [20];
undefined1 local_b90 [20];
undefined4 local_b7c;
undefined4 local_b74;
void *local_b70;
short *local_b6c;
undefined4 *local_b68;
int *local_b64;
char local_b5e;
char local_b5d;
undefined4 *local_b5c [391];
wchar_t local_540 [520];
undefined1 local_130 [20];
undefined1 local_11c [20];
undefined1 local_108 [60];
undefined1 local_cc [20];
undefined4 local_b8 [36];
undefined4 local_28;
undefined4 local_24;
undefined4 local_20;
uint local_14;
void *local_10;
undefined1 *puStack_c;
undefined4 local_8;
local_8 = 0xffffffff;
puStack_c = &LAB_101729a5;
local_10 = ExceptionList;
uVar2 = DAT_101d60b8 ^ (uint)&stack0xfffffffc;
ExceptionList = &local_10;
local_b5c[0] = (undefined4 *)(uint)param_4;
local_b74 = param_5;
local_b70 = param_6;
local_b6c = param_7;
local_14 = uVar2;
cVar1 = FUN_100408d0(uVar2);
if (cVar1 != '\0') {
local_20 = *(undefined4 *)(local_b6c + 2);
swprintf_s(local_540,0x104,L"<success %d category %d detectedBy %d detail %d>",
(int)(short)*(undefined4 *)local_b6c,local_20,*(undefined4 *)(local_b6c + 4),
(int)local_b6c[6]);
local_b64 = (int *)FUN_10004010(local_b74,local_b70);
local_b5c[0] = (undefined4 *)FUN_100040a0(local_b5c[0]);
uVar3 = FUN_100300d0(param_3);
iVar5 = param_2;
p_Var13 = endl_exref;
pbVar4 = (basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_> *)
FUN_1001a0e0(*(undefined4 *)(DAT_101d6474 + 0x20),
L"PreboundReference::OnSetAttributeResult - ENTER correlationId ",param_2,
L" pValue ",uVar3,L" quality ",local_b5c[0],L" timestamp ",local_b64,
L" mxStatus ",local_540);
pbVar4 = std::basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_>::operator<<
(pbVar4,iVar5);
uVar3 = FUN_1001a0e0(pbVar4);
uVar3 = FUN_1001a0e0(uVar3);
uVar3 = FUN_1001a0e0(uVar3);
uVar3 = FUN_1001a0e0(uVar3);
uVar3 = FUN_1001a0e0(uVar3);
uVar3 = FUN_1001a0e0(uVar3);
uVar3 = FUN_1001a0e0(uVar3);
pbVar4 = (basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_> *)
FUN_1001a0e0(uVar3);
std::basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_>::operator<<
(pbVar4,p_Var13);
}
if (param_2 == 0) {
if (*local_b6c == -1) {
iVar5 = (**(code **)(*param_3 + 0x60))(param_3,&local_b68);
iVar5 = FUN_10048e60(iVar5 == 0,iVar5,300,"preboundreference.cpp");
if (iVar5 == 0) goto LAB_1011543c;
if (local_b68 != (undefined4 *)0x0) {
local_b64 = (int *)0x0;
local_8 = 1;
uVar12 = 0x1011;
iVar5 = (**(code **)(*param_3 + 0x80))(param_3,&local_b64);
if (iVar5 == 0) {
FUN_1008e710(local_b64);
local_8._0_1_ = 2;
FUN_10112f20(local_b90);
local_8._0_1_ = 1;
FUN_10021cc0();
FUN_1005f730(&local_28);
uVar3 = CONCAT22(uVar12,(undefined2)local_20);
cVar1 = FUN_100057b0(local_28,local_24,uVar3,0x138,"preboundreference.cpp");
uVar12 = (undefined2)((uint)uVar3 >> 0x10);
if (cVar1 != '\0') {
FUN_1004c220();
local_8._0_1_ = 3;
FUN_1004c320(param_1[0x14]);
local_b5c[0] = local_b8;
uVar12 = 0x1011;
FUN_10073b80(local_b5c,0);
iVar5 = FUN_1005f730(local_130);
FUN_10040470(*(undefined2 *)(iVar5 + 2));
local_8._0_1_ = 1;
FUN_1002e080();
}
cVar1 = FUN_100057b0(local_28,local_24,CONCAT22(uVar12,(undefined2)local_20),0x144,
"preboundreference.cpp");
if (cVar1 == '\0') {
param_1[0x2a] = 4;
}
else {
iVar5 = FUN_1005f730(local_11c);
if (*(short *)(iVar5 + 10) == 0) {
FUN_101131d0();
}
else {
param_1[0x2a] = 3;
param_1[0x29] = 0;
FUN_10114620();
}
}
}
local_8 = 0xffffffff;
if (local_b64 != (int *)0x0) {
(**(code **)(*local_b64 + 8))(local_b64);
}
goto LAB_1011543c;
}
}
else if (((DAT_101d8c40 == 2) && (param_1[0x29] == 0)) &&
(*(ushort *)(param_1[0x19] + 0x2ac) - 0x7c17 < 0x3e9)) {
cVar1 = FUN_100408d0(uVar2);
if (cVar1 != '\0') {
uVar3 = FUN_10003fc0(*(undefined4 *)local_b6c,*(undefined4 *)(local_b6c + 2),
*(undefined4 *)(local_b6c + 4),*(undefined4 *)(local_b6c + 6));
p_Var13 = endl_exref;
uVar3 = FUN_1001a0e0(*(undefined4 *)(DAT_101d6474 + 0x1c),
L"PreboundReference - attempting local platform <",param_1 + 6,
L"> - status ",uVar3);
uVar3 = FUN_1001dec0(uVar3);
uVar3 = FUN_1001a0e0(uVar3);
pbVar4 = (basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_> *)
FUN_1001a0e0(uVar3);
std::basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_>::operator<<
(pbVar4,p_Var13);
}
param_1[5] = param_1[5] + 1;
param_1[0x2a] = 1;
param_1[0x29] = 1;
FUN_10112cd0();
goto LAB_1011543c;
}
LAB_10115432:
param_1[0x2a] = 4;
goto LAB_1011543c;
}
if (param_2 != 1) goto LAB_1011543c;
param_1[0x2a] = 6;
if (*local_b6c != -1) {
if (*(char *)(param_1 + 0x1b) != '\0') {
if ((uint)param_1[0x21] < 8) {
puVar6 = param_1 + 0x1c;
}
else {
puVar6 = (undefined4 *)param_1[0x1c];
}
iVar5 = (**(code **)(*(int *)param_1[0x14] + 0x44))((int *)param_1[0x14],puVar6);
if (iVar5 < 0) {
/* WARNING: Subroutine does not return */
FUN_1005bf30(iVar5,0,"E:\\BldSrc\\6\\s\\ExtInterfaces\\Lmx\\IMxReferencePtr.h",0x75);
}
*(undefined1 *)(param_1 + 0x1b) = 0;
}
if (*(int *)(local_b6c + 2) == 3) {
LAB_1011502e:
param_1[0x2a] = 6;
goto LAB_1011543c;
}
if ((*(int *)(local_b6c + 2) == 4) && (local_b6c[6] == 0x1f42)) {
local_b70 = operator_new(8);
local_8 = 0xb;
if (local_b70 == (void *)0x0) {
local_b5c[0] = (undefined4 *)0x0;
}
else {
local_b5c[0] = (undefined4 *)FUN_10112b50(param_1);
}
local_8 = 0xffffffff;
cVar1 = FUN_10048d60(local_b5c[0] != (undefined4 *)0x0,0x23b,"preboundreference.cpp");
if (cVar1 != '\0') {
uVar3 = FUN_10016fd0();
FUN_1005f7e0(uVar3);
FUN_1004c220();
local_8 = 0xc;
FUN_1004c320(param_1[0x14]);
local_b68 = local_b8;
FUN_10073b80(&local_b68,0);
param_1[5] = param_1[5] + 1;
param_1[0x2a] = 1;
DVar9 = GetTickCount();
FUN_1008f150(local_b5c[0],0,0,0,0,*(undefined4 *)local_b6c,*(undefined4 *)(local_b6c + 2),
*(undefined4 *)(local_b6c + 4),*(undefined4 *)(local_b6c + 6),0,DVar9);
local_8 = 0xffffffff;
FUN_1002e080();
}
goto LAB_1011543c;
}
goto LAB_10115432;
}
iVar5 = (**(code **)(*param_3 + 0x60))(param_3,&local_b68);
iVar5 = FUN_10048e60(iVar5 == 0,iVar5,0x19d,"preboundreference.cpp");
if (iVar5 == 0) goto LAB_1011543c;
if (local_b68 == (undefined4 *)0x0) goto LAB_1011502e;
local_b64 = (int *)0x0;
local_8 = 6;
uVar12 = 0x1011;
iVar5 = (**(code **)(*param_3 + 0x80))(param_3,&local_b64);
if (iVar5 == 0) {
FUN_1008e710(local_b64);
local_8._0_1_ = 7;
FUN_10112f20(local_ba4);
local_8 = CONCAT31(local_8._1_3_,6);
FUN_10021cc0();
if (*(char *)(param_1 + 0x1b) != '\0') {
piVar11 = param_1 + 0x1c;
if (7 < (uint)param_1[0x21]) {
piVar11 = (int *)*piVar11;
}
FUN_1005f700(piVar11);
*(undefined1 *)(param_1 + 0x1b) = 0;
}
iVar5 = FUN_1005f730(local_108);
if (*(short *)(iVar5 + 10) == 0) {
local_b5d = '\0';
local_b5e = '\0';
puVar6 = (undefined4 *)FUN_1005f730(local_cc);
cVar1 = FUN_100057b0(*puVar6,puVar6[1],CONCAT22(uVar12,*(undefined2 *)(puVar6 + 2)),0x1c1,
"preboundreference.cpp");
if (cVar1 == '\0') {
if (*(char *)(param_1 + 4) != '\0') {
FUN_1004c220();
local_8._0_1_ = 8;
FUN_1004c320(param_1[0x14]);
local_b5c[0] = local_b8;
FUN_10073b80(local_b5c,0);
local_8 = CONCAT31(local_8._1_3_,6);
FUN_1002e080();
}
local_b5e = '\x01';
}
else {
pwVar7 = (wchar_t *)FUN_1005f590();
cVar1 = FUN_10134a10(pwVar7);
if (cVar1 == '\0') {
pwVar8 = wcschr(pwVar7,L'.');
if ((pwVar8 != (wchar_t *)0x0) &&
(_MaxCount = (int)pwVar8 - (int)pwVar7 >> 1, _MaxCount != 0)) {
pwVar8 = (wchar_t *)FUN_1005f610();
iVar5 = _wcsnicmp(pwVar7,pwVar8,_MaxCount);
if (iVar5 == 0) {
_Ch = L'.';
pwVar7 = (wchar_t *)FUN_1005f660();
pwVar7 = wcschr(pwVar7,_Ch);
if (pwVar7 == (wchar_t *)0x0) goto LAB_10114e2f;
}
local_b5d = '\x01';
}
}
}
LAB_10114e2f:
if ((*(char *)(param_1 + 4) == '\0') || ((local_b5d == '\0' && (local_b5e == '\0')))) {
param_1[0x2a] = 4;
}
else {
local_b70 = operator_new(8);
local_8._0_1_ = 9;
if (local_b70 == (void *)0x0) {
local_b5c[0] = (undefined4 *)0x0;
}
else {
local_b5c[0] = (undefined4 *)FUN_10112b50(param_1);
}
local_8 = CONCAT31(local_8._1_3_,6);
cVar1 = FUN_10048d60(local_b5c[0] != (undefined4 *)0x0,0x1ee,"preboundreference.cpp");
if (cVar1 == '\0') {
param_1[0x2a] = 4;
iVar5 = FUN_10022ff0();
if (*(int *)(iVar5 + 0xac) == 0) {
iVar10 = FUN_1002f080();
if (iVar10 != 0) goto LAB_10114f66;
uVar3 = 0;
}
else {
LAB_10114f66:
uVar3 = *(undefined4 *)(iVar5 + 0xac);
}
uVar14 = 0;
FUN_10022ff0(uVar3,0);
cVar1 = FUN_10022ba0(uVar3,uVar14);
if (cVar1 != '\0') {
uVar3 = FUN_1005f590();
uVar3 = FUN_10022ff0(L"PreboundReference::OnSetAttributeResult unable to crreate CPreboundReferenceAdapter for ref %s"
,uVar3);
FUN_10022cb0(uVar3);
}
}
else {
*(undefined1 *)(param_1 + 4) = 0;
uVar3 = FUN_10016fd0();
FUN_1005f7e0(uVar3);
FUN_1008fc40(&DAT_1017a514);
FUN_1008fc70(&DAT_1017a514);
param_1[5] = param_1[5] + 1;
param_1[0x2a] = 1;
DVar9 = GetTickCount();
local_b70 = (void *)CONCAT22(local_b70._2_2_,0x1f42);
local_b7c = (uint)local_b7c._2_2_ << 0x10;
FUN_1008f150(local_b5c[0],0,0,0,0,local_b7c,4,0,local_b70,0,DVar9);
}
}
}
else {
param_1[0x2a] = 3;
param_1[0x29] = 0;
FUN_10114620();
}
}
local_8 = 0xffffffff;
if (local_b64 != (int *)0x0) {
(**(code **)(*local_b64 + 8))(local_b64);
}
LAB_1011543c:
if (*(char *)(param_1 + 0x1b) != '\0') {
if ((uint)param_1[0x21] < 8) {
puVar6 = param_1 + 0x1c;
}
else {
puVar6 = (undefined4 *)param_1[0x1c];
}
iVar5 = (**(code **)(*(int *)param_1[0x14] + 0x44))((int *)param_1[0x14],puVar6);
if (iVar5 < 0) {
/* WARNING: Subroutine does not return */
FUN_1005bf30(iVar5,0,"E:\\BldSrc\\6\\s\\ExtInterfaces\\Lmx\\IMxReferencePtr.h",0x75);
}
*(undefined1 *)(param_1 + 0x1b) = 0;
}
if ((param_1[0x2a] != 1) && (param_1[0x2a] != 2)) {
FUN_10050df0(local_b6c,param_1);
}
piVar11 = param_1 + 5;
*piVar11 = *piVar11 + -1;
if (*piVar11 == 0) {
(**(code **)*param_1)(1);
}
local_b5c[0] = (undefined4 *)param_1[0x2a];
if (param_1[5] == 1) {
local_b68 = param_1;
piVar11 = (int *)FUN_100484c0(&local_b70,&local_b68);
iVar5 = *piVar11;
cVar1 = FUN_10048d60(iVar5 != *(int *)(param_1[0x19] + 0x180),0x273,"preboundreference.cpp");
if (cVar1 != '\0') {
FUN_100382e0(&local_b70,iVar5);
piVar11 = param_1 + 5;
*piVar11 = *piVar11 + -1;
if (*piVar11 == 0) {
(**(code **)*param_1)(1);
}
}
}
cVar1 = FUN_100408d0();
if (cVar1 != '\0') {
uVar3 = FUN_10001e20(local_b5c);
p_Var13 = endl_exref;
uVar3 = FUN_1001a0e0(*(undefined4 *)(DAT_101d6474 + 0x20),
L"PreboundReference::OnSetAttributeResult - EXIT status ",uVar3);
pbVar4 = (basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_> *)
FUN_1001a0e0(uVar3);
std::basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_>::operator<<
(pbVar4,p_Var13);
}
ExceptionList = local_10;
__security_check_cookie(local_14 ^ (uint)&stack0xfffffffc);
return;
}
FUN_100dc750 at 100dc750
Signature: undefined FUN_100dc750(void)
void __thiscall FUN_100dc750(int *param_1,uint param_2,int param_3,int param_4,BSTR param_5)
{
char cVar1;
uint uVar2;
undefined4 uVar3;
basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_> *pbVar4;
undefined4 *puVar5;
_func_basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_>_ptr_basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_>_ptr
*p_Var6;
uint local_23c;
int *local_234;
BSTR local_230;
uint local_22c;
int local_228;
int local_224;
BSTR local_220;
wchar_t local_21c [260];
uint local_14;
void *local_10;
undefined1 *puStack_c;
undefined4 local_8;
local_8 = 0xffffffff;
puStack_c = &LAB_1016d12b;
local_10 = ExceptionList;
uVar2 = DAT_101d60b8 ^ (uint)&stack0xfffffffc;
ExceptionList = &local_10;
local_14 = uVar2;
cVar1 = FUN_100408d0(uVar2);
if (cVar1 != '\0') {
local_23c._0_2_ = (short)param_2;
swprintf_s(local_21c,0x104,L"<success %d category %d detectedBy %d detail %d>",
(int)(short)local_23c,param_3,param_4,(int)(short)param_5);
p_Var6 = endl_exref;
uVar3 = FUN_1001a0e0(*(undefined4 *)(DAT_101d6474 + 0x14),
L"DemandReadCallback::CancelWithStatus - status ",local_21c);
pbVar4 = (basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_> *)
FUN_1001a0e0(uVar3);
std::basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_>::operator<<
(pbVar4,p_Var6);
}
if (((param_3 == 5) && (param_4 == 0)) && ((short)param_5 == 1)) {
local_23c = param_2 & 0xffff0000;
local_230 = (BSTR)CONCAT22(local_230._2_2_,5);
local_228 = 3;
local_22c = local_23c;
local_224 = 2;
local_220 = local_230;
}
else {
local_22c = param_2;
local_228 = param_3;
local_224 = param_4;
local_220 = param_5;
}
cVar1 = FUN_100408d0(uVar2);
if (cVar1 != '\0') {
swprintf_s(local_21c,0x104,L"<success %d category %d detectedBy %d detail %d>",
(int)(short)local_22c,local_228,local_224,(int)(short)local_220);
p_Var6 = endl_exref;
uVar3 = FUN_1001a0e0(*(undefined4 *)(DAT_101d6474 + 0x14),
L"DemandReadCallback::CancelWithStatus - Calling OnGetAttributeResult with status "
,local_21c);
pbVar4 = (basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_> *)
FUN_1001a0e0(uVar3);
std::basic_ostream<unsigned_short,struct_std::char_traits<unsigned_short>_>::operator<<
(pbVar4,p_Var6);
}
puVar5 = (undefined4 *)FUN_10005170();
local_8 = 0;
(**(code **)(*param_1 + 4))(*puVar5,0,DAT_101d6504,DAT_101d6508,&local_22c);
local_8 = 0xffffffff;
if (local_234 != (int *)0x0) {
(**(code **)(*local_234 + 8))(local_234);
}
SysFreeString(local_230);
ExceptionList = local_10;
__security_check_cookie(local_14 ^ (uint)&stack0xfffffffc);
return;
}