
    UHj(                       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Zddlm	Z	 ddl
mZ ej                  j                  d e e	e      j!                         j"                               ddlmZmZ  e	e      j!                         j*                  d   Zedz  Zd	Zd
ZdZd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Z%ddZ&e'dk(  r e&        yy) z5Document the save-selector opcode 0x24 handler modes.    )annotationsN)Path)Any)read_sectionsva_to_offset   outi@ i@ is@ i@ iL@ id@ c                p    | j                         s|S t        j                  | j                  d            S )Nutf-8encoding)existsjsonloads	read_text)pathfallbacks     E/home/exedev/hwanse/tools/summarize_save_selector_opcode24_handler.py	load_jsonr      s*    ;;=::dnngn677    c                    t        ||      }||dz   t        |       kD  rt        d|d      t        j                  d| |      d   S )N   unreadable VA 0x08xz<Ir   )r   len
ValueErrorstructunpack_fromexesectionsvaoffsets       r   read_u32r$   "   sQ    (B'F~!c#h.+Bs8455dC033r   c                b    t        ||      }||t        |       k\  rt        d|d      | |   S )Nr   r   )r   r   r   r   s       r   	read_byter&   )   s=    (B'F~3s8++Bs8455v;r   c           
        | D ]  }|j                  d      dk(  s|j                  d      dk(  s-|j                  d      xs i }t        |j                  d      xs dd      }|j                  d      |j                  d      |j                  d	      |j                  d      |d
z	  dz  d|d
z	  dz  d|dz	  dz  |dz	  dz  dc S  i S )Nsourcemap1_01atargetmap2_02dopcode24BoundaryopcodeValueHex0   opcodeVaHex      0x02x   )r(   r*   r0   r-   streamPlus1streamPlus1HexstreamPlus2streamPlus3)getint)
gate_pathsrowboundaryvalues       r   boundary_moder@   0   s     778
*swwx/@J/Nww128bH%56=#rBE''(+''(+'||M:"*,,/?"@ %
d2$&!t(;S&A"B %t3 %t3	 		 Ir   c                   t        |       }t        d      D cg c]  }t        | |t        |dz  z          }}t        d      D cg c]  }t	        | |t
        |z          }}g }t        |d      D ]N  \  }}||   }	|	dk(  rd}
n"|	dk(  rd	}
n|	d
k(  rd}
n|	dk(  rd}
n
|	dk(  rd}
nd}
|j                  ||d|	d|
d       P ddddddddddddg}t        |      }|j                  d      t        fd|D        i       }d}dt        ddt        ddt        dd d!d"d#d$d%|||dt
        ddt        d|d&|d'	S c c}w c c}w )(N   r   
   r   )starti@ zKwrite current object index 0x0059e33e to object+0x61 and set context+0x58=0i@ zlscan runtime object table 0x0059db3c and write the first available slot+3 to object+0x61; set context+0x58=0i
@ zset context+0x58=1i@ zset context+0x58=2in@ z0no object/context update before final +4 advancez unclassified object-state branchr3   r   )objectStateselectortargetVaHexmeaningr   
0x0040c55czCall 0x0043329f for the current runtime object, then branch on object+0x58/object+0x67. This can set context+0x58 to 0/1/2/3 or update object+0x61.)moderG   rH   
0x0040c673zHWrite byte(0x0059e348)+3 to current object+0x61, then advance stream +4.   
0x0040c688zFWrite byte(0x0059e347) to current object+0x61, then advance stream +4.r6   c              3  4   K   | ]  }|d    k(  s|  yw)rJ   N ).0r=   current_modes     r   	<genexpr>z build_summary.<locals>.<genexpr>q   s     USV9TSUs   a  The current map1_01a->map2_02d boundary uses opcode 0x24 mode 1. That mode updates the current runtime object's +0x61 field from global 0x0059e348 and then advances by +4; it does not by itself prove that the following pointer/table payload selects save-selector leaf 0x00542ae8. The next reverse-engineering step is to identify the producer/meaning of 0x0059e348 and the consumer of object+0x61/context+0x58.
0x0059e34d
0x0059e33e
0x0059db30
0x0059e348
0x0059e347)runtimeEnabledFlagcurrentObjectIndexruntimeObjectTablemode1SourceBytemode2SourceByte)selectorTableVaHextargetTableVaHexrows)	handlerVaHexmodeDispatchVaHexfinalAdvanceVaHexglobalscurrentBoundarycurrentModemodesobjectStateSwitch
conclusion)r   ranger$   OBJECT_STATE_TABLE_VAr&   OBJECT_STATE_SELECTOR_VA	enumerateappendr@   r:   next
HANDLER_VAMODE_DISPATCH_VAFINAL_ADVANCE_VA)r    r<   r!   indexobject_state_tableobject_state_selectorsobject_state_rowsobject_staterF   r*   rH   	mode_rowscurrentcurrent_mode_rowrh   rQ   s                  @r   build_summaryrz   B   s   S!HbghibjkY^(32G%RS)2STkkfklnfop]biX7ORW7WXpp"+,B!"L h#H-ZcGz! EGz!*Gz!*Gz!HG8G  ' s|,	"
 	, 'N		
 'a	
 '_	
I( J'G;;}-LUIUWYZ	L  Z,-!"23!78!"23!78".".".++
 #'$&'?&D"E"$%:3$? @%

 !' i lps   EEc                f   | j                  d      xs i }| j                  d      xs i }ddd| j                  d       ddd|j                  d	       d
|j                  d       dd|j                  d       dd|j                  d       dd|j                  d      xs d d| j                  d       dddg}| j                  d      xs i j                         D ]  \  }}|j                  d| d| d        |j                  g d       | j                  d      xs g D ]J  }|j                  d|j                  d       d|j                  d       d|j                  d       d        L |j                  g d!       | j                  d"      xs i j                  d#      xs g D ]\  }|j                  d|j                  d$       d%|j                  d&       d|j                  d       d|j                  d       d 	       ^ |j                  d       d'j	                  |      S )(Nrd   re   z## Save Selector Opcode 0x24 Handler z
Handler: `r`   z`.z- current boundary: `r0   z	` value `r-   `z- current mode byte: `r7   z- current mode target: `rG   z- current mode meaning: rH   -z- conclusion: rh   z
## Globalsrc   z- z: `)r|   z## Mode Dispatchr|   z| mode | target | meaning |z| ---: | --- | --- |rf   z| rJ   z | `z` | z |)r|   z!## Object State Switch For Mode 0r|   z3| object+0x67 state | selector | target | meaning |z| ---: | ---: | --- | --- |rg   r_   rE   z | rF   
)r:   itemsrm   extendjoin)summaryrx   rQ   linesnamer?   r=   s          r   markdownr      sM   kk+,2G;;}-3L-

W[[014

M :;9W[[QaEbDccde
 -=!> ?qA
"<#3#3M#B"C1E
"<#3#3I#>#E#"FG
\234

E  I.4";;= -er$s5'+,-	LL   {{7#)r cr#''&/*$sww}/E.Fd377S\K]J^^`abc	LL   017R<<VDJ 
'(CGGJ,?+@SWW]E[D\\`adahahiras`ttvw	

 
LL99Ur   c                   | j                  d      xs i }| j                  d      xs i }dj                  d | j                  d      xs g D              }dj                  d | j                  d      xs i j                  d      xs g D              }dj                  d	 | j                  d
      xs i j                         D              }dj                  ddddt        j                  t        | j                  d                   dddt        j                  t        |j                  d                   dt        j                  t        |j                  d                   ddt        j                  t        |j                  d                   ddt        j                  t        |j                  d                   ddt        j                  t        |j                  d      xs d             ddt        j                  t        | j                  d                    dd!d"|d!d#d$|d%d&d'|d%g      S )(Nrd   re   r   c              3     K   | ]u  }d |j                  d       dt        j                  t        |j                  d                   dt        j                  t        |j                  d                   d w yw)<tr><td>rJ   </td><td><code>rG   </code></td><td>rH   
</td></tr>Nr:   htmlescapestrrP   r=   s     r   rR   zhtml_page.<locals>.<genexpr>   sv       	wwv  [[SWW]%;!<=> ?{{3swwy1234 5	s   A;A=rf   c              3  "  K   | ]  }d |j                  d       d|j                  d       dt        j                  t        |j                  d                   dt        j                  t        |j                  d                   d	  y	w)
r   rE   z	</td><td>rF   r   rG   r   rH   r   Nr   r   s     r   rR   zhtml_page.<locals>.<genexpr>   s       	ww}%& 'wwz"# $[[SWW]%;!<=> ?{{3swwy1234 5		s   BBrg   r_   c           	   3     K   | ]?  \  }}d t        j                  |       dt        j                  t        |             d A yw)<li>z: <code></code></li>N)r   r   r   )rP   r   r?   s      r   rR   zhtml_page.<locals>.<genexpr>   sC      D% t{{4 !$++c%j*A)B,Os   AArc   zU<!doctype html><meta charset="utf-8"><title>Save Selector Opcode 0x24 Handler</title>z<style>body{font-family:system-ui,sans-serif;background:#111;color:#eee}table{border-collapse:collapse}td,th{border:1px solid #444;padding:6px 8px;vertical-align:top}code{color:#9bd4ff}</style>z*<h1>Save Selector Opcode 0x24 Handler</h1>z<p>Handler: <code>r`   z</code>.</p>z<ul>z<li>current boundary: <code>r0   z</code> value <code>r-   r   z<li>current mode byte: <code>r7   z<li>current mode target: <code>rG   z<li>current mode meaning: rH   r~   z</li>r   rh   z</ul>z<h2>Globals</h2><ul>z<h2>Mode Dispatch</h2>zR<table><thead><tr><th>mode</th><th>target</th><th>meaning</th></tr></thead><tbody>z</tbody></table>z'<h2>Object State Switch For Mode 0</h2>zp<table><thead><tr><th>object+0x67 state</th><th>selector</th><th>target</th><th>meaning</th></tr></thead><tbody>)r:   r   r   r   r   r   )r   rx   rQ   rw   
state_rowsglobal_itemss         r   	html_pager      sF   kk+,2G;;}-3L		  ;;w'-2 I   [[!45;@@HNB J 99 #KK	28b??A L 99a 	L4
T[[W[[-H)IJK<X
&t{{3w{{=7Q3R'S&TThimititux  zA  zE  zE  FV  zW  vX  jY  iZ  Zf  	g
'CDT8U4V(W'XXde
)$++c,:J:J=:Y6Z*[)\\hi
$T[[\5E5Ei5P5WTW1X%Y$ZZ_`
t{{3w{{<89:;5A \1z-  r   c                    |j                  dd       |dz  j                  t        j                  | dd      dz   d	       y )
NT)parentsexist_ok#save_selector_opcode24_handler.jsonFrL   )ensure_asciiindentr   r   r   )mkdir
write_textr   dumps)r   out_dirs     r   write_outputsr      sD    MM$M.44@@

7q9D@ A r   c                    t        j                         } | j                  dt        t        dz         | j                  dt        t
               | j                         }t        |j                  j                         t        |j                  dz  g             }t        ||j                         t        d|j                  dz          y )Nz--exezHwanse2.exe)typedefaultz	--out-dirzsave_selector_gate_paths.jsonz%wrote opcode 0x24 handler summary -> r   )argparseArgumentParseradd_argumentr   ROOTOUT
parse_argsrz   r    
read_bytesr   r   r   print)parserargsr   s      r   mainr      s    $$&F
dD=4HI
$<D$,,!@@"EG '4<<(	1$,,Af2f1g
hir   __main__)r   r   r   r   returnr   )r    bytesr!   
list[dict]r"   r;   r   r;   )r<   r   r   dict)r    r   r<   r   r   r   )r   r   r   r   )r   r   r   r   r   None)r   r   )(__doc__
__future__r   r   r   r   r   syspathlibr   typingr   r   insertr   __file__resolveparentprobe_exe_scene_tablesr   r   r   r   r   ro   rp   MODE1_TARGET_VArq   rj   rk   r   r$   r&   r@   rz   r   r   r   r   __name__rO   r   r   <module>r      s    ; "     
   3tH~--/667 8 > H~''*
Ul
  " % 84$JZ(V/d
j zF r   