
    UHj+                    8   d Z ddlmZ ddlZddlZddlZddlZddlmZ ddl	m
Z
mZmZ ddlmZmZ ddlmZmZmZ  ee      j)                         j*                  d   Zed	z  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efddZ ddZ!e"dk(  r e!        yy)zITrace save-selector leaf streams using script handler advance candidates.    )annotationsN)Path)find_cns_stringsread_sectionsva_to_offset)DEFAULT_HANDLER_VAHANDLER_TABLE_VA)analyze_stream_effectdword_atsection_name_for_va   outc                F    t        ||      }||t        |       k\  ry | |   S )N)r   lenexesectionsvaoffsets       B/home/exedev/hwanse/tools/summarize_save_selector_stream_traces.pybyte_atr      s+    (B'F~3s8+v;    c                v    t        ||      }||dz   t        |       kD  ry t        j                  d| |      d   S )N   z<Ir   )r   r   structunpack_fromr   s       r   u32_atr      s?    (B'F~!c#h.dC033r   c                   t         |dz  z   }t        | ||      }|t        ||      nd }i }|t        k(  r
ddigg g d}n||dk(  rt	        | ||      }t        |j                  dg       D ch c]%  }|j                  d      s|j                  d      ' c}      }|d|dd|d||d|dnd ||t        k(  ||j                  d	      d
u t        |j                  d            |j                  d      xs g dS c c}w )Nr   bytes)fixedAdvancesstreamReadsstreamStoresz.textr    0x02x08xcanJumpToDwordAtPlus4Tr"   r!   )opcode	opcodeHex
entryVaHex	handlerVahandlerVaHexhandlerSectionisDefaultHandlerr    r&   writesStreamr!   )r	   r   r   r   r
   sortedgetbool)	r   r   r'   entry_va
handler_vasectioneffectitemadvancess	            r   handler_entryr8   "   s-   &1*,H#x2J;E;Q!(J7W[GF''%,aL>"VXY		Gw$6&sHjAVZZQS5TjTX\X`X`ahXitxx(jkH&&8C.)1;1G"Z,-T!&*<<!!',C!D!LVZZ78zz-06B  ks   ,C>C>c                *    | dk(  r	 y| dk(  ry| dk(  ryy )Ni@ zif table[(context+0xa8)[stream+2]] == 1 then fall through +8; table is 0x59e370 when stream+1 is 0, otherwise 0x59e360; else jump to dword [stream+4]im@ zVjump to dword [stream+4] when encounter-state flags are set; otherwise fall through +8i&@ z@condition helper can jump to dword [stream+4] or fall through +8 )r3   s    r   branch_noter;   ;   s/    Z,	

 ZgZQr   c                   g }t               }|}t        |      D ]a  }||v r|j                  |d|ddd        |S |j                  |       t	        | ||      }	t        | ||      }
|	|
|j                  |d|ddd        |S t        | ||	      }||d|d|
d|
dd|}|
|v r	||
   |d<   nt        ||
      d|d	<   d|
d|d
<   |d   rJt        | ||dz         }|d|dnd |d<   d|dz   d|d<   t        |j                  d            }|r||d<   |j                  |       |d   }t        |      dk(  r|d   s
||d   z  }7t        |      dk(  r|d   rd|d<    |S |sd|d<    |S d|d<    |S  |S )Nr#   r%   loop)stepvaHex
stopReason
unreadable)r>   r   r?   valuevalueHexcnsTpointer
pointerHexr&   r   branchTargetHex   fallthroughVaHexr*   
branchNoter    r   r   zbranch-or-fallthroughr@   zno-fixed-advancezmultiple-advances)setrangeappendaddr   r   r8   r   r;   r0   r   )r   r   strings	stream_va	max_stepsrowsseenr   r>   r'   rB   handlerrowtargetnoter7   s                   r   trace_streamrX   I   s7   D5D	Bi  +:KK"RHVTUR KQ 	h+sHb)>U]KK"RH\Z[F KE  Xv6"S]U3K(
 
 G CJ(E*6!C	N"$U3K 0C*+C262F:@:Lr&%6RVC!"(*26#,&7C"#w{{;78D$(L!C?+x=Ag.E&F(1+Bx=A'*A"B 7C K  2C K 0LKY+X Kr   c                >   t        |       }t        | |      }g }|D ]~  }dD ]w  \  }}|j                  |      }	|	st        |	d      }
|j	                  |j                  d      |j                  d      |j                  d      ||	t        | |||
|      d       y  |S )N))leafleafPointerHex)nestednestedPointerHex   sourcerV   r[   )r_   rV   r[   
streamKindstreamVaHextrace)r   r   r0   intrM   rX   )r   	leaf_rowsrQ   r   rO   rR   rZ   kindkey
stream_hexrP   s              r   
build_rowsrh   |   s    S!HsH-GD U 	ID##JJ+IKK((8,((8,"&((+;"<")%c8WiS 	 Kr   c                h   ddddddt        |        ddg}| D ]  }|j                  d|d    d	|d
    d|d    ddddg       |d   D ]A  }dj                  d |j                  dg       D              xs d}|dk7  rd| ndg}|j                  d      r|j	                  d       |j                  d      r|j	                  d       |j	                  d|d    d|d    d|j                  dd       d|j                  d d       d|j                  d!d       d"d#j                  |       d|j                  d$      xs d d|j                  d%      xs d d"|j                  d&      xs d d'|j                  d(      xs d d)       D |j	                  d        d*j                  |      S )+Nz# Save Selector Stream Traces zwLinear bytecode traces for save-selector leaf streams. These traces follow only handlers with one fixed stream advance.zrRows with branch targets, missing advances, or multiple possible advances are stopped rather than guessed through.zTraced streams: .z## ra    (r`   , leaf r[   )z]| step | va | value | opcode | handler | effect | branch target | fallthrough | stop | note |z>| ---: | --- | --- | --- | --- | --- | --- | --- | --- | --- |rb   /c              3  &   K   | ]	  }d |   yw+Nr:   .0rB   s     r   	<genexpr>zmarkdown.<locals>.<genexpr>        W!E7W   r    -advance r.   writes streamr&   branchz| r>   z | `r?   z` | `rC   r(   r+   z` | ; rG   rI   r@   z | rJ   z |
)r   extendjoinr0   rM   )rR   linesrU   r6   r7   effect_bitss         r   markdownr      s   '
 	B|

3t9+Q'
E  #m$%RL(9':'#FVBWAXXYZkL	
 	 L 	DxxW/SU9VWW^[^H4<OXhZ0MKxx'""?3xx/0""8,LLT&\N$tG}oU488JPS;T:U VHH[#./uTXXnc5R4SSW99[)*$txx8I/J/Qc.R SHH/07C8TXXl=S=ZWZ<[[^88L)0S1	5	 	R+, 99Ur   c                r   g }| D ]l  }g }|d   D ]  }dj                  d |j                  dg       D              xs d}|dk7  rd| ndg}|j                  d      r|j                  d       |j                  d	      r|j                  d
       |j                  d|d    dt        j                  |d          dt        j                  |j                  dd             dt        j                  |j                  dd             dt        j                  |j                  d      xs d       dt        j                  dj                  |             dt        j                  |j                  d      xs d       dt        j                  |j                  d      xs d       dt        j                  |j                  d      xs d       dt        j                  |j                  d      xs d       d        |j                  dt        j                  |d          dt        j                  |d          dt        j                  |d           d!d"j                  |       d#	       o d$j                  d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7t        |        d8d$j                  |      d9d:d"g      S );Nrb   ro   c              3  &   K   | ]	  }d |   ywrq   r:   rs   s     r   ru   zhtml_page.<locals>.<genexpr>   rv   rw   r    rx   ry   r.   rz   r&   r{   z<tr><td>r>   z</td><td><code>r?   z</code></td><td><code>rC   r(   r+   z</code></td><td>r|   rG   rI   r@   z	</td><td>rJ   z
</td></tr>z<h2>ra   rl   r`   rm   r[   z)</h2><table><thead><tr><th>step</th><th>va</th><th>value</th><th>opcode</th><th>handler</th><th>effect</th><th>branch target</th><th>fallthrough</th><th>stop</th><th>note</th></tr></thead><tbody>rj   z</tbody></table>r}   z<!doctype html>z<html lang="en">z<head>z  <meta charset="utf-8">zF  <meta name="viewport" content="width=device-width, initial-scale=1">z,  <title>Save Selector Stream Traces</title>z	  <style>z^    body { margin: 24px; background: #101010; color: #eee; font: 14px system-ui, sans-serif; }zJ    table { border-collapse: collapse; width: 100%; margin-bottom: 24px; }zM    th, td { border: 1px solid #333; padding: 6px 8px; vertical-align: top; }z9    th { background: #1d1d1d; position: sticky; top: 0; }z    code { color: #f5d76e; }z
  </style>z</head>z<body>z&  <h1>Save Selector Stream Traces</h1>z  <p>Linear bytecode traces for save-selector leaf streams. These traces follow only handlers with one fixed stream advance.</p>z{  <p>Rows with branch targets, missing advances, or multiple possible advances are stopped rather than guessed through.</p>z  <p>Traced streams: z.</p>z</body>z</html>)r   r0   rM   htmlescaper   )rR   r   rU   bodyr6   r7   r5   s          r   	html_pager      s   H 
L 	DxxW/SU9VWW^[^H/73
+CHFxx'o.xx/0h'KKF|n %![[g78 9![[*c)BCD E![[+s)CDE F![[.)A)HSIJ K{{499V#456 7![[2C)D)KLM N![[2D)E)LMN O{{488L#9#@SAB C{{488L#9#@SAB C	* 	4;;s=1232dkk#lBS6T5UU\]a]h]hilm}i~]  ]A Aggdm_$46	
/
8 99"P6hTWC&0 	K 	F
D	{%0		(
/  r   c                    |j                  dd       |dz  j                  t        j                  | dd      dz   d	       y )
NT)parentsexist_ok save_selector_stream_traces.jsonF   )ensure_asciiindentr}   utf-8encoding)mkdir
write_textjsondumps)rR   out_dirs     r   write_outputsr      sC    MM$M.11==

4eA6= > r   c                 n   t        j                  t              } | j                  dt        t
        dz         | j                  dt        t        dz         | j                  dt        t               | j                  dt        d	       | j                         }t        |j                  j                         t        j                  |j                  j                  d
            |j                         }t#        ||j$                         t'        dt)        |       d|j$                  dz          y )N)descriptionz--exezHwanse2.exe)typedefaultz--leaf-streamszsave_selector_leaf_streams.jsonz	--out-dirz--max-steps    r   r   zwrote z  save selector stream traces -> r   )argparseArgumentParser__doc__add_argumentr   ROOTOUTrc   
parse_argsrh   r   
read_bytesr   loadsleaf_streams	read_textrQ   r   r   printr   )parserargsrR   s      r   mainr      s    $$9F
dD=4HI
(tSCd=de
$<
C<D

4$$...@AD
 $%	F3t9+=dllMo>o=p
qrr   __main__)r   r   r   
list[dict]r   rc   return
int | None)r   r   r   r   r'   rc   r   dict)r3   r   r   z
str | None)r   r   r   r   rO   zdict[int, str]rP   rc   rQ   rc   r   r   )r   )r   r   rd   r   rQ   rc   r   r   )rR   r   r   str)rR   r   r   r   r   None)r   r   )#r   
__future__r   r   r   r   r   pathlibr   probe_exe_scene_tablesr   r   r   summarize_script_handler_tabler   r	   r
   r   r   __file__resolver   r   r   r   r   r8   r;   rX   rh   r   r   r   r   __name__r:   r   r   <module>r      s    O "      P P O _ _ H~''*
Ul420f* F6r 58 s  zF r   