// Research only, verified assembly SHA256: // c5e02e6e984f7e5577c78b995a8efeee2d06ee22e67d484ad5e859c8bf21e144. // CraftConfigRow.FromBinary -> loader 1e0db310 -> table at GetAll 1e0dadf0. // Getter/entry layout proven by 1e0db000 (24-byte entries, value at +16). // Runs on the existing managed handbook callback; no gameplay actions/loaders. const m=Process.getModuleByName('GameAssembly.dll'); const check=(rva,expected)=>{const a=Array.from(new Uint8Array(m.base.add(rva).readByteArray(expected.length)));if(a.some((x,i)=>x!==expected[i]))throw Error('Code identity differs');}; check(0x1e0dadf0,[0x48,0x83,0xec,0x28]);check(0x1d3efb60,[0x56,0x57,0x48,0x83,0xec,0x28]); const all=new NativeFunction(m.base.add(0x1e0dadf0),'pointer',['pointer']); const serialize=new NativeFunction(m.base.add(0x1d3efb60),'pointer',['pointer','pointer']); let index=0,count=0,entries=null,done=false; Interceptor.attach(m.base.add(0xdb5f860),{onLeave(){if(done)return;try{ if(entries===null){const d=all(ptr(0));if(d.isNull())throw Error('Craft table is missing');count=d.add(0x20).readU32();entries=d.add(0x18).readPointer();if(count>2048||entries.isNull()||entries.add(0x18).readU32()32768)throw Error('Craft row bound');const json=value.add(0x14).readUtf16String(n);const parsed=JSON.parse(json);if(!parsed.CraftID||!parsed.CraftEquipID||!Array.isArray(parsed.CostEquipList))throw Error('Craft schema differs');send({kind:'ROW',json}); } if(index>=count){done=true;send({kind:'END',count});} }catch(e){done=true;send({kind:'ERROR',error:String(e)});}}}); send({kind:'ATTACHED',scope:'flat craft rows only'});