§
    ¢K¢j*1  ã                  óˆ  — 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
  eej        d¦  «        rej                             d¬¦  «          ee¦  «                             ¦   «         j        j        j        Zed	z  d
z  dz  dz  Zed	z  dz  ZdZdZd#d„Zd$d„Z	 d%d&d „Zd'd!„Zed"k    r e e¦   «         ¦  «        ‚dS )(uZ  
AutoPOE2 - Offset Registry Builder (TASK-RE-PIPELINE-2026 / Phase C4)

Chuyá»ƒn káº¿t quáº£ trÃ­ch xuáº¥t PyGhidra (data/re_out/<BUILD_ID>/extraction.json)
thÃ nh Offset Registry á»Ÿ HAI Ä‘á»‹nh dáº¡ng:
  1. bin/Release/offsets_<BUILD_ID>.toml  - build-keyed, C++ OffsetRegistry náº¡p
     trá»±c tiáº¿p (khÃ´ng cáº§n SQLite dependency trong C++ Core).
  2. data/poe2_offsets.db (SQLite WAL)    - SSoT táº§ng Python vá»›i provenance Ä‘áº§y Ä‘á»§.

INVARIANT Ä‘Æ°á»£c thá»±c thi:
  INV-BUILD-01   : tá»‡p TOML gáº¯n khÃ³a build_time_date_stamp + build_section_layout_hash;
                   C++ sáº½ tá»« chá»‘i dÃ¹ng náº¿u client Ä‘ang cháº¡y khÃ´ng khá»›p fingerprint.
  INV-SIG-UNIQUE : CHá»ˆ signature cÃ³ match_count == 1 Ä‘Æ°á»£c phÃ©p vÃ o registry.
  INV-OFFSET-01  : khÃ´ng cÃ³ báº¥t ká»³ Ä‘á»‹a chá»‰ heap tuyá»‡t Ä‘á»‘i nÃ o (registry chá»‰ chá»©a
                   RVA/offset tÄ©nh suy tá»« binary trÃªn Ä‘Ä©a).
  Rule 14        : má»�i record kÃ¨m provenance (build_id, sha256, tool, thá»�i Ä‘iá»ƒm).

Ngá»¯ nghÄ©a cuá»‘i cÃ¹ng (Ã´ nÃ o lÃ  InGameState / LifeComponent ...) lÃ  bÆ°á»›c
HUMAN-IN-THE-LOOP: tool Ä‘Ã¡nh dáº¥u target='unreviewed' cho tá»›i khi Ä‘Æ°á»£c xÃ¡c nháº­n
báº±ng dá»¯ liá»‡u live (captures/*_RAM.json, memprobe_report.txt).

CÃ¡ch dÃ¹ng:
  python tools/re_pipeline/build_registry.py --extraction data/re_out/6A9E477A/extraction.json
é    )ÚannotationsN)ÚPath)ÚListÚreconfigureúutf-8©ÚencodingÚdataÚre_outÚ6A9E477Azextraction.jsonzpoe2_offsets.dbaw  
CREATE TABLE IF NOT EXISTS builds (
    build_id              TEXT PRIMARY KEY,
    time_date_stamp       TEXT NOT NULL,
    size_of_image         TEXT NOT NULL,
    file_size             INTEGER NOT NULL,
    file_sha256           TEXT NOT NULL,
    section_layout_hash   TEXT NOT NULL,
    binary_path           TEXT NOT NULL,
    first_seen            TEXT NOT NULL,
    last_verified         TEXT
);

CREATE TABLE IF NOT EXISTS signatures (
    id                INTEGER PRIMARY KEY AUTOINCREMENT,
    build_id          TEXT NOT NULL REFERENCES builds(build_id),
    name              TEXT NOT NULL,
    pattern           TEXT NOT NULL,
    rip_offset        INTEGER NOT NULL,
    match_count       INTEGER NOT NULL,
    unique_ok         INTEGER NOT NULL,
    pattern_bytes     INTEGER,
    target_address    TEXT NOT NULL,
    target_block      TEXT NOT NULL,
    fan_in            INTEGER,
    instruction_addr  TEXT,
    mnemonic          TEXT,
    cross_build_ok    INTEGER DEFAULT 0,
    provenance        TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS offsets (
    id              INTEGER PRIMARY KEY AUTOINCREMENT,
    build_id        TEXT NOT NULL REFERENCES builds(build_id),
    kind            TEXT NOT NULL,
    target          TEXT NOT NULL,
    payload         TEXT NOT NULL,
    validator_id    TEXT,
    source          TEXT NOT NULL,
    discovered_at   TEXT NOT NULL,
    last_verified   TEXT,
    hit_count       INTEGER DEFAULT 0,
    miss_count      INTEGER DEFAULT 0
);

CREATE INDEX IF NOT EXISTS idx_offsets_build ON offsets(build_id, kind);
CREATE INDEX IF NOT EXISTS idx_signatures_build ON signatures(build_id, unique_ok);
)ú.dataz.rdataÚ_RDATAÚaddress_strÚstrÚ
image_baseÚintÚreturnc                ó(   — t          | d¦  «        |z
  S )u>   Chuyá»ƒn Ä‘á»‹a chá»‰ áº£nh (VA) Ghidra tráº£ vá»� thÃ nh RVA.é   )r   )r   r   s     ú8C:\Projects\AutoPOE2\tools\re_pipeline\build_registry.pyÚrva_from_addressr   c   s   € åˆ{˜BÑÔ *Ñ,Ð,ó    ÚrecordÚdictÚsize_of_imageÚboolc                ó  — t          |                      d¦  «        pd¦  «        }|t          vrdS 	 t          t          | d         ¦  «        |¦  «        }n# t          t
          t          f$ r Y dS w xY wd|cxk    o|k     nc S )uO   INV-BUILD-01: registry chá»‰ chá»©a slot .data/.rdata/_RDATA náº±m trong image.ÚblockÚ FÚaddressr   )r   ÚgetÚIN_IMAGE_DATA_BLOCKSr   ÚKeyErrorÚ	TypeErrorÚ
ValueError)r   r   r   r   Úrvas        r   Úis_in_image_data_slotr'   h   s¡   € õ �—
’
˜7Ñ#Ô#Ð) rÑ*Ô*€EØÕ(Ð(Ð(ØˆuðÝ�s 6¨)Ô#4Ñ5Ô5°zÑBÔBˆˆøÝ•i¥Ð,ð ð ð Øˆuˆuðøøøà�Ð#Ð#Ò#Ð#�mÒ#Ð#Ð#Ð#Ð#s   ±#A ÁA0Á/A0Úextraction_pathr   Údb_pathÚ	toml_pathÚ
min_fan_inc                óH  ‡‡‡— t          j        |                      d¬¦  «        ¦  «        }|                     d¦  «        dk    r3t	          d|                     d¦  «        › �t
          j        ¬¦  «         dS |d         }|d	         }|d
         }t          t          |d         ¦  «        d¦  «        Š|d         }|d         }	t          t          |d         ¦  «        d¦  «        Šˆˆˆfd„|d         D ¦   «         }
|
st	          d¦  «         t	          d¦  «         |j	         
                    dd¬¦  «         t          j        t          |¦  «        ¦  «        }	 |                     t          ¦  «         |                     d¦  «         |                     d||d         |d         |d         |d         |d         |d         ||f	¦  «         |                     d|f¦  «         |                     d|f¦  «         t!          |
d¬¦  «        D �]8\  }}|                     d |d!|› d"|d#›�|d$         |                     d%d&¦  «        |d'         d|                     d(¦  «        |d)         |d*         |                     d+¦  «        |                     d,¦  «        |                     d-¦  «        d&t          j        |	|t          | ¦  «        d.œd/¬0¦  «        f¦  «         |                     d1|d2d3t          j        |d$         |                     d%d&¦  «        d4t%          |d)         ‰¦  «        d5›�d6œd/¬0¦  «        d7d8|d d&d&f
¦  «         �Œ:|                     ¦   «          |                     ¦   «          n# |                     ¦   «          w xY wd9d:|› �d;|d         › �d<|d         › �d=|› �d>|	› �d?d@dAdB|d         › �dC|d         › �dAg}g }|
D ])}|d*         dDk    r|                     |d)         ¦  «         Œ*t!          |d dE…         d¬¦  «        D ]/\  }}|                     dF|› dGt%          |‰¦  «        d5›�¦  «         Œ0|r|                     dA¦  «         t!          |
d dE…         d¬¦  «        D ]U\  }}|                     dH|› dI|d$         › �¦  «         |                     dJ|› dI|                     d%d&¦  «        › �¦  «         ŒV|
r|                     dA¦  «         |j	         
                    dd¬¦  «         |                     dK                     |¦  «        dKz   d¬¦  «         t	          dL|› �¦  «         t	          dM|› �¦  «         t	          dN|› dOt1          |
¦  «        › dPt1          |¦  «        › �¦  «         t	          dQ¦  «         t	          dR¦  «         t	          dS¦  «         d&S )TNr   r   Úschemazautopoe2.re_extraction/v1u"   [ERROR] Schema khÃ´ng há»— trá»£: ©Úfileé   Ú
provenanceÚresultÚbuild_idr   r   Úgenerated_atÚtoolr   c                ó
  •— g | ]}|                      d ¦  «        rh|                      d¦  «        dk    rO|                      d¦  «        r:t          |                      dd¦  «        ¦  «        ‰k    ¯lt          |‰‰¦  «        ¯}|‘Œ€S )ÚuniqueÚmatch_countr0   Ú	signatureÚfan_inr   )r!   r   r'   )Ú.0Úcr   r+   r   s     €€€r   ú
<listcomp>z"build_registry.<locals>.<listcomp>ˆ   s’   ø€ ð ð ð ØØ�5Š5�‰?Œ?ðà Ÿušu ]Ñ3Ô3°qÒ8Ð8¸Q¿UºUÀ;Ñ=OÔ=OÐ8Ý�—’�h Ñ"Ô"Ñ#Ô# zÒ1Ð1Ý! ! Z°Ñ?Ô?ð 2ð 	
à1Ð1Ð1r   Ú
candidatesuL   [WARN] KhÃ´ng cÃ³ signature UNIQUE nÃ o - registry rá»—ng pháº§n tri thá»©c.uM          HÃ£y tÄƒng --max-candidates/--pattern-window khi cháº¡y re_extract.py.T)ÚparentsÚexist_okzPRAGMA journal_mode=WAL;z8INSERT OR REPLACE INTO builds VALUES (?,?,?,?,?,?,?,?,?)Útime_date_stampÚ	file_sizeÚfile_sha256Úsection_layout_hashÚbinary_pathz)DELETE FROM signatures WHERE build_id = ?z&DELETE FROM offsets WHERE build_id = ?)ÚstartzÙINSERT INTO signatures (build_id,name,pattern,rip_offset,match_count,unique_ok,pattern_bytes,target_address,target_block,fan_in,instruction_addr,mnemonic,cross_build_ok,provenance) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)Úsig_Ú_Ú03dr9   Ú
rip_offsetr   r8   Úpattern_bytesr    r   r:   Úinstruction_addressÚmnemonic)r5   r4   Ú
extractionF)Úensure_asciiz”INSERT INTO offsets (build_id,kind,target,payload,validator_id,source,discovered_at,last_verified,hit_count,miss_count) VALUES (?,?,?,?,?,?,?,?,?,?)Úaob_patternÚ
unreviewedÚ0xÚX)ÚpatternrJ   Ú
target_rvaÚValidateInGameStateÚ	static_rez?# AutoPOE2 Offset Registry - INV-BUILD-01 build-keyed knowledgez# build_id              = z# binary_sha256         = z# section_layout_hash   = z# generated_at          = z# tool                  = zF# INV-SIG-UNIQUE: moi pattern duoi day chi khop DUNG 1 lan trong .textz:# INV-OFFSET-01: khong co dia chi heap tuyet doi nao o dayr   zbuild_time_date_stamp = zbuild_section_layout_hash = r   é    Ústatic_root_z = 0xÚaob_pattern_z = Úaob_rip_offset_ú
z[OK] SQLite registry : z[OK] TOML registry   : z     build_id=z unique_signatures=z static_roots=zB     [HUMAN-IN-THE-LOOP] Ngu nghia cac slot dang la 'unreviewed' -zB     can doi chuan live (memprobe_report.txt, captures/*_RAM.json)zD     truoc khi gan ten InGameState/LifeComponent/... vao cot target.)ÚjsonÚloadsÚ	read_textr!   ÚprintÚsysÚstderrr   r   ÚparentÚmkdirÚsqlite3ÚconnectÚexecutescriptÚ
SQL_SCHEMAÚexecuteÚ	enumerateÚdumpsr   ÚcommitÚcloseÚappendÚ
write_textÚjoinÚlen)r(   r)   r*   r+   Úpayloadr1   r2   r3   r4   r5   r>   ÚconnÚindexr   ÚlinesÚstatic_rootsr   r   r   s      `             @@r   Úbuild_registryrw   v   s·  øøø€ åŒj˜×2Ò2¸GÐ2ÑDÔDÑEÔE€GØ‡{‚{�8ÑÔÐ ;Ò;Ð;ÝÐJ°7·;²;¸xÑ3HÔ3HÐJÐJÕQTÔQ[Ð\Ñ\Ô\Ð\Øˆqà˜Ô&€JØ�XÔ€FØ˜*Ô%€HÝ•S˜ Ô-Ñ.Ô.°Ñ3Ô3€JØ˜>Ô*€LØ�6Œ?€Då�˜J Ô7Ñ8Ô8¸"Ñ=Ô=€Mðð ð ð ð ð Ø˜,Ô'ðñ ô €Jð ð _ÝÐ\Ñ]Ô]Ð]ÝÐ]Ñ^Ô^Ð^ð „N×Ò °ÐÑ5Ô5Ð5ÝŒ?�3˜w™<œ<Ñ(Ô(€DðHØ×Ò�:Ñ&Ô&Ð&Ø�ŠÐ/Ñ0Ô0Ð0à�ŠØFàØÐ,Ô-Ø˜?Ô+Ø˜;Ô'Ø˜=Ô)ØÐ0Ô1Ø˜=Ô)ØØð
ñ	
ô 	
ð 	
ð 	�ŠÐ@À8À+ÑNÔNÐNØ�ŠÐ=À¸{ÑKÔKÐKå& z¸Ð;Ñ;Ô;ð 0	ñ 0	‰MˆE�6Ø�LŠLð7ð
 Ø1˜8Ð1Ð1 eÐ1Ð1Ð1Ø˜;Ô'Ø—J’J˜|¨QÑ/Ô/Ø˜=Ô)ØØ—J’J˜Ñ/Ô/Ø˜9Ô%Ø˜7”OØ—J’J˜xÑ(Ô(Ø—J’JÐ4Ñ5Ô5Ø—J’J˜zÑ*Ô*ØÝ”JØ!%°|Ý'*¨?Ñ';Ô';ð=ð =à%*ðñ ô ðñô ð ð4 �LŠLð/ð Ø!Ø Ý”JØ$*¨;Ô$7Ø'-§z¢z°,ÀÑ'BÔ'BØ'_Õ,<¸VÀIÔ=NÐPZÑ,[Ô,[Ð'_Ð'_Ð'_ðað að &+ð	ñ ô ð *ØØ ØØØðñ	ô ð ñ ð, 	�Š‰Œˆà�
Š
‰Œˆˆøˆ�
Š
‰Œˆˆøøøð 	JØ/ XÐ/Ð/Ø@ Z°Ô%>Ð@Ð@ØH ZÐ0EÔ%FÐHÐHØ3 \Ð3Ð3Ø+ TÐ+Ð+ØPØDØ
ØB :Ð.?Ô#@ÐBÐBØJ zÐ2GÔ'HÐJÐJØ
ð€Eð !€LØð 3ð 3ˆØ�'Œ?˜gÒ%Ð%Ø×Ò  yÔ 1Ñ2Ô2Ð2øå'¨°S°b°SÔ(9ÀÐCÑCÔCð _ð _Ñˆˆ{Ø�ŠÐ] EÐ]Ð]Õ0@ÀÈjÑ0YÔ0YÐ]Ð]Ð]Ñ^Ô^Ð^Ð^Øð Ø�Š�RÑÔÐå" :¨c¨r¨c¤?¸!Ð<Ñ<Ô<ð Pð P‰ˆˆvØ�ŠÐC EÐCÐC¨f°[Ô.AÐCÐCÑDÔDÐDØ�ŠÐN uÐNÐN°·²¸LÈ!Ñ1LÔ1LÐNÐNÑOÔOÐOÐOØð Ø�Š�RÑÔÐàÔ×Ò 4°$ÐÑ7Ô7Ð7Ø×Ò˜Ÿš 5Ñ)Ô)¨DÑ0¸7ÐÑCÔCÐCå	Ð
- GÐ
-Ð
-Ñ.Ô.Ð.Ý	Ð
/ IÐ
/Ð
/Ñ0Ô0Ð0Ý	ð .˜8ð .ð .½¸J¹¼ð .ð .Ý˜lÑ+Ô+ð.ð .ñ /ô /ð /å	Ð
NÑOÔOÐOÝ	Ð
NÑOÔOÐOÝ	Ð
PÑQÔQÐQØˆ1s   ÅG?M. Í.Nc                 óF  — t          j        d¬¦  «        } |                      dt          t          ¦  «        ¬¦  «         |                      dt          t
          ¦  «        ¬¦  «         |                      dd d¬¦  «         |                      d	t          d
d¬¦  «         |                      ¦   «         }t          |j	        ¦  «        }| 
                    ¦   «         s;t          d|› �t          j        ¬¦  «         t          dt          j        ¬¦  «         dS t          j        |                     d¬¦  «        ¦  «        }|d         d         }|j        rt          |j        ¦  «        nt$          dz  dz  d|› d�z  }t'          |t          |j        ¦  «        ||j        ¦  «        S )Nz+AutoPOE2 Offset Registry Builder (Phase C4))Údescriptionz--extraction)Údefaultz--dbz--tomluI   Tá»‡p TOML xuáº¥t ra (máº·c Ä‘á»‹nh: bin/Release/offsets_<BUILD_ID>.toml))rz   Úhelpz--min-fan-inr   uG   Lá»�c signature theo fan-in tá»‘i thiá»ƒu (0 = giá»¯ táº¥t cáº£ unique))Útyperz   r{   u(   [ERROR] KhÃ´ng tháº¥y tá»‡p extraction: r.   uE           HÃ£y cháº¡y: python tools/re_pipeline/re_extract.py trÆ°á»›c.é   r   r   r1   r3   ÚbinÚReleaseÚoffsets_z.toml)ÚargparseÚArgumentParserÚadd_argumentr   ÚDEFAULT_EXTRACTIONÚ
DEFAULT_DBr   Ú
parse_argsr   rN   Úis_filer`   ra   rb   r]   r^   r_   ÚtomlÚ	REPO_ROOTrw   Údbr+   )ÚparserÚargsr(   rr   r3   r*   s         r   Úmainr�     s¨  € ÝÔ$ØAðñ ô €Fð ×Ò˜µÕ4FÑ0GÔ0GÐÑHÔHÐHØ
×Ò˜­­J©¬ÐÑ8Ô8Ð8Ø
×ÒØ˜$ØXð ñ ô ð ð ×ÒØ�S¨!ØVð ñ ô ð ð ×ÒÑÔ€Då˜4œ?Ñ+Ô+€OØ×"Ò"Ñ$Ô$ð ÝÐJ¸ÐJÐJÕQTÔQ[Ð\Ñ\Ô\Ð\ÝÐUÕ\_Ô\fÐgÑgÔgÐgØˆqåŒj˜×2Ò2¸GÐ2ÑDÔDÑEÔE€GØ�|Ô$ ZÔ0€HØ#'¤9ð •�T”Y‘”�Ý�EÑ˜IÑ%Ð(B°8Ð(BÐ(BÐ(BÑBð õ ˜/­4°´©=¬=¸)ÀTÄ_ÑUÔUÐUr   Ú__main__)r   r   r   r   r   r   )r   r   r   r   r   r   r   r   )r   )
r(   r   r)   r   r*   r   r+   r   r   r   )r   r   )Ú__doc__Ú
__future__r   r�   r]   re   ra   Úpathlibr   Útypingr   ÚhasattrÚstdoutr   Ú__file__Úresolverc   r‰   r„   r…   rh   r"   r   r'   rw   r�   Ú__name__Ú
SystemExit© r   r   ú<module>rš      s†  ððð ð2 #Ð "Ð "Ð "Ð "Ð "à €€€Ø €€€Ø €€€Ø 
€
€
€
Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð à
€7ˆ3Œ:�}Ñ%Ô%ð -Ø„J×Ò GÐÑ,Ô,Ð,àˆD�‰NŒN×"Ò"Ñ$Ô$Ô+Ô2Ô9€	Ø Ñ'¨(Ñ2°ZÑ?ÐBSÑSÐ Ø˜ÑÐ"3Ñ3€
ð/€
ðl 5Ð ð-ð -ð -ð -ð
$ð $ð $ð $ð &'ðSð Sð Sð Sð SðlVð Vð Vð Vð< ˆzÒÐØ
ˆ*�T�T‘V”VÑ
Ô
Ðð Ðr   