
    Lj|G                       d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	 ddl
mZ ddlmZmZmZ  e	e      j#                         j$                  d   Zed	z  Zed
z  Zedz  ZdZdZd"dZd#dZd$dZd%dZd&dZd'dZd(dZd)d*dZ d+dZ!d,dZ"d-dZ#d-dZ$d.dZ%d/dZ&ddd0dZ'd1dZ(d2d Z)e*d!k(  r e+ e)             y)3a  Classify static references to the generic display/object VM root.

The generic runner at 0x00402321 is intentionally broad: battle effects,
status/menu descriptors, active objects, and generic script objects can all
install it as their update callback.  This pass classifies every immediate
reference to that root so we do not mistake generic object creation for a
normal-field ESC/X HUD opener or a scene-route producer.
    )annotationsN)Counter)Path)Any)offset_to_varead_sectionsva_to_offset   zHwanse2.exeoutwebi!#@ i[[C c                    | dS d| dS )N-0x08x values    1tools/build_display_vm_root_ref_context_review.pyhxr      s    -35r%%55    c                V    t        j                  | dd      S t        |       d      S )N T)quote)htmlescapestrr   s    r   hr   #   s%    ;;U]r$GGE
$GGr   c                r    | D ]2  }t        |d         }|t        |d         z   }||cxk  r	|k  s.|c S  4 y )Nrawraw_sizeint)sectionsoffsetsectionstartends        r   section_for_offsetr(   '   sO     GEN#c'*-..F S N !
 r   c                v    t        | |      }|yt        | |      }|dS t        |j                  dd            S )Nr   name)r	   r(   r   get)r#   var$   r%   s       r   section_name_for_var-   0   sA    (B'F~ 62G2Bc'++fb*A&BBr   c                   t        d |D              }t        |d         }|t        |d         z   }g }|}	 | j                  d||      }|dk  rn%t        ||      }||j	                  |       |dz   }>t        t        |            }g }	t        |      D ]O  \  }
}|
dz   t        |      k  r||
dz      nt        |d         t        |d         z   }|	j	                  ||d       Q |	S )	Nc              3  J   K   | ]  }|j                  d       dk(  s|  yw)r*   .textN)r+   ).0r%   s     r   	<genexpr>z"function_ranges.<locals>.<genexpr>9   s      RG7;;v3F'3QRs   ##r   r    s   Ur   r
   r,   )startVaendVa)	nextr"   findr   appendsortedset	enumeratelen)exer#   text	raw_startraw_endstartsposhitr,   rowsindexstart_vanext_vas                r   function_rangesrG   8   s   RxRRDDK I#d:.//GF
C
hhW57(C(>MM"Ag  CK F!#D$V, =x',qy3v;'>&#CT
OVYZ^_iZjVkDk7;<= Kr   c                d    | D ]+  }t        |d         |cxk  rt        |d         k  s'|c S  - y )Nr3   r4   r!   )	functionsr,   functions      r   owner_functionrK   N   sB     x	"#rBC0A,BBO C r   c                    | y| dk(  ry| dk(  ryd| cxk  rdk  ry d	| cxk  rd
k  ry d| cxk  rdk  ry d| cxk  rdk  ry d| cxk  rdk  ry d| cxk  rdk  ry d| cxk  rdk  ry yy)Nzunknown-owneri"@ zgeneric-vm-object-wrapperiI%@ zgeneric-vm-child-object-factoryi j@ i {@ z$generic-object-script-handler-familyi @ iP@ zsave/menu/display-helper-familyi A i QA *battle-effect/helper-object-spawner-familyi A iPA z&text-status/menu-display-object-familyi B i B z"resource-or-display-object-factoryi C i )C %active-descriptor/materializer-familyi /C i 2C z"active-object-script-update-familyzunclassified-ownerr   )rE   s    r   classify_ownerrO   U   s    :*:0X++5 ,X++0 ,X++; ,X++7 ,X++3 ,X++6 ,X++3 ,r   c                    t        t        |       dz
  ||z         }t        ||      D ]B  }| |   dk7  rt        ||      }|t	        j
                  d| |dz         d   }||dz   |z   fc S  y )N      <ir
   r      )minr;   ranger   structunpack_from)r<   r#   r$   limitr'   call_offcall_varels           r   call_target_afterr]   m   s    
c#hlFUN
+C&#& *x=D x2?  sHqL9!<!c)))* r   c                   |dk\  r'| |dz
     dk(  r| |dz
     dk(  rt        | |dz
           S |dk\  r| |dz
     dk(  r| |dz
     dk(  ry|dk\  r<| |dz
     dk(  r1| |dz
     dk(  r&t        t        j                  d	| |d
z
        d         S y)N   j   r
   h      P   dynamic-stack-byte   <IrT   r   unknown)r   r   rW   rX   )r<   r$   s     r   previous_object_kind_argrh   z   s    {s6A:$.3vz?d3J3vz?##{s6A:$.3vz?d3J#{s6A:$.3vz?d3J&$$T3
;A>??r   c                   t        ||      }|t        d|dd      |dkD  r| |dz
     dk(  rt        | |      }t        | ||dz         }|r|nd\  }}|t        k(  r%d	}|d
k(  rd}	n|dk(  rd}	n|dk(  rd}	n|dk(  rd}	nd}	nd}d}	|t        |      t        ||      |||	t        |      t        |      | t        d|dz
        |dz    j                  d      d	S |dk\  rL| |dz
  | dk(  rA|t        |      t        ||      ddddd| t        d|dz
        |dz    j                  d      d	S |t        |      t        ||      ddd dd| t        d|dz
        |dz    j                  d      d	S )!Nzraw offset z#xz is not mapped to a VAr   r
   ra   rQ   )NN%object-create/install-display-vm-root0zgeneric/root display object1z$descriptor/materialized child object2z#battle/effect/display helper objectrd   zruntime-selected object kindzunknown object kindzpush-reference-nonallocatorzunclassified push reference       )	refVarefVaHexr%   refKindobjectKindArgobjectKindDomainallocatorCallVaallocatorTargetVa
contextHexr_   s   @object-field-callback-storer   z!stores 0x00402321 into [eax+0x10]r   zunclassified-dword-referenceunclassified)	r   
ValueErrorrh   r]   OBJECT_ALLOCATOR_VAr   r-   maxhex)
r<   r#   r$   ref_vakind_argcallr[   	target_vaclassificationdomains
             r   classify_refr      s   (F+F~;vbk1GHIIzc&1*o-+C8 h
;%)T|++DN36S?S>117.:N2F6
*8V<%% &!'{!#Ic!Vb[1FRK@DDSI

 
	
 {s6A:/?B6
*8V<4 C"!$c!Vb[1FRK@DDSI

 
	
 vJ&x81* #a"-<@@E
 
r   c                   t        j                  dt              }g }| j                  |      }|dk7  rt	        ||      }|it        | ||      }t        |t        |d               }|d nt        |d         }	|	|d<   t        |	      |d<   t        |	      |d<   |j                  |       | j                  ||dz         }|dk7  r|S )	Nrf   rq   r3   ownerStartVaownerStartVaHex
ownerClassr
   )rW   packDISPLAY_VM_ROOT_VAr6   r(   r   rK   r"   r   rO   r7   )
r<   r#   rI   needlerC   rA   r%   rowownerowner_starts
             r   find_dword_refsr      s    [[12F!#D
((6
C
)$Xs3sHc2C"9c#g,.?@E"'-$Sy9I5JK"-C%'_C!" .{ ;CKKhhvsQw' ) Kr   c                X   g }|D ]!  }|j                  d      dk7  rt        |d         }|t        |d         z   }t        |t        ||dz
              D ]  }| |   dk7  rt	        ||      }|t        j                  d| |dz         d	   }	|dz   |	z   t        k7  rHt        ||      }
|
d nt        |
d
         }|j                  |t        |      |t        |      t        |      | t        ||dz
        t        ||dz          j                  d      t        |      d        $ |S )Nr*   r0   r   r    rT   rR   rS   r
   r   r3         rp   )callVa	callVaHexr   r   r   rx   r   )r+   r"   rV   r}   r   rW   rX   r   rK   r7   r   rO   rU   r~   classify_direct_call)r<   r#   rI   rC   r%   r&   r'   offr[   r\   r   r   s               r   find_direct_callsr      sK   !#D ;;v')GEN#c'*-..E37 34 	C3x4"8S1G$$T3a8;C{S $66"9g6E"'-$Sy9I5JKKK%!#G$/')+"0"="%c%r&:ScBh=O"P"T"TUX"Y&:7&C
	6 Kr   c                4    | dk(  ry| dk(  ry| dk(  ry| dk(  ryy	)
Ni#@ znested-runner-wrapper-self-calliX@ z/opcode-0x2a-linked-object-script-fanout-restoreiX@ z2opcode-0x2a-linked-object-script-fanout-persistenti0C z"active-object-delayed-script-routezunclassified-direct-callr   )r[   s    r   r   r      s1    *0*@*C*3%r   c                    t         j                         } t        |       }t        | |      }t	        | ||      }t        | ||      }t        d |D              }t        d |D              }t        d |D              }t        d |D              }|D 	cg c]  }	|	d   dk(  s|	 }
}	|
D 	cg c]  }	|	d   t        t              k(  s|	 }}	|D 	cg c]  }	|	d   dk(  s|	 }}	d	d
di dt        t              dt        t              dt        |      dt        |
      dt        |      dt        |      dt        |      dt        |      dt        |      dt        |      dt        |      d|j                  dd      d|j                  dd      dddddd d!d"||||
g d#g d$d%
}|S c c}	w c c}	w c c}	w )&Nc              3  &   K   | ]	  }|d      yw)rs   Nr   r1   r   s     r   r2   zbuild_report.<locals>.<genexpr>  s     Cc)nC   c              3  8   K   | ]  }|d    dk(  s|d     yw)rs   rj   rt   Nr   r   s     r   r2   zbuild_report.<locals>.<genexpr>  s0       !J#sS\~  bI  PI_!5  !Js   
c              3  &   K   | ]	  }|d      yw)r   Nr   r   s     r   r2   zbuild_report.<locals>.<genexpr>	  s     C3|,Cr   c              3  &   K   | ]	  }|d      yw)r   Nr   r   s     r   r2   zbuild_report.<locals>.<genexpr>
  s      O3%5!6 Or   rs   rj   rw   ry   r
   z)hwanse-display-vm-root-ref-context-reviewz1tools/build_display_vm_root_ref_context_review.pydisplayVmRootVaHexobjectAllocatorVaHexdwordRefCountobjectCreateRefCount#allocatorBackedObjectCreateRefCountfieldCallbackStoreCountdirectCallCountrefKindCountsobjectKindArgCountsownerClassCountsdirectCallClassCountsbattleEffectOwnerRefCountrM   r   descriptorOwnerRefCountrN   normalFieldHudOpenerPromotedFsceneRouteProducerPromotedr   zQgeneric display/object VM root references classified; no opener producer promoteddecisiona  Immediate references to 0x00402321 are overwhelmingly generic object creation sites that install the runner through allocator 0x00435b5b.  The only non-push reference stores the same runner into an object callback field.  These references prove display/object VM reuse across helper, descriptor, menu/status, and active-object domains; they do not prove the normal-field ESC/X opener or a scene/map route producer.)zg82/83 immediate dword references are allocator-backed object creation sites, not stream/root producers.z\67 allocator-backed refs use object kind 2 and cluster in battle/effect/helper spawner code.zdescriptor/materializer refs create active/display child objects, but still do not identify who schedules the normal-field HUD wrapper.zrthe sole store reference writes 0x00402321 into [eax+0x10], a callback/root field, not object+0x40 stream content.zdirect calls to 0x00402321 remain the known nested runner, opcode 0x2a fanout, and active-object delayed script route; no new opener call appears here.)zUTreat 0x00402321 as a reusable callback/runner, not as a unique HUD opener signature.zFor ESC/X opener proof, trace which producer attaches the already-grounded top-menu wrapper stream, not every object that installs the generic runner.zFor scene route proof, require an upstream gameplay state/root writer that selects a stream, not allocator references to the generic runner.)
versionkindsourcesummarydirectCallRowsdwordRefRowsfieldCallbackStoreRowsobjectCreateRowsnegativeEvidencenextFrontier)EXE
read_bytesr   rG   r   r   r   r   r|   r   r;   dictr+   )r<   r#   rI   
dword_refsdirect_callsref_kind_countsobject_kind_countsowner_countsdirect_call_countsr   object_create_rowsallocator_rowsfield_store_rowsreports                 r   build_reportr      s^   
..
CS!HX.I h	:J$S(I>LC
CCO   !J  !J  JC
CCL  O, OO)3q#s9~Ip7p#qq%7oc3?R;SWYZmWn;ncoNo'1eS^Gd5dee ;E
 "%7"8
"B':$;
 S_
 #C(:$;	

 23~3F
 &s+;'<
 s<0
 T/2
 "4(:#;
 \ 2
 $T*<%=
 ()9)9:fhi)j
 &|'7'78_ab'c
 +E
 )%
  q!
" O%
2 '""2.

Q-F\ Me roes$   F4 F4*F9F9F>F>x   )rY   c                   dj                  d | d | D              }t        |       |kD  r|dt        |       |z
   dz  }|xs dS )Nr   c              3  `  K   | ]%  }d t        |j                  d      xs |j                  d             dt        |j                  d             dt        |j                  d             dt        |j                  d      xs |j                  d	             dt        |j                  d
d             dt        |j                  dd             dt        |j                  dd             dt        |j                  dd             dt        |j                  d             d ( yw)z<tr><td><code>rr   r   z</code></td><td><code>r   z</code><br>r   z	</td><td>rs   r   rt   r   z<br>ru   z</td><td><code>rv   z</code><br><code>rw   rx   z</code></td></tr>N)r   r+   r   s     r   r2   zrender_table.<locals>.<genexpr>B  s%     
 	swwz*Bcggk.BCD Esww0123;qAV?W>X Y#@sww/?'@AB C"-./tAcgg>PRT6U4V3W Xsww0"5677H377SfhjKkIlHm nsww|,-. /	
s   D,D.z<tr><td colspan='6'>... z more rows in JSON</td></tr>z"<tr><td colspan='6'>none</td></tr>)joinr;   )rC   rY   bodys      r   render_tabler   A  s^    77 
 <
 
D 4y5*3t9u+<*==YZZ777r   c                j   | d   }t        j                  | d      }dj                  d |j                         D              }dj                  d | d   D              }dj                  d | d	   D              }d
t	        |d          d| d| d| dt        | d          dt        | d          d| dS )Nr   F)ensure_asciir   c              3  b   K   | ]'  \  }}|d k7  rdt        |       dt        |       d ) yw)r   z<div class='card'><b>z
</b><span>z</span></div>Nr   )r1   keyr   s      r   r2   zrender_html.<locals>.<genexpr>U  s;      C*  #xz!E(=Is   -/c              3  :   K   | ]  }d t        |       d  ywz<li>z</li>Nr   r1   items     r   r2   zrender_html.<locals>.<genexpr>Z  s     U$$qwiu-U   r   c              3  :   K   | ]  }d t        |       d  ywr   r   r   s     r   r2   zrender_html.<locals>.<genexpr>[  s     PagYe,Pr   r   aA  <!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Display VM Root Ref Context Review</title>
<style>
  body { margin:0; font-family:system-ui,-apple-system,Segoe UI,sans-serif; background:#101318; color:#edf1f7; }
  main { max-width:1360px; margin:0 auto; padding:24px; }
  h1 { margin:0 0 8px; font-size:28px; }
  h2 { margin-top:28px; font-size:18px; }
  p, li { line-height:1.45; }
  code { font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; }
  .cards { display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr)); gap:10px; margin:18px 0; }
  .card { background:#171d26; border:1px solid #293241; border-radius:8px; padding:10px 12px; }
  .card b { display:block; color:#9cb3d1; font-size:12px; }
  .card span { display:block; margin-top:4px; overflow-wrap:anywhere; }
  table { width:100%; border-collapse:collapse; background:#151a22; border:1px solid #293241; table-layout:fixed; }
  th, td { border-bottom:1px solid #263040; padding:7px 8px; text-align:left; vertical-align:top; font-size:12px; }
  th { background:#1d2633; color:#dbe7f7; }
  td:nth-child(1) { width:105px; }
  td:nth-child(2) { width:220px; }
  td:nth-child(3) { width:230px; }
  td:nth-child(4) { width:190px; }
  td:nth-child(5) { width:130px; }
  td:nth-child(6) { overflow-wrap:anywhere; }
  pre { white-space:pre-wrap; background:#080b10; color:#edf1f7; padding:14px; border-radius:8px; max-height:360px; overflow:auto; }
</style>
</head>
<body>
<main>
  <h1>Display VM Root Ref Context Review</h1>
  <p>r   z</p>
  <div class="cards">z:</div>
  <section>
    <h2>Negative Evidence</h2>
    <ul>zB</ul>
  </section>
  <section>
    <h2>Next Frontier</h2>
    <ul>z</ul>
  </section>
  <section>
    <h2>Dword References</h2>
    <table><thead><tr><th>ref</th><th>owner</th><th>kind</th><th>object kind</th><th>allocator</th><th>bytes</th></tr></thead><tbody>r   z</tbody></table>
  </section>
  <section>
    <h2>Direct Calls</h2>
    <table><thead><tr><th>call</th><th>owner</th><th>kind</th><th>object kind</th><th>allocator</th><th>bytes</th></tr></thead><tbody>r   z</tbody></table>
  </section>
  <section>
    <h2>Raw JSON</h2>
    <pre id="json"></pre>
  </section>
</main>
<script>
window.HWANSE_DISPLAY_VM_ROOT_REF_CONTEXT_REVIEW = z;
document.getElementById('json').textContent = JSON.stringify(window.HWANSE_DISPLAY_VM_ROOT_REF_CONTEXT_REVIEW, null, 2);
</script>
</body>
</html>
)jsondumpsr   itemsr   r   )r   r   payloadcards	negativesfrontiers         r   render_htmlr   R  s*   YGjje4GGG !--/ E
 U&AS:TUUIwwP9OPPH @ 
 W 	 
 	 

 F GS  TZ  [i  Tj  Gk  Fl lG HT  U[  \l  Um  Hn  Go o4 5<9 =q= =r   c                 2   t               } t        j                  d       t        j                  d       t        dz  j	                  t        j                  | dd      dz   d	       t        d
z  j	                  t        |       d	       t        d       y)NT)exist_okz'display_vm_root_ref_context_review.jsonFrb   )r   indent
zutf-8)encodingz'display_vm_root_ref_context_review.htmlz%display_vm_root_ref_context_review okr   )	r   OUTmkdirWEB
write_textr   r   r   print)r   s    r   mainr     s    ^FIItIIItI44@@

6a84? A  	44@@VAT_f@g	
12r   __main__)r   
int | Nonereturnr   )r   r   r   r   )r#   list[dict[str, Any]]r$   r"   r   dict[str, Any] | None)r#   r   r,   r"   r   r   )r<   bytesr#   r   r   r   )rI   r   r,   r"   r   r   )rE   r   r   r   )(   )
r<   r   r#   r   r$   r"   rY   r"   r   ztuple[int, int] | None)r<   r   r$   r"   r   r   )r<   r   r#   r   r$   r"   r   dict[str, Any])r<   r   r#   r   rI   r   r   r   )r[   r"   r   r   )r   r   )rC   r   rY   r"   r   r   )r   r   r   r   )r   r"   ),__doc__
__future__r   r   r   rW   collectionsr   pathlibr   typingr   probe_exe_scene_tablesr   r   r	   __file__resolveparentsROOTr   r   r   r   r|   r   r   r(   r-   rG   rK   rO   r]   rh   r   r   r   r   r   r   r   r   __name__
SystemExitr   r   r   <module>r     s    #       L L H~''*
]
Ul
Ul   6HC, 0
;|$@	&>B >A 8"GT
 z
TV
 r   