
    UHjo6                       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  ee      j                         j                  d   Zedz  Zej%                  d      ej%                  d	      ej%                  d
      ej%                  d      ej%                  d      ej%                  d      ej%                  d      ej%                  d      ej%                  d      ej%                  d      ej%                  d      ej%                  d      dZddZddZddZddZddZddZefd dZd!dZedk(  r e        yy)"z4Document the original EXE save-loader selector path.    )annotationsN)Path)read_sectionsva_to_offset   out33c0
a0da7645008b0485352d440033c98a0ddb7645008b0488
a330de5900
a130de5900894140)i4B i4B i4B i4B i4B i4B i4B i@ i@ i@ i7@ iJ@ c                N    t        ||      }|t        d|dd      | |||z    S )N0x08xz is not in a loaded section)r   
ValueError)exesectionsvasizeoffsets        8/home/exedev/hwanse/tools/summarize_save_loader_trace.pybytes_atr   "   s;    (B'F~2bX%@ABBv&&    c           
     *   g }t         j                         D ]y  \  }}t        | ||t        |            }||k7  r1t	        d|dd|j                          d|j                                |j                  d|d|j                  d      d       { |S )Nr   r   z: expected z, got  )vaHexbytes)EXPECTED_BYTESitemsr   lenr   hexappend)r   r   rowsr   expectedactuals         r   verify_bytesr*   )   s    D&,,. HH#xS];Xr"SX\\^4DF6::<.YZZ2c(mfjjoFG	H
 Kr   c           	     L    t        j                  dt        | ||d            d   S )Nz<I   r   )structunpackr   )r   r   r   s      r   dword_atr/   3   s#    ==xXr1=>qAAr   c                   t        |       }t        | |      }t        | |d      }t        | ||      }t        | ||dz         }t        | ||dz         }dddddd	d
ddddd	dddddd	gdddddddddddddddd d!d"d#dgdd$d%d&d'd(d)d&dd*d+d&d,d-d.d&d/d0d1d&gd2d3d4d5d6d7d8d9d:d;dd<d=d>d?d9d@dAdBdCdDdEdFd9gdGd4d3d2d5dHdd;d:d<dHdBdAd@dCdHgdI|dJdKdLdM|dNdM|dNdM|dNdM|dNdOdPdQS )RNi=-D       
0x00423404
0x004576d80x00000x0072zJfirst save block, includes scene selector bytes and tile/camera candidates)	callVaHextargetVaHexsaveOffsetHexsizeHexdescription
0x00423430
0x004577500x0288zsecond save block
0x0042345c
0x0059db600x02fa0x0200zthird save block0x0002
0x004576dazscene selector group
0x004234a3)r9   runtimeVaHexfieldloaderVaHex0x0003
0x004576dbzscene selector slot
0x004234b10x0004
0x004576dcztile/camera X candidate
0x00424a930x0006
0x004576deztile/camera Y candidate
0x00424ab8zAL = byte [0x004576da]z0load save selector group from save offset 0x0002)r    	operationmeaning
0x004234a8z!EAX = dword [0x00442d35 + AL * 4]z#select row pointer from group tablezCL = byte [0x004576db]z/load save selector slot from save offset 0x0003
0x004234b7zEAX = dword [EAX + ECX * 4]z/select scene/progress pointer from row and slot
0x004234bazdword [0x0059de30] = EAXz;store selected scene/progress pointer for later runtime use
0x0040ad9b
0x0044073c   selectIndexedPointerz1stream byte + table pointer -> dword [0x0059de30]zVruntime script opcode selects an indexed pointer into the same selected-pointer global
0x0040adb8)r    handlerTableVaHexhandlerIndexkindrR   rS   evidenceVaHex
0x0040adc9
0x00440740jumpToSelectedPointerzYif dword [0x0059de30] != 0, save current stream and set context+0x40 = dword [0x0059de30]z?selected pointer becomes the active script/event stream pointer
0x0040adfe
0x0040ae0e
0x00440744	   setSelectedPointerzTmode 0 stores current stream pointer; mode 1 stores dword [stream+4] into 0x0059de30z9runtime script opcodes update the selected pointer global
0x0040ae37
0x00440720)index
entryVaHexhandlerVaHexr^   )
startVaHexselectedPointerHandlers   r   
0x00442d35r   r   z(map1_01a -> map2_02d via leaf 0x00542ac0)groupslotgroupTableVaHexrowPointerVaHexselectedPointerHexsecondLevelPointerHexleafPointerHexknownFrontier)saveReadBlocksselectorFieldsselectorTraceselectedPointerRuntimeUsesscriptHandlerTableselectorInstructionBytesfrontierExample)r   r*   r/   )r   r   selector_instruction_bytesselector_tableselected_pointersecond_level_pointerselector_leafs          r   build_summaryr   7   sG   S!H!-c8!<c8-?@NX~>#C3Ce3KLS(,@5,HIM *+!)#k *+!)#2 *+!)#1
2 "* ,/+	 "* ,.+	 "* ,2+	 "* ,2+	'
8 &5M &@@ &5L &:L &7X+
: &%1 !.Ps!- &%1 !/x\!- &%1 !,sV!-''
< ' ".$02	 ".$03	 ".$00	(
. %?+!#N3#78$&'7&<"=')*>s)C%D "="56G	
EL Lr   c                .   g d}| d   D ]2  }|j                  d|d    d|d    d|d    d|d    d|d	    d
       4 |j                  g d       | d   D ],  }|j                  d|d    d|d    d|d    d|d    d
	       . |j                  g d       | d   D ]&  }|j                  d|d    d|d    d|d    d
       ( | d   }|j                  dddd| d   d    ddddg       | d    D ]>  }|j                  d|d!    d|d"    d|d    d|d#    d|d    d|d    d|d$    d
       @ |j                  dd%dd&|d'    d(|d)    d*d+|d,    d*d-|d.    d*d/|d0    d*d1|d2    d*d3|d4    d*d5|d6    dg       d7j                  |      S )8N)z# Save Loader Trace z>Original EXE save-load evidence for the scene selector fields.r   z## Save Read Blocksr   z4| call | target | save offset | size | description |z| --- | --- | --- | --- | --- |ry   z| r7   z | r8   r9   r:   r;   z |)r   z## Selector Fieldsr   z2| save offset | runtime VA | field | evidence VA |z| --- | --- | --- | --- |rz   rF   rG   rH   )r   z## Selector Tracer   z| VA | operation | meaning |z| --- | --- | --- |r{   r    z | `rR   z` | rS   r   r   z### Runtime Uses Of Selected PointerzHandler table starts at `r}   rm   z`.zL| index | table entry | handler VA | kind | operation | meaning | evidence |z,| ---: | --- | --- | --- | --- | --- | --- |r|   r]   r\   r^   r_   z## Frontier Examplez- group/slot: `rq   :rr   `z- group table: `rs   z- row pointer: `rt   z- selected pointer: `ru   z- second-level pointer: `rv   z- sample leaf pointer: `rw   z- known frontier: rx   
)r&   extendjoin)summarylinesrowexamples       r   markdownr      s   	E '( 
[!"#c-&8%9S=Q<RRUVYZcVdUeehilmzi{h||~	

 
LL   '( tr#o./s3~3F2Gs3w<.X[\_`m\n[ooqrst	LL   ' Vr#g,tC,<+=T#i.AQQSTUV'(G	LL
-

#G,@$A,$O#PPRS
V6  34 
^$%S-@)A(B#c'l^SVWZ[aWbVc dK !c)n%5S_9M8NbR	


 
LL


''*+1WV_,=Q?
7#456a8
7#456a8
(< =>a@
#G,C$D#EQG
"7+;#<"=Q?
W_567
  99Ur   c                   dId}| d   D cg c]  }|d   |d   |d   |d   |d   g }}| d   D cg c]  }|d   |d	   |d
   |d   g }}| d   D cg c]  }|d   |d   |d   g }}| d   D cg c])  }t        |d         |d   |d   |d   |d   |d   |d   g+ }}| d   }dj                  g dddddddddd d!d"d#d$d%d&d'd( |g d)|      d* |g d+|      d, |g d-|      d.d/| d0   d1    d2 |g d3|      d4d5|d6    d7|d8    d9|d:    d;|d<    d=|d>    d?|d@    dA|dB    d2dCt        j                  |dD          dEdFdGdH      S c c}w c c}w c c}w c c}w )JNc                t    dj                  d | D              }dj                  d |D              }d| d| dS )Nr   c              3  N   K   | ]  }d t        j                  |       d  yw)z<th>z</th>Nhtmlescape).0headers     r   	<genexpr>z+html_page.<locals>.table.<locals>.<genexpr>  s#     OVdkk&12%8O   #%r   c              3  X   K   | ]"  }d dj                  d |D              z   dz    $ yw)z<tr>r   c              3  N   K   | ]  }d t        j                  |       d  yw)z<td>z</td>Nr   )r   values     r   r   z5html_page.<locals>.table.<locals>.<genexpr>.<genexpr>  s#     O%tDKK$6#7u=Or   z</tr>Nr   )r   r   s     r   r   z+html_page.<locals>.table.<locals>.<genexpr>  s2      
 RWWO3OOORYY
s   (*z<table><thead><tr>z</tr></thead><tbody>z</tbody></table>r   )headersr'   headbodys       r   tablezhtml_page.<locals>.table  sJ    wwOwOOyy 

 
 $D6)=dVCSTTr   ry   r7   r8   r9   r:   r;   rz   rF   rG   rH   r{   r    rR   rS   r|   r]   r\   r^   r_   r   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 Loader Trace</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: 12px 0 24px; }zM    th, td { border: 1px solid #333; padding: 6px 8px; vertical-align: top; }z    th { background: #1d1d1d; }z    code { color: #d6e8ff; }z
  </style>z</head>z<body>z  <h1>Save Loader Trace</h1>zG  <p>Original EXE save-load evidence for the scene selector fields.</p>z  <h2>Save Read Blocks</h2>)calltargetsave offsetr   r;   z  <h2>Selector Fields</h2>)r   z
runtime VArG   zevidence VAz  <h2>Selector Trace</h2>)VArR   rS   z+  <h2>Runtime Uses Of Selected Pointer</h2>z#  <p>Handler table starts at <code>r}   rm   z</code>.</p>)rj   ztable entryz
handler VAr^   rR   rS   evidencez  <h2>Frontier Example</h2>z  <p><code>rq   r   rr   z</code> resolves through <code>rs   z</code> to <code>rt   z </code>, selected pointer <code>ru   z$</code>, second-level pointer <code>rv   z </code>, then sample leaf <code>rw   z  <p>rx   z</p>z</body>z</html>r   )r   z	list[str]r'   zlist[list[str]]returnstr)r   r   r   r   )r   r   r   	read_rows
field_rows
trace_rowsruntime_rowsr   s           r   	html_pager     s{   U +, 
[	3}-s?/CS^UXYfUghI  +, 
_	s>2CL#mBTUJ  ?+ 
Ws;'Y8J  78  N#$#$LK	N 	
L  '(G99 ### 	# 	#	#
 	Q# 	-# 	# 	i# 	U# 	X# 	*# 	'# 	# 	# 	#  	'!#" 	R##$ 	&%#& 	F	R'#( 	%)#* 	CZP+#, 	$-#. 	,j9/#0 	61#2 .g6J.KL.Y-ZZfg3#4 	`bno5#6 	&7#8 gg&'q(99XY`arYsXt u-.//OPWXlPmOn o&&-.E&F%GGgho  qA  iB  hC  CO	P9#> GO456d;?#@ 	A#B 	C#D 	E# # #3s   E+E0E52.E:c                    |j                  dd       |dz  j                  t        j                  | dd      dz   d	       y )
NT)parentsexist_oksave_loader_trace.jsonFro   )ensure_asciiindentr   zutf-8)encoding)mkdir
write_textjsondumps)r   out_dirs     r   write_outputsr   U  sC    MM$M.''33

7q9D@ 4 r   c                 v   t        j                  t              } | j                  dt        t
        dz         | j                  dt        t               | j                         }t        |j                  j                               }t        ||j                         t        d|j                  dz          y )N)r;   z--exezHwanse2.exe)typedefaultz	--out-dirzwrote save loader trace -> r   )argparseArgumentParser__doc__add_argumentr   ROOTOUT
parse_argsr   r   
read_bytesr   r   print)parserargsr   s      r   mainr   ]  s    $$9F
dD=4HI
$<DDHH//12G'4<<(	'7O(O'P
QRr   __main__)
r   r!   r   
list[dict]r   intr   r   r   r!   )r   r!   r   r   r   r   )r   r!   r   r   r   r   r   r   )r   r!   r   dict)r   r   r   r   )r   r   r   r   r   None)r   r   )r   
__future__r   r   r   r   r-   pathlibr   probe_exe_scene_tablesr   r   __file__resolver   r   r   r!   fromhexr"   r   r*   r/   r   r   r   r   r   __name__ r   r   <module>r      s'   : "      > H~''*
Ul f%l+./f%n-h'l+l+l+h'l+l+ 'BSl=@EP 25 S zF r   