
    JjB                       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 ddlmZ  e	e      j!                         j,                  d   Zed	z  Zd
ZdZeez
  ZdZdZdZg dZg dZ dddddddddg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*d/d!Z+d0d"Z,d1d#Z-d1d$Z.d2d3d%Z/d4d&Z0e1d'k(  r e0        yy)5zASummarize file-read candidates for opcode 0x24 mode1 source byte.    )annotationsN)Path)Any)read_sections)parse_imports   outiY iHY i Y iPY iZ )zreadfile-mode1-source-producerzruntime-file-io-tracezruntime-watchpoint-trace)zFReadFile destination/size covering opcode 0x24 mode1 source 0x0059e348zFruntime file-I/O trace proving a save/file read initializes 0x0059e348z8runtime watchpoint trace proving the 0x0059e348 producerHwanse2.exez/ReadFile IAT call and destination argument scan)pathdescriptionzout/exe_imports.jsonzKERNEL32.ReadFile IAT addressz"out/runtime_trace_feasibility.jsonz)runtime file-I/O/watchpoint trace blockerc                    d| dz  dS )N0x    08x values    U/home/exedev/hwanse/tools/summarize_save_selector_opcode24_mode1_file_read_context.pyhex32r   ,   s    
"3'((    c                    d| dz  dS )Nr      02xr   r   s    r   hex8r   0   s    S!""r   c                ^    t        d t        |       D              }|| |d   |d   |d   z    fS )Nc              3  2   K   | ]  }|d    dk(  s|  yw)namez.textNr   ).0sections     r   	<genexpr>ztext_section.<locals>.<genexpr>5   s     [wSZ@Z7[s   rawraw_size)nextr   )exer   s     r   text_sectionr%   4   s;    [-*<[[GC'*:M)MNNNr   c                X   | j                  d      xs g D ]  }t        |j                  d      xs d      j                         |j                         k7  rA|j                  d      xs g D ]:  }|j                  d      |k(  s|j                  d      *t        |d         c c S   y )Nimportsdll 	functionsr   iatVa)getstrlowerint)r'   dll_namefunction_namer(   functions        r   import_iat_var3   9   s    {{9%+ .swwu~#$**,0@@,2 	.H||F#}4g9N9Z8G,--	.. r   c                    dt        j                  d|      z   }g }| j                  |      }|dk\  r,|j                  |       | j                  ||dz         }|dk\  r,|S )Ns   <Ir   r   )structpackfindappend)dataiat_vaneedlehitsposs        r   find_iat_callsr?   C   sa    6;;tV44FD
))F
C
(Ciia( ( Kr   c                x   |dz   t        |       kD  s| |   dk7  ry t        j                  d| |dz         d   }|dz   }d}d }|dz   t        |       k  rD| |   dk(  r<| |dz      d	k(  r1t        j                  d
| |dz         d   }dt        |       }|dz  }n|dz   t        |       k  r9| |   dk(  r1t        j                  d| |dz         d   }dt	        |       }|dz  }nT|dz   t        |       k  rC| |   dk(  r;| |dz      d	k(  r0t        j                  d| |dz         d   }dt	        |       }|dz  }|t        |       k\  s| |   dk7  ry ||z   }|t	        ||z         t	        ||z         |t	        |      t	        |      |t        |      dkD  rt	        |      n
t        |      d|rd| ndz   dz   |dz   |z
  d
S )N      r5   r   r               b   z	add eax, z<i   P      zmov eax, imm32z; r)   z
; push eax

setupIndex
setupVaHex	pushVaHextarget	targetHexbaseHexoffset	offsetHexsetupInstructionsetupByteLength)lenr6   unpack_fromr   r   abs)r:   indextext_vabasecursorrS   offset_instructionrP   s           r   decode_mov_eax_add_pushr_   M   s   qy3t9Ut 3dD%!)4Q7DQYFFzSY4<4#7D!<LPT<T##Cvz:1=(f7!	!s4y	 T&\T%9##D$
;A>(v8!	!s4y	 T&\T%9d6A:>NRV>V##D$
;A>(v8!Td6ld2F]FGeO,7V+,6];&)&kD&8U6]d6l,(:R"#$D
 "A:- r   c                    |dz   t        |       kD  s| |   dk7  ry t        j                  d| |dz         d   }|t        ||z         t        ||z         |t        |      d |t        z
  t        |t        z
  dz        ddd
S )	NrC   h   r5   r   r   r   
push imm32rL   )rW   r6   rX   r   GLOBAL_BUFFER_BASE)r:   rZ   r[   rP   s       r   decode_push_imm32rd   s   s    qy3t9Ut 3dEAI6q9FGeO,7U?+6]--F%77:EF( r   c           	        g }t        |t        |t        |                   D ]W  }t        | ||      }|t	        | ||      }|"t        |d         }t        |cxk  r
t        k  sDn G|j                  |       Y |sy t        |d       S )NrP   c                    | d   S )NrM   r   rows    r   <lambda>z/find_global_destination_setup.<locals>.<lambda>   s    3|+< r   key)
rangeminrW   r_   rd   r/   GLOBAL_SCAN_STARTGLOBAL_SCAN_ENDr9   max)r:   startendr[   
candidatesrZ   decodedrP   s           r   find_global_destination_setupru      s    ')Juc#s4y12 ')$w??'eW=G?WX&'9/9g&' z<==r   c                   g }t        ||dz
        }||k  r| |   }|dk(  r[|dz   |k  rSt        j                  d| |dz         d   }|dk\  r+|j                  |t	        |      t        ||z         dd       |dz  }j|d	k(  rV|d
z   |k  rNt        j                  d| |dz         d   }|j                  |t        |      t        ||z         dd       |dz  }|dz  }||k  r|sy |d   S )N    j   r   rG   r   z	push imm8)sizesizeHex	sizeVaHexsizeInstructionrH   ra      r5   rb   rC   )rp   r6   rX   r9   r   r   )r:   rq   
dest_indexr[   rowsrZ   opcoder   s           r   find_read_size_pushr      s!   !#DzB'E
*
eT>eai*4&&sD%!)<Q?Ez!#E{!&w!7'2	  QJET>eai*4&&tT519=a@EKK <"7U?3#/	  QJE
/ *
0 8Or   c                ~   t        |       \  }}t        |dd      xs t        }t        ||      }g }|D ]f  }t	        d|dz
        }t        ||||d         }	|	't        ||t        |	d         |d         }
|
r-t        |
j                  d      t              rt        |
d         nd }t        |	d         }|d uxr! |t        cxk  xr |t	        |d	      z   k  nc }|j                  t        |d   |z         t        |      |	d
   |	d   |	d   |t        z
  t        |t        z
        dkD  rt        |t        z
  dz        nt        |t        z
        ||
r|
j                  d      nd |
r|
j                  d      nd |
r|
j                  d      nd ||	d   d       i |j!                  d        ||t#        |      fS )NzKERNEL32.dllReadFiler   `   varM   ry   rP   r   rN   rO   rQ   rK   r   rz   r{   r|   rU   )	callVaHexreadFileIatVaHexdestinationSetupVaHexdestinationPushVaHexdestinationHexdestinationOffsetFromGlobalBase"destinationOffsetFromGlobalBaseHexreadSizereadSizeHexreadSizeVaHexreadSizeInstructioncoversMode1SourcerU   c                    | d   S )Nr   r   rg   s    r   ri   z+scan_readfile_global_rows.<locals>.<lambda>   s    c+. r   rj   )r%   r3   READFILE_IAT_FALLBACKr?   rp   ru   r   r/   
isinstancer,   MODE1_SOURCEr9   r   rc   rY   r   sortrW   )r$   r'   textr:   readfile_iatcall_positionsr   call_poswindow_startdestry   	read_sizerP   covers_mode1s                 r   scan_readfile_global_rowsr      s   c"JD$ .*E^I^L#D,7N!#D" 1hm,,T<4PT:V<"4s4;M7NPTUYPZ[)-*TXXf=Ms2SCV%Y]	T(^$T! D,C#i2C)CC 	 	tDzH45 %l 3%),%7$($5";//58J/J6../$6 38BT9TXb8b2cf112!26488I.D6:TXXk2BF488,=#>D!- $%7 8
 	: 	II.I/s>222r   c                   t        | |      \  }}}|D cg c]  }|j                  d      s| }}|sdnd}i dt        t              dt        t              dt        t              dt        t               dt        t               d	t        |      d
|dt        |      dt        |      dt        |      d|d|dddddt        dt        dt        dt        t              d|dS c c}w )Nr   a  The bounded ReadFile argument scan found global-buffer file reads only for offsets 0x11 and 0x12 of 0x0059e310. Both reads transfer one byte and therefore do not cover opcode 0x24 mode1 source 0x0059e348 (+0x38). This rules out the obvious file-read producer shape seen in the same global buffer function, but it is still a static argument-pattern scan rather than a full runtime watchpoint trace.z{At least one ReadFile destination covers 0x0059e348; inspect the file-read rows before treating mode1 source as unresolved.mode1SourceHexglobalBufferBaseHexmode1OffsetHexglobalScanRangeHexz..r   readFileCallCountglobalDestinationReadFileCountmode1FileReadCandidateCountmode1FileReadProducerFoundglobalDestinationReadFileRowsmode1FileReadCandidates
proofFoundFopcode24Mode1FileReadProofFound"failedOpcode24Mode1FileReadGateIdsmissingEvidenceevidenceRefsevidenceRefCountblocked)promotionStatus
conclusion)r   r,   r   r   rc   r   MODE1_OFFSETrn   ro   rW   bool(FAILED_OPCODE24_MODE1_FILE_READ_GATE_IDS)OPCODE24_MODE1_FILE_READ_MISSING_EVIDENCE&OPCODE24_MODE1_FILE_READ_EVIDENCE_REFS)r$   r'   r   r   readfile_call_countrh   
mode1_rowsr   s           r   build_summaryr      ss   .GW.U+L$+!%F#1D)E#FJF 	 K %-u%78 	$|, 	'8!9 :"U?=S<TU	
 	E,/ 	0 	)#d) 	&s: 	%d:&6 	( 	": 	e 	*5 	-.V 	D  	>!" 	C FG#$ % '  Gs
   C5C5c                   ddd| d    dd| d    dd| d	    dd
| d    dd| d    dd| d    d| d    d| d    d| d    dd| d    dd| d    dd| d   dddg}|j                  d | d   D               |j                  g d       |j                  d | d    D               |j                  g d!       |j                  d" | d#   D               |j                  g d$       | d%   D ]E  }|j                  d&|d'    d(|d)    d(|d*    d(|d+    d,|d-   |d-   nd. d/|d0    d1|d2    d3       G | d%   s|j                  d4       |j                  d       d5j                  |      S )6Nz3# Save Selector Opcode 0x24 Mode1 File Read Contextr)   z- mode1 source: `r   `z- global buffer base: `r   z"- mode1 offset from global base: `r   z- global scan range: `r   z- ReadFile IAT: `r   z- ReadFile call count: r   z$- global-destination ReadFile rows: r   z- mode1 file-read candidates: r   z- proofFound: `r   z$- opcode24Mode1FileReadProofFound: `r   z- promotion status: `r   r   z## Failed Gatesc              3  (   K   | ]
  }d | d  yw)- `r   Nr   r   items     r   r    zmarkdown.<locals>.<genexpr>  s     Y43tfAYs   r   )r)   z## Missing Evidencer)   c              3  &   K   | ]	  }d |   yw)z- Nr   r   s     r   r    zmarkdown.<locals>.<genexpr>  s     D2dVDs   r   )r)   z## Evidence Refsr)   c              3  8   K   | ]  }d |d    d|d      yw)r   r   z`: r   Nr   r   rh   s     r   r    zmarkdown.<locals>.<genexpr>  s/       c&k]#c-012s   r   )r)   z## Global ReadFile Destinationsr)   zQ| call | destination setup | destination | offset | size | covers mode1 | setup |z,| --- | --- | --- | --- | ---: | --- | --- |r   z| `r   z` | `r   r   r   z` | r   -z | r   z | `rU   z` |z| - | - | - | - | - | - | - |
)extendr9   join)summarylinesrh   s      r   markdownr      sA   =

G$456a8
!'*?"@!AC
,W5E-F,GqI
 )=!> ?qA
G$678:
!'*=">!?@
.w7W/X.YZ
(1N)O(PQ
',/02
.w7X/Y.ZZ[\
(9 :;1=


%E( 
LLY73W+XYY	LL  
 
LLD1B)CDD	LL  
 
LL >*  
LL   67 
#k"#5-D)E(F G$%&eC0T,U+VVZ"%j/"=s:3Gs&'(S1C-D,ESJ	

 2345	LL99Ur   c           	     "   dj                  d | d   D              }|sd}dj                  d | d   D              }dj                  d | d	   D              }dj                  d
 | d   D              }dj                  g dt        j                  | d          dt        j                  | d          dt        j                  | d          dt        j                  | d          dt        j                  | d          d| d    d| d    d| d    dt        j                  t        | d                dt        j                  | d          d t        j                  | d!          d"| d#| d$| d%| d&      S )'Nr   c              3  B  K   | ]  }d t        j                  |d          dt        j                  |d          dt        j                  |d          dt        j                  |d          d|d   |d   nd	 d
|d    dt        j                  |d          d  yw)z<tr><td><code>r   z</code></td><td><code>r   r   r   z</code></td><td>r   Nr   z	</td><td>r   z</td><td><code>rU   z</code></td></tr>htmlescaper   s     r   r    zhtml_page.<locals>.<genexpr>8  s       	[[[!123 4[[%<!=>? @[[%5!678 9[[%I!JKL M"%j/"=s:3G H&'( )[[%7!89: ;	s   BBr   z"<tr><td colspan='7'>none</td></tr>r)   c              3  N   K   | ]  }d t        j                  |       d  yw)
<li><code>z</code></li>Nr   r   s     r   r    zhtml_page.<locals>.<genexpr>F  s+       T[[&'|4   #%r   c              3  N   K   | ]  }d t        j                  |       d  yw)z<li></li>Nr   r   s     r   r    zhtml_page.<locals>.<genexpr>J  s+       t{{4 !'r   r   c              3     K   | ]9  }d t        j                  |d          dt        j                  |d          d ; yw)r   r   z	</code>: r   r   Nr   r   s     r   r    zhtml_page.<locals>.<genexpr>N  sE       T[[V-.iCDV8W7XX]^s   ?Ar   a  <!doctype html>
<meta charset="utf-8">
<title>Save Selector Opcode 0x24 Mode1 File Read Context</title>
<style>
body { font-family: sans-serif; margin: 2rem; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ccc; padding: 0.35rem 0.5rem; vertical-align: top; }
code { white-space: nowrap; }
</style>
<h1>Save Selector Opcode 0x24 Mode1 File Read Context</h1>
<ul>
  <li>mode1 source: <code>r   z-</code></li>
  <li>global buffer base: <code>r   z'</code></li>
  <li>mode1 offset: <code>r   z,</code></li>
  <li>global scan range: <code>r   z'</code></li>
  <li>ReadFile IAT: <code>r   z(</code></li>
  <li>ReadFile call count: r   z.</li>
  <li>global-destination ReadFile rows: r   z(</li>
  <li>mode1 file-read candidates: r   z</li>
  <li>proofFound: <code>r   z+</code></li>
  <li>promotion status: <code>r   z</code></li>
</ul>
<p>r   z</p>
<h2>Failed Gates</h2>
<ul>z$</ul>
<h2>Missing Evidence</h2>
<ul>z!</ul>
<h2>Evidence Refs</h2>
<ul>z</ul>
<h2>Global ReadFile Destinations</h2>
<table><thead><tr><th>call</th><th>destination setup</th><th>destination</th><th>offset</th><th>size</th><th>covers mode1</th><th>setup</th></tr></thead><tbody>
z
</tbody></table>
)r   r   r   r-   )r   r   failed_gatesmissing_evidenceevidence_refss        r   	html_pager   7  s   99  :; D 377 @A L ww -.  GG >* M! !  !  ;;w/?'@AB!C!! "&W5J-K!L M!N!  ;;w/?'@AB!C ! !%G4H,I JK!L!  ;;w/A'BCD!E!  $$789!! :)!!" *11Q)R(S#!"T##!$ $++H#I"J%!$K%!& S)>%?@A'!&B'!(  ${{73D+EFG)!(H)!, 	KK%&'-!,(-!0 N1!01!4 5!45!8 O9!89!> ?!>?! !r   c                   |j                  dd       |dz  }|j                  t        j                  | dd      dz   d	       |9|j                  j                  dd       |j                  t        |       d	       |S )
NT)parentsexist_okz3save_selector_opcode24_mode1_file_read_context.jsonFrH   )ensure_asciiindentr   utf-8encoding)mkdir
write_textjsondumpsparentr   )r   out_dirhtml_outjson_outs       r   write_outputsr   v  s    MM$M.NNH

7q9D@   dT:Ig.AOr   c                    t        j                  t              } | j                  dt        t
        dz         | j                  dt        t        dz         | j                  dt        t               | j                  dt        d d	
       | j                         }|j                  j                         }|j                  j                         r/t        j                  |j                  j                  d            nt        |j                        }t!        ||      }t#        ||j$                  |j&                        }t)        d|        y )N)r   z--exer
   )typedefaultz	--importszexe_imports.jsonz	--out-dirz
--html-outzHOptional legacy HTML output path. JSON is the default retained artifact.)r   r   helpr   r   z*wrote opcode24 mode1 file-read context -> )argparseArgumentParser__doc__add_argumentr   ROOTOUT
parse_argsr$   
read_bytesr'   existsr   loads	read_textr   r   r   r   r   print)parserargsr$   r'   r   r   s         r   mainr     s   $$9F
dD=4HI
$>P8PQ
$<
W	   D
((


C <<  	

4<<))7);<488$ 
 C)GWdllDMMBH	4*	r   __main__)r   r/   returnr-   )r$   bytesr  ztuple[dict, bytes])r'   dict[str, Any]r0   r-   r1   r-   r  z
int | None)r:   r  r;   r/   r  z	list[int])r:   r  rZ   r/   r[   r/   r  dict[str, Any] | None)
r:   r  rq   r/   rr   r/   r[   r/   r  r  )
r:   r  rq   r/   r   r/   r[   r/   r  r  )r$   r  r'   r  r  z%tuple[int, list[dict[str, Any]], int])r$   r  r'   r  r  r  )r   r  r  r-   )N)r   r  r   r   r   zPath | Noner  r   )r  None)2r   
__future__r   r   r   r   r6   syspathlibr   typingr   r   insertr-   __file__resolver   probe_exe_scene_tablesr   summarize_exe_importsr   r   r   r   rc   r   r   rn   ro   r   r   r   r   r   r   r%   r3   r?   r_   rd   ru   r   r   r   r   r   r   r   __name__r   r   r   <module>r     s:   G "     
   3tH~--/667 8 0 / H~''*
Ul 00 " , (
- ) +\]#4ST1Bmn* &)#O
#L$> @#3L F6r<~
4 zF r   