<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>TaskAgent Reverse Lab</title><description>AI-driven reverse engineering for protected algorithms</description><link>https://taskagent.one/</link><generator>TaskAgent</generator><lastBuildDate>2026年5月11日 18:48:01</lastBuildDate><item><title>WeChat 8.7.0 ClientCheckData White-Box AES: From AES-CBC to 03/08 Table Interpreter Recovery</title><link>https://taskagent.one/en/posts/wechat-client-check-whitebox-aes-cbc/</link><guid isPermaLink="true">https://taskagent.one/en/posts/wechat-client-check-whitebox-aes-cbc/</guid><description>A self-contained walkthrough of the white-box AES-CBC design in the WeChat 8.7.0 client check data path, covering the VER08 PB table interpreter, 03/08 profile differences, key/IV recovery, Frida Hook reverse validation, and edge-generated challenge vectors.</description><pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The first two RQTX articles focused on VM runtime observation, trace aggregation, and semantic hash recovery. This third article moves to another piece of the WeChat 8.7.0 request-protection surface: the white-box AES used around client check data.&lt;/p&gt;
&lt;p&gt;This component does not look like a normal &lt;code&gt;AES-CBC(key, iv, data)&lt;/code&gt; library call. It behaves more like a table interpreter. The runtime code is mostly stable, while the concrete algorithm instance is carried by a PB template. That template contains an IV, TableKey, TableValue, FinalTable, and a few profile fields. The interpreter feeds those tables round by round and eventually emits ciphertext that is semantically equivalent to AES-128-CBC.&lt;/p&gt;
&lt;p&gt;This is a common industry pattern. A protocol wants to preserve AES-CBC semantics, while the client wants to avoid shipping a raw AES key as a normal constant. The key schedule, SBox, MixColumns contribution, and final round key material are folded into lookup tables. The key does not appear as a plain source constant, but the computation still needs the equivalent material somewhere.&lt;/p&gt;
&lt;p&gt;The article starts from standard AES-CBC, then peels into the 03/08 table interpreter, how traces reveal the algorithm boundary, how key/IV recovery works, and how the edge challenge vector can be used for reverse validation.&lt;/p&gt;
&lt;section&gt;&lt;h2&gt;Key Findings&lt;a href=&quot;#key-findings&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;The client check data encryption path is semantically AES-128-CBC: data is processed in 16-byte blocks, each block is XORed with the IV or previous ciphertext block, then encrypted.&lt;/li&gt;
&lt;li&gt;The runtime is not a normal AES implementation. It is a PB-template-driven white-box table interpreter: &lt;code&gt;runtime code = interpreter&lt;/code&gt;, &lt;code&gt;PB template = concrete AES instance&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;00000008&lt;/code&gt; has a weak FinalTable shape. Each byte lane can be fitted as an AES final-round SBox lane, yielding the round-10 key and then the AES-128 master key through inverse key schedule.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;00000003&lt;/code&gt; adds byte-level encoding. Its FinalTable no longer directly reveals the final-round key, but the hidden XOR coordinates can still be recovered from TableValue, allowing first-round TableKey fitting.&lt;/li&gt;
&lt;li&gt;In 8.7.0, the VER08 template is best modeled as descriptor plus template blob plus length plus transform gateway. The gateway materializes protobuf wire records into a typed object before the later OLLVM-style table interpreter consumes them.&lt;/li&gt;
&lt;li&gt;The IV is not a cryptanalytic problem. It is a CBC chaining value carried by the template. Stronger protection needs per-message IV policy, template integrity, stronger table encoding, and cross-byte fusion.&lt;/li&gt;
&lt;li&gt;The page challenge is generated by an edge function. Every refresh produces a random hex input and the corresponding 03/08 AES-CBC ciphertexts for validation against a hook, offline interpreter, or recovered standard AES implementation.&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Edge-Generated White-Box AES Challenge&lt;a href=&quot;#edge-generated-white-box-aes-challenge&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The vector below is generated when the page loads. Every refresh creates a new 24-byte hex input. The server applies the client check data block-padding semantics and returns ciphertext for both &lt;code&gt;00000008&lt;/code&gt; and &lt;code&gt;00000003&lt;/code&gt; profiles.&lt;/p&gt;&lt;p&gt;The browser receives only the input, lengths, padding mode, and ciphertexts. The profile key/IV material is used server-side.&lt;/p&gt;&lt;p&gt;If the card says the server profile is not configured, the deployment has not received the 03/08 equivalent profiles yet. The edge function fails closed and does not return placeholder ciphertext.&lt;/p&gt;&lt;div&gt;
  &lt;div&gt;
    &lt;span&gt;White-box AES Challenge&lt;/span&gt;
    &lt;small&gt;Generating&lt;/small&gt;
  &lt;/div&gt;
  &lt;dl&gt;
    &lt;div&gt;
      &lt;dt&gt;input_kind&lt;/dt&gt;
      &lt;dd&gt;hex_bytes&lt;/dd&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;dt&gt;input_hex&lt;/dt&gt;
      &lt;dd&gt;loading&lt;/dd&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;dt&gt;input_length&lt;/dt&gt;
      &lt;dd&gt;&lt;span&gt;-&lt;/span&gt; bytes&lt;/dd&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;dt&gt;padding&lt;/dt&gt;
      &lt;dd&gt;-&lt;/dd&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;dt&gt;padded_length&lt;/dt&gt;
      &lt;dd&gt;&lt;span&gt;-&lt;/span&gt; bytes&lt;/dd&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;dt&gt;00000008 cipher_hex&lt;/dt&gt;
      &lt;dd&gt;-&lt;/dd&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;dt&gt;00000008 profile_source&lt;/dt&gt;
      &lt;dd&gt;-&lt;/dd&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;dt&gt;00000003 cipher_hex&lt;/dt&gt;
      &lt;dd&gt;-&lt;/dd&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;dt&gt;00000003 profile_source&lt;/dt&gt;
      &lt;dd&gt;-&lt;/dd&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;dt&gt;generated_at&lt;/dt&gt;
      &lt;dd&gt;-&lt;/dd&gt;
    &lt;/div&gt;
  &lt;/dl&gt;
&lt;/div&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Start With Plain AES-CBC&lt;a href=&quot;#start-with-plain-aes-cbc&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;White-box AES is easier to understand once the plain CBC layer is clear:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;ciphertext = AES-CBC-Encrypt(key, iv, plaintext)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;CBC mode is short:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;C[-1] = IV&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;for each 16-byte plaintext block P[i]:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;X[i] = P[i] xor C[i-1]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;C[i] = AES_Encrypt(K, X[i])&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;AES-128 block encryption then follows the familiar round structure:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;state = input&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;state = AddRoundKey(state, K0)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;for round 1..9:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;state = SubBytes(state)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;state = ShiftRows(state)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;state = MixColumns(state)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;state = AddRoundKey(state, Kround)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;state = SubBytes(state)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;state = ShiftRows(state)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;state = AddRoundKey(state, K10)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;SubBytes&lt;/code&gt; is the byte SBox, &lt;code&gt;ShiftRows&lt;/code&gt; rotates rows in the 4x4 state, &lt;code&gt;MixColumns&lt;/code&gt; linearly mixes each column, and &lt;code&gt;AddRoundKey&lt;/code&gt; XORs round-key bytes into the state. AES-128 has eleven round keys, &lt;code&gt;K0..K10&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;A normal implementation often exposes AES constants, SBox tables, T-tables, key schedule code, or a library call boundary. A white-box implementation tries to remove those obvious shapes from source code by folding them into tables.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;The White-Box Intuition: Turn Formulae Into Tables&lt;a href=&quot;#the-white-box-intuition-turn-formulae-into-tables&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A normal AES round can be viewed as:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;output_column = MixColumns(SubBytes(input_column xor round_key_column))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;A white-box implementation precomputes pieces of that relation:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;TableKey[position][input_byte] -&amp;gt; contribution bytes&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The runtime uses the current state byte as a lookup index, obtains contribution bytes, and then combines those contributions through another table:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;TableValue[encoded_contribution_0, encoded_contribution_1, ...] -&amp;gt; output_byte&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The source no longer contains a clear &lt;code&gt;SBox[x xor key]&lt;/code&gt; expression, nor a visible MixColumns formula such as &lt;code&gt;2*x ^ 3*y ^ z&lt;/code&gt;. It mostly contains indexing, offsets, and byte movement.&lt;/p&gt;&lt;p&gt;For the 03/08 family, the core model is:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;runtime code = generic table interpreter&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;PB template   = concrete AES-CBC instance&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Changing the PB template changes the profile while the interpreter remains the same.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;ClientCheckData Encryption Flow&lt;a href=&quot;#clientcheckdata-encryption-flow&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;At the outer layer, the dataflow is:&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;flowchart TD
    A[client check data bytes] --&amp;gt; B[block padding]
    B --&amp;gt; C[split into 16-byte blocks]
    C --&amp;gt; D[CBC XOR with IV or previous ciphertext]
    D --&amp;gt; E[white-box AES table interpreter]
    E --&amp;gt; F[ciphertext block]
    F --&amp;gt; G[next CBC chaining block]&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Inside the interpreter:&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;flowchart TD
    A[plain block xor chaining block] --&amp;gt; B[Transpose to AES-like state]
    B --&amp;gt; C[visible ShiftRows]
    C --&amp;gt; D[round 0 TableKey]
    D --&amp;gt; E[round 0 TableValue]
    E --&amp;gt; F[ShiftRows]
    F --&amp;gt; G[round 1..8 repeat]
    G --&amp;gt; H[FinalTable]
    H --&amp;gt; I[TransposeBack]
    I --&amp;gt; J[cipher block]&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Several boundaries are useful during analysis:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;CBC XOR is visible, so block boundaries are clear.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Transpose&lt;/code&gt; and &lt;code&gt;TransposeBack&lt;/code&gt; convert between byte arrays and AES-like state layout.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ShiftRows&lt;/code&gt; remains visible and appears after each round.&lt;/li&gt;
&lt;li&gt;The nine main rounds become &lt;code&gt;TableKey -&amp;gt; TableValue -&amp;gt; ShiftRows&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The AES final round is collapsed into &lt;code&gt;FinalTable&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;This is not AES disappearing. It is AES represented as a table interpreter.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;The 8.7.0 VER08 Template Boundary&lt;a href=&quot;#the-870-ver08-template-boundary&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In the 8.7.0 client check data path, VER08 should not be understood as an isolated &lt;code&gt;AES_encrypt()&lt;/code&gt; function. The cleaner boundary is:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;collect CCD fields&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; build dataBody&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; build middle wrapper with field 3 = dataBody&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; zlib-compatible compression&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; VER08 AES-CBC-compatible envelope&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; outer ccData&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The white-box AES layer is only the envelope layer. If a hook or offline validator mixes raw business fields, the pre-compression wrapper, compressed bytes, and white-box entry bytes, it will produce false algorithm mismatches.&lt;/p&gt;&lt;p&gt;The 8.7.0 VER08 entry can be modeled with four pieces:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;template descriptor&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;template blob&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;template length&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;transform gateway&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;section&gt;&lt;h3&gt;IDA Callsite Reference&lt;a href=&quot;#ida-callsite-reference&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In IDA, the main collector callsite has this shape:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;ADRL X8, dword_11D077548&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;LDR  W21, [X8]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;ADRL X1, unk_11D036528&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;ADRL X2, unk_11D037454&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;MOV&lt;/span&gt;&lt;span&gt;  X3, X21&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;MOV&lt;/span&gt;&lt;span&gt;  X4, X20&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;BL&lt;/span&gt;&lt;span&gt;   sub_1129E7A20&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;That gives a direct parameter map:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;dword_11D077548 -&amp;gt; template length word&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;unk_11D036528   -&amp;gt; template descriptor&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;unk_11D037454   -&amp;gt; template blob&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;X21             -&amp;gt; template length value&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;X20             -&amp;gt; scratch / arena-like context&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;sub_1129E7A20   -&amp;gt; VER08 template/table expansion gateway&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;In the current 8.7.0 view, the template length is &lt;code&gt;0x400f3&lt;/code&gt;. That is not ciphertext length. It is the full VER08 template blob length, and it lines up with the later field layout and the TableKey/TableValue/FinalTable sizes.&lt;/p&gt;&lt;p&gt;The collector passes descriptor, blob, length, and scratch arena into the gateway. The first gateway stage is not an AES round. It parses protobuf wire records, maps them through descriptor rows, and materializes typed object slots. Large length-delimited fields are represented as source pointer plus length first; the interpreter reads the table windows later.&lt;/p&gt;&lt;p&gt;That prevents a common misread. Looking only at gateway size, switches, and control flow, it may appear to be one huge AES function. Semantically it is closer to:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;wire-format template parser&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; descriptor-backed object materializer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; table expansion / transform gateway&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;No ordinary AES-CBC library boundary is visible on this path. The AES semantics live in template fields, table windows, and interpreter access rhythm.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Gateway Parser Details&lt;a href=&quot;#gateway-parser-details&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The gateway can be modeled with this signature:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sub_1129E7A20&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;VerObject &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;&lt;span&gt;out&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;VerDescriptor &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;&lt;span&gt;descriptor&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;uint8_t&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;&lt;span&gt;blob&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;blob_len&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Arena &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;&lt;span&gt;arena_or_scratch&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Its first stage parses the template blob into 12-byte wire records:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;struct&lt;/span&gt;&lt;span&gt; WireRecord {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;uint32_t&lt;/span&gt;&lt;span&gt; tag;&lt;/span&gt;&lt;span&gt;  // protobuf wire tag, field_number = tag &amp;gt;&amp;gt; 3&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;uint32_t&lt;/span&gt;&lt;span&gt; lo;&lt;/span&gt;&lt;span&gt;   // scalar low bits or value start offset&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;uint32_t&lt;/span&gt;&lt;span&gt; hi;&lt;/span&gt;&lt;span&gt;   // scalar high bits or value end offset&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The important parser behavior is:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;initial record storage: stack scratch, capacity 18&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;growth path: heap array, capacity grows in 0x40-record chunks&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;record size: 0x0c&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;supported wire types: 0, 1, 2, 5&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;rejected wire types: 3, 4&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;length-delimited values: stored as source offsets, not copied immediately&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The second stage is descriptor-driven. The descriptor points to a fixed-size entry array, and the current top-level entries can be read as:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;entry array pointer: 0x11d036108&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;entry count:         22&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;entry size:          0x30&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;fields 1,2:   type 12, flag 1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;field 3:      type 5,  flag 1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;fields 4-8:   type 12, flag 0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;fields 9-12:  type 12, flag 1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;fields 13-21: type 12, flag 0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;field 50:     type 13, flag 0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;type 12&lt;/code&gt; handles length-delimited bytes/string-like fields, &lt;code&gt;type 5&lt;/code&gt; handles a scalar lane, and &lt;code&gt;type 13&lt;/code&gt; handles profile scalar fields such as field 50. Materialized fields are then inserted into a hash/table-like object. Useful gateway ranges to label are:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;0x1129ea26c..0x1129ea288&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;type-12 bytes/slice materialization:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;stores source pointer and length&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;0x1129e8a54..0x1129e8a70&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;scalar/simple materialization into typed field object&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;0x1129ea000..0x1129ea044&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;nested-message handler exists,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;but top-level VER08 table fields use bytes/slice slots&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;So &lt;code&gt;sub_1129E7A20&lt;/code&gt; is better labeled as the VER08 template/table expansion gateway, not as a compact AES round function. It is large, switch-heavy, and recursive in shape, but the current client check data path does not show an ordinary AES-CBC API boundary.&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;What Lives In The PB Template&lt;a href=&quot;#what-lives-in-the-pb-template&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The template is a protobuf wire-format blob. Its fields can be understood by role:&lt;/p&gt;

















































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Field&lt;/th&gt;&lt;th&gt;Role&lt;/th&gt;&lt;th&gt;Reverse-engineering value&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;field 1&lt;/td&gt;&lt;td&gt;profile/version string&lt;/td&gt;&lt;td&gt;Separates &lt;code&gt;00000003&lt;/code&gt;, &lt;code&gt;00000008&lt;/code&gt;, and other table-generation strategies&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;field 2&lt;/td&gt;&lt;td&gt;16-byte IV&lt;/td&gt;&lt;td&gt;CBC initial chaining block&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;field 3&lt;/td&gt;&lt;td&gt;scalar control parameter&lt;/td&gt;&lt;td&gt;In 8.7.0 VER08, this acts as a round-plan control parameter&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;field 9/11&lt;/td&gt;&lt;td&gt;small auxiliary tables&lt;/td&gt;&lt;td&gt;Profile metadata or helper data&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;field 10&lt;/td&gt;&lt;td&gt;TableKey, nine rounds&lt;/td&gt;&lt;td&gt;Absorbs round key, SBox, and MixColumns contribution&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;field 12&lt;/td&gt;&lt;td&gt;TableValue, nine rounds&lt;/td&gt;&lt;td&gt;Combines contributions; close to XOR in 08, encoded binary combiner in 03&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;field 18&lt;/td&gt;&lt;td&gt;FinalTable&lt;/td&gt;&lt;td&gt;Absorbs final SubBytes and last-round key material&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;field 50&lt;/td&gt;&lt;td&gt;profile scalar&lt;/td&gt;&lt;td&gt;Template parameter&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;For 8.7.0 VER08, the roles are more concrete:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;field 1   version selector: &quot;00000008&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;field 2   16-byte CBC IV&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;field 3   scalar control parameter, observed as 0x3060&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;field 9   small required table block, 0x80 bytes&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;field 10  large TableKey block, 0x24000 bytes&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;field 11  small required table block, 0x40 bytes&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;field 12  large TableValue block, 0x1b000 bytes&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;field 18  FinalTable block, 0x1000 bytes&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;field 50  scalar profile parameter, observed as 3&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The same descriptor family also reserves optional slots that are not the main table carriers for the current VER08 instance. This matters for version migration: when a later version shifts field numbers, start by recovering the roles of version, IV, large table blocks, scalar control, and gateway xrefs rather than searching for a raw key.&lt;/p&gt;&lt;p&gt;The large table sizes mirror AES structure:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;TableKey   = 9 rounds * 16 positions * 256 inputs * 4 contribution bytes&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;TableValue = 9 rounds * 16 output positions * 0x300-byte combiner windows&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;FinalTable = 16 positions * 256 entries&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;These are not arbitrary constants. They align with the 16-byte AES state, the nine rounds that include MixColumns, and the final round without MixColumns.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Single-Block Semantics&lt;a href=&quot;#single-block-semantics&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;After reducing implementation detail, one block can be described as:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;state = Transpose(plainBlock xor chainingBlock)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;state = ShiftRows(state)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;for round = 0..8:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;secTable = TableKey[round](state)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;state = TableValue[round](secTable)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;state = ShiftRows(state)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;state = FinalTable(state)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;cipherBlock = TransposeBack(state)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;On 8.7.0 VER08, that plan can be grounded in field windows:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;CBCXor with field 2 IV&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;Transpose4x4&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;ShiftRows&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;for round = 0..8:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;read field 10 TableKey window at round * 0x4000&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;read field 12 TableValue window at round * 0x3000&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ShiftRows&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;read field 18 FinalTable&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;TransposeBack4x4&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;That rhythm is what deserves trace labels: the &lt;code&gt;0x4000&lt;/code&gt;-sized TableKey round window, the &lt;code&gt;0x3000&lt;/code&gt;-sized TableValue round window, the stable &lt;code&gt;ShiftRows&lt;/code&gt; interval, and the separate final table.&lt;/p&gt;&lt;p&gt;Compared with normal AES:&lt;/p&gt;
































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Normal AES&lt;/th&gt;&lt;th&gt;Table interpreter&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;AddRoundKey&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Folded into TableKey and FinalTable&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;SubBytes&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Folded into TableKey and FinalTable&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;MixColumns&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Split into contribution generation and TableValue combining&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;ShiftRows&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Still visible&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;CBC XOR&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Still visible&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;final round&lt;/td&gt;&lt;td&gt;16 independent FinalTable byte lanes&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Once a trace reveals these boundaries, the AES shape is already mostly exposed.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;How Trace Locates The Algorithm&lt;a href=&quot;#how-trace-locates-the-algorithm&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Searching for &lt;code&gt;AES&lt;/code&gt;, &lt;code&gt;SBox&lt;/code&gt;, or &lt;code&gt;CBC&lt;/code&gt; strings is usually weak. The better route is to compress behavior from the boundary inward.&lt;/p&gt;&lt;p&gt;First, observe length behavior. The ciphertext length is always a multiple of 16. Non-aligned input is padded to the next block; aligned input does not receive an extra full block. That padding behavior is a useful boundary marker.&lt;/p&gt;&lt;p&gt;Second, observe chaining. The first plaintext block is XORed with a 16-byte initial block, and later plaintext blocks are XORed with the previous ciphertext block. That is the CBC shell.&lt;/p&gt;&lt;p&gt;Third, observe state layout. After CBC XOR, the 16 bytes are transposed into a 4x4 state and then shifted by AES row rules. &lt;code&gt;Transpose + ShiftRows&lt;/code&gt; is a strong AES fingerprint.&lt;/p&gt;&lt;p&gt;Fourth, observe the 64-byte intermediate buffer. Each TableKey round takes 16 state bytes and emits four contribution bytes for each one. That gives a 64-byte &lt;code&gt;secTable&lt;/code&gt;, matching the idea of byte-level contribution generation.&lt;/p&gt;&lt;p&gt;Fifth, observe TableValue access. It does not simply XOR four bytes in source. Each output byte walks three nibble-level lookup stages. In 08 this is semantically close to XOR; in 03 the same shape is encoded into hidden coordinates.&lt;/p&gt;&lt;p&gt;The trace then becomes a named pipeline:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;padding&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; CBC chaining&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; state transpose&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; visible ShiftRows&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; TableKey contribution&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; TableValue combiner&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; FinalTable&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;              &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; ciphertext&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;That naming is the move from runtime trace to semantic algorithm recovery.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;&lt;code&gt;00000008&lt;/code&gt;: Why FinalTable Leaks The Last-Round Key&lt;a href=&quot;#00000008-why-finaltable-leaks-the-last-round-key&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;00000008&lt;/code&gt; is the more direct profile. TableValue is table-driven, but semantically close to XOR. TableKey contributions are close to raw MixColumns contributions. The most important weakness is FinalTable.&lt;/p&gt;&lt;p&gt;Each final lane is:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;FinalTable[position][x] -&amp;gt; y&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;For 08, each lane can be fitted as:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;T[x] = SBox[x xor a] xor b&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;a&lt;/code&gt; is input-side material absorbed by the table, while &lt;code&gt;b&lt;/code&gt; corresponds to a byte of the last-round key. Fitting is simple:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;for a in 0..255:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;b = T[0] xor SBox[a]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if T[x] == SBox[x xor a] xor b for every x:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;recover b&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Repeat that for 16 lanes, reorder from state position to ciphertext position, and the AES round-10 key is recovered:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;FinalTable&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; 16 lane SBox fit&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; round10 key&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; inverse AES-128 key schedule&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; master key&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The AES-128 key schedule is reversible. Given &lt;code&gt;K10&lt;/code&gt;, walking the schedule backward yields the master key.&lt;/p&gt;&lt;p&gt;The IV is more direct: it is carried by the template as the CBC initial chaining block.&lt;/p&gt;&lt;p&gt;For 08, the recovery route is therefore:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;field18 FinalTable -&amp;gt; round10 key -&amp;gt; master key&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;field2 IV          -&amp;gt; IV&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;That is table-driven AES-CBC, not a strong extraction-resistant white-box design.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;&lt;code&gt;00000003&lt;/code&gt;: More White-Box-Like, Still Recoverable&lt;a href=&quot;#00000003-more-white-box-like-still-recoverable&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;00000003&lt;/code&gt; improves on 08. Its FinalTable no longer directly fits &lt;code&gt;SBox[x xor a] xor b&lt;/code&gt;, and TableKey contribution bytes are not raw MixColumns contribution in the current byte coordinate.&lt;/p&gt;&lt;p&gt;It blocks the shortest 08-style route:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;FinalTable -&amp;gt; round10 key&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;However, the complete truth tables are still present. Each 0x100 TableValue subtable can be treated as an encoded binary combiner:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;encoded_op(encoded_a, encoded_b) -&amp;gt; encoded_sum&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The underlying operation is still XOR, but input and output coordinates have been changed. The recovery route is to normalize the binary operation:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;read binary combiner table&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; find left/right projections&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; recover hidden identity&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; build XOR-isomorphic coordinates&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; decode contribution bytes&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Once the hidden XOR coordinates are recovered, first-round TableKey contribution can be fitted back to AES semantics:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;decoded_contribution ~= affine(coeff * SBox[x xor keyGuess])&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;coeff&lt;/code&gt; is one of the AES MixColumns coefficients &lt;code&gt;01/02/03&lt;/code&gt;. For each key byte, the candidate that matches all 256 inputs is the recovered byte. Since the first round uses the AES master key directly, no inverse key schedule is needed.&lt;/p&gt;&lt;p&gt;The 03 recovery route is:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;TableValue&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; recover hidden XOR coordinates&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; decode first-round contribution&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; fit coeff * SBox[x xor keyGuess]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; master key&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;field2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; IV&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;It is harder than 08, but still a PB-only recovery because the template carries the complete algorithm instance.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;03 vs 08&lt;a href=&quot;#03-vs-08&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;







































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Dimension&lt;/th&gt;&lt;th&gt;&lt;code&gt;00000008&lt;/code&gt;&lt;/th&gt;&lt;th&gt;&lt;code&gt;00000003&lt;/code&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;FinalTable&lt;/td&gt;&lt;td&gt;Direct SBox-lane fit&lt;/td&gt;&lt;td&gt;Encoded permutation, not directly fitted&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;TableValue&lt;/td&gt;&lt;td&gt;Close to XOR combiner&lt;/td&gt;&lt;td&gt;Encoded binary combiner&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;TableKey contribution&lt;/td&gt;&lt;td&gt;Close to raw MixColumns contribution&lt;/td&gt;&lt;td&gt;Byte-level encoded contribution&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PB-only key recovery&lt;/td&gt;&lt;td&gt;Very short through FinalTable&lt;/td&gt;&lt;td&gt;Medium effort through hidden XOR coordinates&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Automated feature matching&lt;/td&gt;&lt;td&gt;Easy&lt;/td&gt;&lt;td&gt;Harder&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;White-box strength&lt;/td&gt;&lt;td&gt;Weak&lt;/td&gt;&lt;td&gt;Better, still insufficient&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;03 raises the cost of simple pattern matching and static fitting. A script that directly searches SBox-like final lanes will work on 08 but not on 03. Still, the deeper structures remain:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;complete truth tables are readable;&lt;/li&gt;
&lt;li&gt;output bytes are not strongly fused;&lt;/li&gt;
&lt;li&gt;round boundaries are stable;&lt;/li&gt;
&lt;li&gt;CBC boundaries are stable;&lt;/li&gt;
&lt;li&gt;the IV is template-provided;&lt;/li&gt;
&lt;li&gt;there is no per-build binding material or runtime-derived table in the core semantics.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;So 03 is better described as encoded table-driven AES, not a strong white-box design.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;From Key/IV Recovery To Semantic Proof&lt;a href=&quot;#from-keyiv-recovery-to-semantic-proof&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Recovering key and IV is only the first step. The useful proof is equivalence.&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;flowchart TD
    A[PB table interpreter] --&amp;gt; D[compare ciphertext]
    B[Recovered AES-CBC key and IV] --&amp;gt; D
    C[Independent random input vectors] --&amp;gt; A
    C --&amp;gt; B
    D --&amp;gt; E[semantic equivalence]&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The first layer is single-block verification, including non-aligned inputs so padding participates in the computation.&lt;/p&gt;&lt;p&gt;The second layer is multi-block verification, which exercises CBC chaining. It is not enough to validate AES block encryption alone.&lt;/p&gt;&lt;p&gt;The third layer is profile verification. 08 and 03 take different recovery routes, but both should land on the same abstract interface:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;encrypt_client_check_data(profile, plaintext_hex) -&amp;gt; cipher_hex&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The page challenge is a lightweight entry point for this proof. Refresh the page, take the generated input and ciphertexts, and compare them with a hook boundary, an offline interpreter, or a recovered standard AES-CBC implementation.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Reverse Validation With A Hook&lt;a href=&quot;#reverse-validation-with-a-hook&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The hook should not patch the return value. That would destroy the verification. The clean approach is to replace the input once at the encryption boundary, then observe the real ciphertext produced by the runtime path.&lt;/p&gt;&lt;p&gt;The boundary can be modeled as:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;encrypt_client_check_data(input_bytes) -&amp;gt; cipher_bytes&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Record four fields:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;page.input_hex&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;runtime input after patch&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;runtime cipher_hex&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;page.cipher_hex&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;When all four align, the edge AES-CBC equivalent implementation, the local encryption boundary, and the recovered 03/08 profile are referring to the same semantics.&lt;/p&gt;&lt;p&gt;A Frida script should start read-only. Confirm argument length, output length, and timing first, then perform one controlled input replacement:&lt;/p&gt;&lt;p&gt;Use a four-step workflow:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;Observe first, do not write memory. Confirm the function receives envelope plaintext, not raw CCD fields or the pre-compression wrapper.&lt;/li&gt;
&lt;li&gt;Record the input pointer, input length, output location, and output length. Output length must be a multiple of 16; non-aligned input should only pad to the next block.&lt;/li&gt;
&lt;li&gt;Replace input once. The replacement length must exactly match the page &lt;code&gt;input_hex&lt;/code&gt; length to avoid breaking the caller’s buffer lifetime.&lt;/li&gt;
&lt;li&gt;Read the real runtime ciphertext in &lt;code&gt;onLeave&lt;/code&gt;, then compare it with the page &lt;code&gt;00000008&lt;/code&gt; or &lt;code&gt;00000003&lt;/code&gt; &lt;code&gt;cipher_hex&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Jailbroken attach and Frida Gadget repackaging differ only in script loading, not in validation logic. In a jailbroken lab, attach after the process is stable. In a repackaged lab, let Gadget load the same script after initialization. The script should not publish hard-coded addresses; resolve slide and target boundaries inside the authorized local environment.&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;challenge&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;profile&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;00000008&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;inputHex&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&amp;lt;page-input-hex&amp;gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;expectedCipherHex&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&amp;lt;page-cipher-hex&amp;gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;targetAddress&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ptr&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&amp;lt;locally-resolved-envelope-entry&amp;gt;&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;patchedOnce&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hexToBytes&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;hex&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;out&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Uint8Array&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;hex&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;out&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;/span&gt;&lt;span&gt;++&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;out&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;parseInt&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;hex&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;slice&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;), &lt;/span&gt;&lt;span&gt;16&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;out&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;readHex&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ptrValue&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Array&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Uint8Array&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ptrValue&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;readByteArray&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt;)))&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&amp;gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;toString&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;16&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;padStart&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;0&quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;join&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;Interceptor&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;attach&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;targetAddress&lt;/span&gt;&lt;span&gt;, {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;onEnter&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resolveInputBuffer&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resolveInputLength&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;expectedLength&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;challenge&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;inputHex&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;check&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;patchedOnce&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;!==&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;expectedLength&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;beforeHex&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;readHex&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;writeByteArray&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;hexToBytes&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;challenge&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;inputHex&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;patchedOnce&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;38&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;check&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;39&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;40&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;onLeave&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;retval&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;41&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;check&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;42&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cipher&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resolveOutputBuffer&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;retval&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;43&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cipherLength&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;challenge&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;expectedCipherHex&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;44&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cipherHex&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;readHex&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cipher&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;cipherLength&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;45&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;46&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;JSON&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;stringify&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;47&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;profile&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;challenge&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;profile&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;48&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;input_before&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;beforeHex&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;49&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;input_after&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;challenge&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;inputHex&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;50&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;cipher_runtime&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cipherHex&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;51&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;cipher_expected&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;challenge&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;expectedCipherHex&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;52&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;matched&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cipherHex&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;challenge&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;expectedCipherHex&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;53&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;54&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;55&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;resolveInputBuffer&lt;/code&gt;, &lt;code&gt;resolveInputLength&lt;/code&gt;, and &lt;code&gt;resolveOutputBuffer&lt;/code&gt; depend on the local boundary. Keep the patch near the white-box AES envelope entry. Patching higher-level business objects or lower-level ciphertext destroys the clarity of the test.&lt;/p&gt;&lt;p&gt;If runtime output does not match the page ciphertext, check these first:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;whether the hook point is after compression and before the white-box envelope;&lt;/li&gt;
&lt;li&gt;whether injected input length exactly matches page &lt;code&gt;input_hex&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;whether the captured output buffer belongs to the current call rather than a reused previous result;&lt;/li&gt;
&lt;li&gt;whether the selected profile is wrong, because &lt;code&gt;00000008&lt;/code&gt; and &lt;code&gt;00000003&lt;/code&gt; are not interchangeable;&lt;/li&gt;
&lt;li&gt;whether aligned input was accidentally given an extra padding block.&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Why White-Box AES Is Hard&lt;a href=&quot;#why-white-box-aes-is-hard&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;White-box cryptography tries to protect key material even when the attacker can observe, debug, and copy the runtime environment. That is much harder than server-side encryption.&lt;/p&gt;&lt;p&gt;The problem with the 03/08 family is not that there is no obfuscation. The problem is that the obfuscation does not remove enough recoverable structure:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;independent FinalTable lanes invite byte-wise analysis;&lt;/li&gt;
&lt;li&gt;full TableValue truth tables allow hidden XOR coordinate recovery;&lt;/li&gt;
&lt;li&gt;per-input TableKey contribution allows SBox/key fitting;&lt;/li&gt;
&lt;li&gt;a static IV is not a security boundary;&lt;/li&gt;
&lt;li&gt;unsigned templates can be analyzed, replaced, or downgraded.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Stronger designs usually combine several measures:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;input/output external encoding&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;+ cross-byte fusion&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;+ fused rounds&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;+ per-build table layout&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;+ runtime-derived transient tables&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;+ template signature&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;+ per-message IV&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;+ anti-downgrade policy&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;White-box AES can still have engineering value. It raises extraction cost and preserves protocol compatibility. But it should not be treated as a guarantee that key material can never be recovered.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Reading Path For Beginners&lt;a href=&quot;#reading-path-for-beginners&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If this is your first white-box AES case, read it in this order:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;Understand AES-CBC: blocks, IV, padding, chaining.&lt;/li&gt;
&lt;li&gt;Understand AES rounds: SBox, ShiftRows, MixColumns, AddRoundKey.&lt;/li&gt;
&lt;li&gt;Think of &lt;code&gt;SBox[x xor key]&lt;/code&gt; as a lookup table.&lt;/li&gt;
&lt;li&gt;Think of MixColumns as four contributions combined by XOR.&lt;/li&gt;
&lt;li&gt;Then map the white-box design: TableKey creates contributions, TableValue combines them, FinalTable finishes the round.&lt;/li&gt;
&lt;li&gt;Finally, read the recovery logic: 08 leaks through final lanes; 03 requires recovering hidden XOR coordinates first.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Viewed this way, white-box AES is not magic. It is standard AES turned into tables and encodings.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;FAQ&lt;a href=&quot;#faq&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;Is the WeChat client check data white-box AES standard AES-CBC?&lt;a href=&quot;#is-the-wechat-client-check-data-white-box-aes-standard-aes-cbc&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Its external semantics are equivalent to AES-128-CBC, but the runtime is not a normal library call. It interprets TableKey, TableValue, and FinalTable from a PB template, and the resulting ciphertext can be verified against recovered key/IV through standard AES-CBC.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Are &lt;code&gt;00000003&lt;/code&gt; and &lt;code&gt;00000008&lt;/code&gt; two completely different algorithms?&lt;a href=&quot;#are-00000003-and-00000008-two-completely-different-algorithms&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;They are better understood as two table-generation strategies for the same AES-CBC table interpreter. 08 is closer to unencoded or weakly encoded table-driven AES. 03 adds byte-level encoding to contribution and combiner tables.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Why can &lt;code&gt;00000008&lt;/code&gt; recover key through FinalTable?&lt;a href=&quot;#why-can-00000008-recover-key-through-finaltable&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Because each 08 FinalTable byte lane can be fitted as &lt;code&gt;SBox[x xor a] xor b&lt;/code&gt;. Recovering the 16 &lt;code&gt;b&lt;/code&gt; values yields the last-round key; inverse AES-128 key schedule then yields the master key.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Why is &lt;code&gt;00000003&lt;/code&gt; still recoverable?&lt;a href=&quot;#why-is-00000003-still-recoverable&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Its FinalTable does not directly fit the same lane model, but TableValue stores complete encoded binary combiner truth tables. After recovering hidden XOR coordinates, first-round TableKey contributions can be fitted to &lt;code&gt;coeff * SBox[x xor keyGuess]&lt;/code&gt;.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;What is the page challenge for?&lt;a href=&quot;#what-is-the-page-challenge-for&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;It is a reverse-validation vector. Refresh the page to get a new hex input and 03/08 ciphertexts, then compare them with a local hook, offline interpreter, or recovered standard AES-CBC implementation.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;How should the 8.7.0 VER08 entry be located?&lt;a href=&quot;#how-should-the-870-ver08-entry-be-located&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Do not start with key search. A more stable route is to follow the client check data collector into the envelope transform, then recover the relationship among version, IV, large table blocks, scalar control, and gateway. Once that boundary is found, validate the path as &lt;code&gt;compressed bytes -&amp;gt; VER08 envelope -&amp;gt; ciphertext&lt;/code&gt;.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Can white-box AES fully prevent key extraction?&lt;a href=&quot;#can-white-box-aes-fully-prevent-key-extraction&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Not by itself. White-box AES raises extraction cost. If full tables, stable round boundaries, independent final lanes, and static IVs remain analyzable, key/IV recovery may still be possible. Stronger designs need encoding, byte fusion, template integrity, and runtime diversity together.&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>WeChat RQTX Part 2: From VM Runtime Trace to Semantic Algorithm Recovery</title><link>https://taskagent.one/en/posts/wechat-rqtx-vm-runtime-to-semantic-hash/</link><guid isPermaLink="true">https://taskagent.one/en/posts/wechat-rqtx-vm-runtime-to-semantic-hash/</guid><description>A technical walkthrough of turning observable WeChat RQTX VM runtime behavior into a semantic hash-like algorithm, including trace aggregation, block naming, standard-algorithm comparison, and verification.</description><pubDate>Sat, 09 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;RQTX sits in a WeChat request-chain signing and checking path. Its input comes from request-related data, and the visible output is a short integer. This second article focuses on what happens after the VM runtime becomes observable: how a long virtual-machine execution stream can be reduced into an algorithm that is readable, testable, and maintainable.&lt;/p&gt;
&lt;p&gt;I prefer to call this step “from runtime to semantics.” At the beginning, the observable objects are VM input, output, registers, memory, and many blocks. At the end, the goal is to name ordinary engineering functions:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;message_schedule()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;compress_sha_like()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;tail_transform()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;rolling133_to_0x44()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;When a register replay like &lt;code&gt;r8/r9/ra/rb&lt;/code&gt; becomes algorithm objects such as &lt;code&gt;state&lt;/code&gt;, &lt;code&gt;block&lt;/code&gt;, &lt;code&gt;digest&lt;/code&gt;, and &lt;code&gt;finalizer&lt;/code&gt;, RQTX has effectively walked out of the VM.&lt;/p&gt;
&lt;p&gt;The article first gives a page-level verification vector, then extracts a standard-library-like algorithm skeleton. After that, it explains how trace localizes the algorithm and where the result resembles or diverges from MD5, SHA-2, HMAC, CRC, and rolling-hash families.&lt;/p&gt;
&lt;section&gt;&lt;h2&gt;Key Conclusions&lt;a href=&quot;#key-conclusions&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;The input boundary for this path is not the raw request body. It is a normalized 32-byte lowercase MD5 hex string.&lt;/li&gt;
&lt;li&gt;VM trace should not be read as one long line. It should be aggregated into memory boundaries, dynamic blocks, context-slot diffs, and block-local instruction windows.&lt;/li&gt;
&lt;li&gt;The main algorithm is not CRC, standard MD5, standard SHA-256, or standard HMAC. It borrows recognizable structures and then applies profile-specific changes.&lt;/li&gt;
&lt;li&gt;Semantic recovery depends on naming blocks by behavior, validating them against standard algorithm shapes, and closing the loop with both a VM oracle and primitive tests.&lt;/li&gt;
&lt;li&gt;The VM runtime should not be discarded after the semantic implementation works. It remains useful as a trace oracle, regression oracle, and version-migration oracle.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;The article moves through five layers: a refresh-generated vector, a publishable algorithm skeleton, trace localization, standard-algorithm comparison, and a verification loop.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Refresh-generated Verification Vector&lt;a href=&quot;#refresh-generated-verification-vector&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The vector below is generated by an edge function when the page loads. Each refresh produces a new 32-byte ASCII hex input and the corresponding &lt;code&gt;0x44&lt;/code&gt;-prefixed RQTX result. It is meant for reverse comparison with local hooks, runtime trace, or a semantic implementation.&lt;/p&gt;&lt;div&gt;
  &lt;div&gt;
    &lt;span&gt;RQTX Challenge&lt;/span&gt;
    &lt;small&gt;generating&lt;/small&gt;
  &lt;/div&gt;
  &lt;dl&gt;
    &lt;div&gt;
      &lt;dt&gt;input_kind&lt;/dt&gt;
      &lt;dd&gt;md5_hex_32&lt;/dd&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;dt&gt;cmd&lt;/dt&gt;
      &lt;dd&gt;-&lt;/dd&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;dt&gt;input&lt;/dt&gt;
      &lt;dd&gt;loading&lt;/dd&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;dt&gt;rqtx&lt;/dt&gt;
      &lt;dd&gt;-&lt;/dd&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;dt&gt;generated_at&lt;/dt&gt;
      &lt;dd&gt;-&lt;/dd&gt;
    &lt;/div&gt;
  &lt;/dl&gt;
&lt;/div&gt;&lt;section&gt;&lt;h3&gt;Local Reverse Validation With Frida&lt;a href=&quot;#local-reverse-validation-with-frida&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The page does not accept custom reader input. Instead, it publishes a fresh vector on each refresh. A reader can hook the relevant local boundary, replace the live input with the generated vector, and compare the device result with the page result.&lt;/p&gt;&lt;p&gt;For a jailbroken Frida flow, the validation shape is:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// Replace symbolic names with locally verified symbols.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;target&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Module&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;findExportByName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;rqtx_entry_like&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;Interceptor&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;attach&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;target&lt;/span&gt;&lt;span&gt;, {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;onEnter&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;vector&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;replace_with_page_generated_input&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Memory&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;writeUtf8String&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;&lt;span&gt;], &lt;/span&gt;&lt;span&gt;vector&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ptr&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;vector&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;onLeave&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;retval&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;device rqtx =&quot;&lt;/span&gt;&lt;span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;retval&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;For a repackaged Frida flow, inject the same boundary replacement into the app process and compare the result after the request path reaches RQTX. Keep the probe narrow: modify only the normalized input boundary and log only the short result. Avoid collecting raw request bodies or unrelated user data.&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;First, Shape The Algorithm Like A Standard Library&lt;a href=&quot;#first-shape-the-algorithm-like-a-standard-library&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Before reading every trace line, it helps to define the kind of code we want to end with. The publishable semantic implementation should look like a normal small algorithm library, not like VM register replay.&lt;/p&gt;&lt;p&gt;A useful architecture is:&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;struct&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RqtxInput&lt;/span&gt;&lt;span&gt;&amp;lt;&apos;&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;&amp;gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;md5_hex_32&lt;/span&gt;&lt;span&gt;: &amp;amp;&apos;&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;u8&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;32&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cmd&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;u32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;struct&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RqtxProfile&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;iv&lt;/span&gt;&lt;span&gt;: [&lt;/span&gt;&lt;span&gt;u32&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;8&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;round_constants&lt;/span&gt;&lt;span&gt;: &amp;amp;&apos;&lt;/span&gt;&lt;span&gt;static&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;u32&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;finalizer_seed&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;u32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;pub&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rqtx_870&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;: &amp;amp;&lt;/span&gt;&lt;span&gt;RqtxInput&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;profile&lt;/span&gt;&lt;span&gt;: &amp;amp;&lt;/span&gt;&lt;span&gt;RqtxProfile&lt;/span&gt;&lt;span&gt;) -&amp;gt; &lt;/span&gt;&lt;span&gt;u16&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;block&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;stage_md5_hex&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;.md5_hex_32, &lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;.cmd);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;words&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;message_schedule&lt;/span&gt;&lt;span&gt;(&amp;amp;&lt;/span&gt;&lt;span&gt;block&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;digest&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;compress_sha_like&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;profile&lt;/span&gt;&lt;span&gt;.iv, &amp;amp;&lt;/span&gt;&lt;span&gt;words&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;profile&lt;/span&gt;&lt;span&gt;.round_constants);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;tail&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;tail_transform&lt;/span&gt;&lt;span&gt;(&amp;amp;&lt;/span&gt;&lt;span&gt;digest&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;.cmd);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;rolling133_to_0x44&lt;/span&gt;&lt;span&gt;(&amp;amp;&lt;/span&gt;&lt;span&gt;tail&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;profile&lt;/span&gt;&lt;span&gt;.finalizer_seed)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This shape is intentionally close to standard cryptographic and checksum libraries. It separates input staging, message schedule, compression-like mixing, tail transformation, and final short-integer reduction.&lt;/p&gt;&lt;p&gt;That does not mean RQTX is SHA-256, HMAC, MD5, or CRC. It means the comparison target is clear. Once the semantic code has this shape, the analysis can say precisely which pieces resemble a standard primitive and which pieces are profile-specific.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Start By Accepting The VM As The Oracle&lt;a href=&quot;#start-by-accepting-the-vm-as-the-oracle&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;At the beginning of semantic recovery, the VM runtime is the only trustworthy oracle. The trace is noisy, the pseudo-code is distorted by CFG flattening, and a hand-written semantic implementation is not yet proven.&lt;/p&gt;&lt;p&gt;The first rule is simple: the semantic implementation is wrong until it matches the VM oracle for many inputs.&lt;/p&gt;&lt;p&gt;The oracle gives three kinds of evidence:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;input staging: where the normalized 32-byte input is placed;&lt;/li&gt;
&lt;li&gt;state evolution: how context fields and memory windows change across blocks;&lt;/li&gt;
&lt;li&gt;output write: where the short RQTX value is produced.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;This prevents a common mistake: seeing SHA-like operations in the runner and immediately declaring the whole algorithm to be SHA-256. The VM oracle forces every abstraction to earn its name.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Trace Should Be Aggregated, Not Hoarded&lt;a href=&quot;#trace-should-be-aggregated-not-hoarded&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;More trace is not automatically better. Raw instruction trace becomes unreadable quickly. The useful trace is compressed into layers:&lt;/p&gt;
























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Trace View&lt;/th&gt;&lt;th&gt;What It Answers&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;memory boundary trace&lt;/td&gt;&lt;td&gt;Where input is staged and output is written.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;dynamic block trace&lt;/td&gt;&lt;td&gt;Which blocks form loops, rounds, and tails.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;context slot diff&lt;/td&gt;&lt;td&gt;Which slots behave like state, block words, counters, or digest.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;block-local instruction window&lt;/td&gt;&lt;td&gt;Which operations resemble known algorithm steps.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;The goal is to replace “thousands of native instructions” with “a small number of behavior-labeled blocks.” A block name should describe what the block does, not where it lives.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;How Trace Localizes The Algorithm&lt;a href=&quot;#how-trace-localizes-the-algorithm&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;Step 1: Lock The Wrapper Boundary&lt;a href=&quot;#step-1-lock-the-wrapper-boundary&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Start from the known request-chain entry and stop at the wrapper that receives the normalized RQTX input. This boundary keeps request normalization separate from the protected algorithm.&lt;/p&gt;&lt;p&gt;The wrapper boundary is proven when:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;repeated calls hit the same path;&lt;/li&gt;
&lt;li&gt;the normalized input appears at a stable memory boundary;&lt;/li&gt;
&lt;li&gt;replacing only that staged input changes the final RQTX result;&lt;/li&gt;
&lt;li&gt;unrelated request fields do not need to be dumped to reproduce the algorithm input.&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Step 2: Use Boundary Memory Trace For Input Staging And Output Write&lt;a href=&quot;#step-2-use-boundary-memory-trace-for-input-staging-and-output-write&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Memory boundary trace identifies where the 32-byte hex string enters VM-visible memory and where the short integer is written back.&lt;/p&gt;&lt;p&gt;This is the first semantic cut:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;request material&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; normalized md5_hex_32&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; VM staging buffer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; VM rounds&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; short rqtx result&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The staging boundary tells us that the raw request body is not the algorithm input. The output boundary tells us which value the semantic implementation must reproduce.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Step 3: Use Dynamic Block Trace To Find Loop Skeletons&lt;a href=&quot;#step-3-use-dynamic-block-trace-to-find-loop-skeletons&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;After staging, the VM runs repeated block groups. The important question is not the native block address. The important question is whether the block group behaves like a schedule loop, a compression round, a tail transformation, or a final reducer.&lt;/p&gt;&lt;p&gt;Dynamic block trace gives this shape:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;stage_input&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; prepare_words&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; schedule_loop&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; compression_round_loop&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; tail_mix&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; rolling_finalizer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; write_output&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;This skeleton is the bridge between VM runtime and semantic algorithm.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Step 4: Use Context Slot Diffs To Name State, Block, And Digest&lt;a href=&quot;#step-4-use-context-slot-diffs-to-name-state-block-and-digest&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Context slot diffs turn blocks into objects. A slot that is written once after input staging is likely part of &lt;code&gt;block&lt;/code&gt;. A group of eight 32-bit values updated across rounds behaves like &lt;code&gt;state&lt;/code&gt;. A derived group that survives into the final reducer behaves like &lt;code&gt;digest&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;This naming step should be conservative. If a slot looks like a counter in one trace but behaves like a pointer in another, it should remain unnamed until the conflict is explained.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Step 5: Compare Block-local Windows With Standard Algorithms&lt;a href=&quot;#step-5-compare-block-local-windows-with-standard-algorithms&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Only after the block skeleton and context names are stable should standard algorithms enter the discussion. The comparison should be structural:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Does the schedule expand 16 words into a larger word array?&lt;/li&gt;
&lt;li&gt;Does the round loop maintain eight working variables?&lt;/li&gt;
&lt;li&gt;Are rotate, shift, choose, majority, xor, or modular-add patterns present?&lt;/li&gt;
&lt;li&gt;Are constants used like SHA-2 round constants or profile-specific tables?&lt;/li&gt;
&lt;li&gt;Does the finalizer reduce a digest into a short result like a checksum or rolling hash?&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;This is where “similar to SHA-2” becomes a useful clue, and “not standard SHA-256” becomes a precise conclusion.&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;The First Main Line Seen In Runtime&lt;a href=&quot;#the-first-main-line-seen-in-runtime&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The first stable line in runtime is input staging. The visible input is a lowercase 32-byte MD5 hex string. That string is not the final algorithm. It is a normalized boundary.&lt;/p&gt;&lt;p&gt;The VM then transforms it through a sequence that looks like:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;md5_hex_32&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; profile-aware block staging&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; message schedule&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; SHA-like compression&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; MD5-like or HMAC-like tail influence&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; rolling reducer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; 0x44-prefixed short value&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;This line explains why isolated observations can be misleading. Seeing MD5 at the input boundary does not make the core MD5. Seeing SHA-like rounds does not make it standard SHA-256. Seeing a short final result does not make it CRC.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Semantic Part 1: MD5 Hex Is Input Normalization, Not The Main Algorithm&lt;a href=&quot;#semantic-part-1-md5-hex-is-input-normalization-not-the-main-algorithm&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The 32-byte lowercase MD5 hex string is a boundary artifact. It is how request-related material is normalized before it enters the protected path.&lt;/p&gt;&lt;p&gt;This matters because MD5 can appear in the trace and still not be the algorithm being recovered. The semantic code should represent this as staging:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;stage_md5_hex&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;: &amp;amp;[&lt;/span&gt;&lt;span&gt;u8&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;32&lt;/span&gt;&lt;span&gt;], &lt;/span&gt;&lt;span&gt;cmd&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;u32&lt;/span&gt;&lt;span&gt;) -&amp;gt; &lt;/span&gt;&lt;span&gt;ProfileBlock&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// Normalize and place bytes into the profile-specific block layout.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;ProfileBlock&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;from_md5_hex_and_cmd&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;cmd&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The proof is behavioral: replacing the staged 32-byte value changes the final RQTX result in a controlled way, while the rest of the algorithm still executes through the VM path.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Semantic Part 2: It Looks Like SHA-2, But It Is Not SHA-256&lt;a href=&quot;#semantic-part-2-it-looks-like-sha-2-but-it-is-not-sha-256&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The strongest structural similarity is SHA-2-like compression:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;words are expanded from an initial block;&lt;/li&gt;
&lt;li&gt;several 32-bit working values move through repeated rounds;&lt;/li&gt;
&lt;li&gt;rotate, shift, xor, choose-like, majority-like, and modular-add patterns appear;&lt;/li&gt;
&lt;li&gt;constants influence round behavior.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;The differences are just as important:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;the input block is profile-staged, not a standard SHA-256 padded message block;&lt;/li&gt;
&lt;li&gt;constants and IV-like values are profile-specific;&lt;/li&gt;
&lt;li&gt;tail processing does not follow standard SHA-256 digest finalization;&lt;/li&gt;
&lt;li&gt;the output is reduced into a short RQTX value instead of a 256-bit digest.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;So the correct description is SHA-2-like, not SHA-256.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Why The SHA-2-like Label Is Defensible&lt;a href=&quot;#why-the-sha-2-like-label-is-defensible&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The label is defensible because it comes from multiple signals, not from one operation:&lt;/p&gt;




























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Signal&lt;/th&gt;&lt;th&gt;Why It Matters&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;schedule expansion&lt;/td&gt;&lt;td&gt;Matches the idea of deriving later words from earlier words.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;eight-lane state&lt;/td&gt;&lt;td&gt;Resembles a SHA-2 compression state shape.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;rotate/shift/xor mix&lt;/td&gt;&lt;td&gt;Matches SHA-2-style bit mixing.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;repeated round loop&lt;/td&gt;&lt;td&gt;Separates schedule, compression, and tail behavior.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;profile constants&lt;/td&gt;&lt;td&gt;Explains why it is similar but not standard.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;The label would be weak if it came only from a rotate instruction or a single constant. It becomes useful when the whole block behavior aligns.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Semantic Part 3: It Looks Like HMAC, But It Is Not HMAC&lt;a href=&quot;#semantic-part-3-it-looks-like-hmac-but-it-is-not-hmac&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;HMAC-like signals can appear when the trace shows staged material, profile-derived constants, and inner/outer-looking influence. But standard HMAC has a clear construction: key normalization, ipad/opad, inner hash, and outer hash.&lt;/p&gt;&lt;p&gt;RQTX does not cleanly follow that construction. The better interpretation is that it borrows the idea of profile-conditioned mixing, not the exact HMAC algorithm.&lt;/p&gt;&lt;p&gt;In semantic code, that difference should be visible:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;tail_transform&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;digest&lt;/span&gt;&lt;span&gt;: &amp;amp;[&lt;/span&gt;&lt;span&gt;u32&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;8&lt;/span&gt;&lt;span&gt;], &lt;/span&gt;&lt;span&gt;cmd&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;u32&lt;/span&gt;&lt;span&gt;) -&amp;gt; &lt;/span&gt;&lt;span&gt;TailState&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// Profile-specific tail mixing, not HMAC ipad/opad finalization.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;TailState&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;mix&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;digest&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;cmd&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Semantic Part 4: It Looks Like MD5, But It Is Not MD5&lt;a href=&quot;#semantic-part-4-it-looks-like-md5-but-it-is-not-md5&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;MD5 appears at the boundary and can also appear as a comparison shape because the input is a 32-byte hex MD5 string. But the algorithm’s core loop does not behave like standard MD5 compression.&lt;/p&gt;&lt;p&gt;The important distinction is:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;MD5 as a normalization source: yes;&lt;/li&gt;
&lt;li&gt;MD5 as the recovered VM core: no;&lt;/li&gt;
&lt;li&gt;MD5-like byte ordering or digest influence: possible, but must be tied to specific blocks.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;This prevents the analysis from collapsing all “MD5-looking” artifacts into one incorrect conclusion.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Semantic Part 5: The Final Step Is Not CRC, But A Rolling Mixer&lt;a href=&quot;#semantic-part-5-the-final-step-is-not-crc-but-a-rolling-mixer&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The final reducer is tempting to call CRC because it produces a short result. The trace does not support that conclusion.&lt;/p&gt;&lt;p&gt;A CRC-like reducer would normally show polynomial-style shifts and table or bit-level feedback. The observed finalizer is better modeled as a rolling mixer:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rolling133_to_0x44&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;tail&lt;/span&gt;&lt;span&gt;: &amp;amp;&lt;/span&gt;&lt;span&gt;TailState&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;seed&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;u32&lt;/span&gt;&lt;span&gt;) -&amp;gt; &lt;/span&gt;&lt;span&gt;u16&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mut&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;acc&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;seed&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;tail&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;bytes&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;acc&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;acc&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;wrapping_mul&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;133&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;wrapping_add&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;u32&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;acc&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;^=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;acc&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;11&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;0x4400&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; ((&lt;/span&gt;&lt;/span&gt;&lt;span&gt;acc&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;u16&lt;/span&gt;&lt;span&gt;) &amp;amp; &lt;/span&gt;&lt;span&gt;0x00ff&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The exact constants belong to the profile under analysis. The important public point is the shape: rolling accumulation and short reduction, not CRC polynomial computation.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;From Register Replay To Semantic Code&lt;a href=&quot;#from-register-replay-to-semantic-code&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Register replay is useful early because it stays close to the VM. It is bad as the final article-level abstraction because it hides meaning.&lt;/p&gt;&lt;p&gt;The migration path is:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;r8/r9/ra/rb snapshots&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; context slot names&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; state/block/digest/tail objects&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; standard-library-like functions&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; tests against VM oracle&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;A good semantic implementation should be boring to read. It should look like ordinary code with small functions and explicit profiles. The reverse-engineering work remains in the evidence chain and tests, not in exotic naming.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Standard Algorithm Comparison&lt;a href=&quot;#standard-algorithm-comparison&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;“Similar” is a lead. “Different” is the result that matters.&lt;/p&gt;
























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Standard Shape&lt;/th&gt;&lt;th&gt;RQTX Relationship&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;MD5&lt;/td&gt;&lt;td&gt;Used as input normalization boundary; not the main VM core.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SHA-256 / SHA-2&lt;/td&gt;&lt;td&gt;Strong structural resemblance in schedule and compression; not a standard digest implementation.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;HMAC&lt;/td&gt;&lt;td&gt;Profile-conditioned tail influence resembles keyed mixing; not standard HMAC construction.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;CRC&lt;/td&gt;&lt;td&gt;Short output is superficially similar; final reducer behaves more like a rolling mixer.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;This comparison is valuable because it lets the article say exactly what was borrowed and exactly what was changed.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Verification Loop&lt;a href=&quot;#verification-loop&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The verification loop has four layers:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;Page vector: edge-generated input/result pair.&lt;/li&gt;
&lt;li&gt;Device hook: replace the normalized input boundary and observe device output.&lt;/li&gt;
&lt;li&gt;VM oracle: run the recovered VM runtime against the same input.&lt;/li&gt;
&lt;li&gt;Semantic implementation: run the standard-library-like code against the same input.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;The implementation is accepted only when all four agree over many generated vectors. A single match can be luck. A thousand random matches against the VM and semantic implementation provide much stronger confidence.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;The Role Of AI In This Process&lt;a href=&quot;#the-role-of-ai-in-this-process&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;AI is useful as a naming, summarization, and comparison assistant. It can help turn trace groups into candidate names, compare a block skeleton against standard algorithm families, and point out missing verification steps.&lt;/p&gt;&lt;p&gt;AI should not be treated as the oracle. The oracle is still the VM runtime, the device result, and the tests. A suggested function name is useful only after trace behavior proves it.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Common Pitfalls&lt;a href=&quot;#common-pitfalls&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Calling the input MD5 because the boundary contains MD5 hex.&lt;/li&gt;
&lt;li&gt;Calling the core SHA-256 because the rounds look SHA-like.&lt;/li&gt;
&lt;li&gt;Calling the final reducer CRC because the output is short.&lt;/li&gt;
&lt;li&gt;Trusting one trace without checking input variation.&lt;/li&gt;
&lt;li&gt;Keeping register names in the final semantic layer.&lt;/li&gt;
&lt;li&gt;Throwing away the VM runtime after the semantic code starts passing.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Each pitfall comes from naming too early. The cure is to keep the evidence chain visible.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Combining The Two Stages&lt;a href=&quot;#combining-the-two-stages&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The first article recovers the VM architecture: entry, &lt;code&gt;rqtx.dat&lt;/code&gt;, context, instruction decoding, runner, and offline runtime. This article uses that runtime to recover semantic algorithm structure.&lt;/p&gt;&lt;p&gt;Together they form one chain:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;entry proof&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; VM image proof&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; context proof&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; runner proof&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; runtime oracle&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; trace aggregation&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; semantic algorithm&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;              &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; standard comparison&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; verification vectors&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;This is why the runtime matters even after semantic lifting. It remains the bridge between protected execution and readable code.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Final Notes&lt;a href=&quot;#final-notes&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The most useful result is not a dramatic name for the algorithm. The useful result is a maintainable model: normalized input, profile-specific staging, SHA-2-like compression, non-standard tail mixing, rolling finalization, and tests that compare semantic output with VM output.&lt;/p&gt;&lt;p&gt;That model is precise enough to publish, precise enough to test, and flexible enough to survive version migration.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;FAQ&lt;a href=&quot;#faq&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;Is RQTX standard SHA-256?&lt;a href=&quot;#is-rqtx-standard-sha-256&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;No. It has SHA-2-like structure, but the input staging, constants, tail behavior, and short output do not match standard SHA-256.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Is RQTX standard HMAC?&lt;a href=&quot;#is-rqtx-standard-hmac&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;No. Some profile-conditioned mixing can look HMAC-like, but the recovered path does not follow the standard HMAC construction.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Is the 32-byte input the raw request body?&lt;a href=&quot;#is-the-32-byte-input-the-raw-request-body&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;No. The observed input boundary is a normalized lowercase MD5 hex value derived from request-related material.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Why keep the VM runtime after semantic recovery?&lt;a href=&quot;#why-keep-the-vm-runtime-after-semantic-recovery&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The runtime remains the oracle for regression, trace, and version migration. Semantic code is easier to read, but the VM proves whether it is still correct.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;How should readers verify the result?&lt;a href=&quot;#how-should-readers-verify-the-result&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Use the generated page vector, hook the normalized local input boundary, compare the device result, then compare the VM runtime and semantic implementation against the same vector.&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>WeChat RQTX IRVMP Recovery: Architecture, Instructions, and Runtime</title><link>https://taskagent.one/en/posts/wechat-rqtx-irvmp-recovery/</link><guid isPermaLink="true">https://taskagent.one/en/posts/wechat-rqtx-irvmp-recovery/</guid><description>A technical recovery note on WeChat 8.7.0 RQTX IRVMP, covering rqtx.dat, VM initialization, instruction encoding, CFG deobfuscation, IDA/Frida analysis, and offline runtime reconstruction.</description><pubDate>Fri, 08 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This article records the reverse-engineering and recovery process for the RQTX IRVMP path. The important part is not a single hook point. The useful result is a chain of engineering objects that can be inspected and tested: the entry point, VM initialization, the &lt;code&gt;rqtx.dat&lt;/code&gt; layout, instruction encoding, runner semantics, CFG cleanup, and an offline runtime.&lt;/p&gt;
&lt;p&gt;Each layer is explained in the same order: what it is, why it matters, and how it can be proven. The article should read as an evidence chain rather than a work log.&lt;/p&gt;
&lt;section&gt;&lt;h2&gt;Key Conclusions&lt;a href=&quot;#key-conclusions&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;The WeChat 8.7.0 RQTX path can be split into seven stages: ObjC anchor, slot/body proof, VM init and layout proof, payload dump, runner localization, CFG skeleton stripping, and offline runtime verification.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rqtx.dat&lt;/code&gt; is not just an opcode list. It behaves like a packaged VM image that contains an opcode map, payload image, relocation/export slots, and internal VM blocks.&lt;/li&gt;
&lt;li&gt;RQTX IRVMP instruction decoding depends on &lt;code&gt;raw_word&lt;/code&gt;, the current IP, and the opcode map. The same high six bits can map to different semantics at different IPs.&lt;/li&gt;
&lt;li&gt;Version migration should preserve the evidence chain and layout relationships instead of directly reusing old runtime addresses.&lt;/li&gt;
&lt;li&gt;The offline runtime is useful only when it reconstructs the VM image, context, handler semantics, and observed traffic behavior. A single hook return value is not enough.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;The reading path has four parts. First, we straighten the call chain. Then we explain how the VM image and context are initialized. After that, we recover instruction decoding and the CFG-obfuscated runner. Finally, we reduce the evidence into an offline runtime and a version-migration method.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Keywords And Terms&lt;a href=&quot;#keywords-and-terms&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Term&lt;/th&gt;&lt;th&gt;Meaning&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;WeChat&lt;/td&gt;&lt;td&gt;The client environment where the RQTX path is observed.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;RQTX&lt;/td&gt;&lt;td&gt;A protected computation path in the request chain.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;IRVMP&lt;/td&gt;&lt;td&gt;Instruction-level virtual machine protection used by the RQTX path.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;rqtx.dat&lt;/td&gt;&lt;td&gt;A VM data file carrying the opcode map, payload image, and relocation slots.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;CFG deobfuscation&lt;/td&gt;&lt;td&gt;Block coverage, dispatcher stripping, and semantic recovery for a flattened native runner.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;IDA Pro / Frida&lt;/td&gt;&lt;td&gt;Static analysis and dynamic instrumentation tools used for proof and validation.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Related articles are collected in the &lt;a href=&quot;/en/topics/wechat-rqtx-irvmp/&quot;&gt;WeChat RQTX IRVMP Research Index&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;RQTX is difficult because several protection layers are stacked together:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;the upper layer is an Objective-C selector that provides a stable business entry;&lt;/li&gt;
&lt;li&gt;the middle layer contains native stages that are flattened by CFG and are responsible for object construction, runtime handles, entry parsing, and bridging;&lt;/li&gt;
&lt;li&gt;the lower layer is an IRVMP runner that interprets &lt;code&gt;rqtx.dat&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;the data layer includes an opcode map, payload image, relocation slots, and VM context;&lt;/li&gt;
&lt;li&gt;the dynamic-analysis layer must handle ASLR, thread noise, hot-path overhead, and watchdog or re-entry behavior.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;For this kind of target, reading one pseudo-code fragment and making a conclusion is risky. The recovery method should make every conclusion falsifiable: the static address should match, the dynamic path should be hit, the VM state should explain the behavior, and the offline runtime should reproduce the observed result. Anything that cannot pass that bar stays marked as unknown.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Overall Path&lt;a href=&quot;#overall-path&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The first object to recover is the live path. Without it, every later statement about &lt;code&gt;rqtx.dat&lt;/code&gt;, VM context, or the runner is floating. With it, the high-level selector, body wrapper, bridge, and VM runner can be placed on the same graph.&lt;/p&gt;&lt;p&gt;The live path can be summarized as:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;WCCalRqtDataMgr&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- calRqtData:len:cmd:uin:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; slot dispatcher / wrapper&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; rqtx_md5_body_dispatch&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; rqtx_calc_stage_dispatch&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; rqtx_vm_bridge&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; rqtx_vm_runner_flat&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;              &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&amp;gt; rqtx.dat + VM context + opcode map&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The slot chain is not a single jump. After the &lt;code&gt;calRqtData&lt;/code&gt; layer loads the slot, the analysis still needs to follow a thunk chain through several wrappers before reaching the body dispatch stage. Stopping at the first dispatcher makes the wrapper look like the algorithm, which is the wrong boundary.&lt;/p&gt;&lt;p&gt;The role table is more important than the raw address values:&lt;/p&gt;




























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Role&lt;/th&gt;&lt;th&gt;Purpose&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;ObjC anchor&lt;/td&gt;&lt;td&gt;Stable top-level selector for the request-chain entry.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;body wrapper&lt;/td&gt;&lt;td&gt;Accepts the normalized input and enters the RQTX computation path.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;calc stage&lt;/td&gt;&lt;td&gt;Checks the runtime handle and parses entry-like fields.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;VM bridge&lt;/td&gt;&lt;td&gt;Loads the blob/context and initializes VM registers.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;VM runner&lt;/td&gt;&lt;td&gt;Executes the IRVMP instruction stream with heavy CFG flattening.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;IRVMP Design Model&lt;a href=&quot;#irvmp-design-model&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The entry and slot chain answer “where does execution go?” The next question is “why does the code not look like a normal native algorithm after we arrive there?” The answer is the IRVMP layering.&lt;/p&gt;&lt;p&gt;The RQTX IRVMP can be understood as five layers.&lt;/p&gt;&lt;p&gt;The first layer is the packaged VM image. The core logic is not simply hard-coded inside a native function. It is expressed by a VM image carried by &lt;code&gt;rqtx.dat&lt;/code&gt;, and the native runner interprets that image.&lt;/p&gt;&lt;p&gt;The second layer is an objectized runtime. &lt;code&gt;rqtx.dat&lt;/code&gt; is not executed as a raw file. It passes through global initialization, provider or handle management, blob getters, and context getters before it becomes the runtime object used by the bridge.&lt;/p&gt;&lt;p&gt;The third layer is VM context. Each bridge call prepares a context buffer that contains a register file, IP, next IP, VM state slots, and memory-window pointers.&lt;/p&gt;&lt;p&gt;The fourth layer is IP-aware instruction decoding. Opcode extraction is not merely &lt;code&gt;word &amp;gt;&amp;gt; 26&lt;/code&gt;. The decoder mixes the current IP and the opcode map. Register fields are also XOR-obfuscated.&lt;/p&gt;&lt;p&gt;The fifth layer is native runner obfuscation. The interpreter itself is flattened by CFG and contains a main dispatcher, sub-dispatchers, selector state, and shared tails.&lt;/p&gt;&lt;p&gt;These layers create a typical protected target: static analysis cannot see the whole algorithm, dynamic trace is noisy, and dumped data cannot run directly unless relocation and context are reconstructed.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;rqtx.dat Layout&lt;a href=&quot;#rqtxdat-layout&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;After the model is clear, the bottom layer is the VM image. &lt;code&gt;rqtx.dat&lt;/code&gt; carries the VM data and the protected logic. If this layout cannot be explained, the later init, decode, and runtime recovery have no stable foundation.&lt;/p&gt;&lt;p&gt;The recovered model treats &lt;code&gt;rqtx.dat&lt;/code&gt; as a packaged image:&lt;/p&gt;
























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Region&lt;/th&gt;&lt;th&gt;Purpose&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;opcode map&lt;/td&gt;&lt;td&gt;Deobfuscates instruction opcode values.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;payload image&lt;/td&gt;&lt;td&gt;Holds VM instruction words and embedded data.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;relocation/export slots&lt;/td&gt;&lt;td&gt;Connect the packaged image to runtime pointers and bridge state.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;internal VM blocks&lt;/td&gt;&lt;td&gt;Provide control-flow and handler-level data used by the runner.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;The important observation is that the native runner and the VM image are coupled. A dump of the file is useful only after the loader relationship is understood: which bytes are copied, which pointers are rewritten, and which slots are interpreted as runtime state.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;VM Initialization&lt;a href=&quot;#vm-initialization&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The initialization stage turns a data file into a runtime object. The useful proof is not just “this function touches the file.” The proof is a sequence:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;A global initialization path obtains or constructs the RQTX provider.&lt;/li&gt;
&lt;li&gt;A handle-like object is used by later calculation stages.&lt;/li&gt;
&lt;li&gt;The VM bridge asks for a blob and a context.&lt;/li&gt;
&lt;li&gt;The context gets filled with register and memory-window state.&lt;/li&gt;
&lt;li&gt;The runner receives the context and begins interpreting payload instructions.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;In practice, the init path should be verified from both directions. Static analysis gives the object graph and field offsets. Dynamic instrumentation confirms that the same fields are read and written during a live call. When those two views agree, the layout becomes reliable enough for offline reconstruction.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;VM Context&lt;a href=&quot;#vm-context&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The VM context is the boundary between native code and the virtual machine. It is where VM registers, IP, state slots, memory windows, and temporary buffers become observable.&lt;/p&gt;&lt;p&gt;A useful context model separates fields by behavior:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;VmContext&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;registers[...]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ip&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;next_ip&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;state_slots[...]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;memory_windows[...]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;bridge_input&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;bridge_output&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The field names are not guessed from a single snapshot. They are assigned after repeated calls show stable read/write behavior. For example, a field that advances with every decoded instruction is an IP candidate. A field that is read by memory-like handlers and points into the staged input is a memory-window candidate. A field that receives the final short integer is an output slot candidate.&lt;/p&gt;&lt;p&gt;This is also where dynamic trace becomes useful. It does not need to record every native instruction. It needs to show which context fields change at block boundaries and which changes are correlated with input staging, loop execution, or final output.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Instruction Encoding&lt;a href=&quot;#instruction-encoding&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The RQTX VM instruction word is not decoded by a plain fixed-format table. The high bits, register fields, immediate fields, current IP, and opcode map all participate.&lt;/p&gt;&lt;p&gt;The recovery model uses four public-facing formats:&lt;/p&gt;&lt;section&gt;&lt;h3&gt;I-format&lt;a href=&quot;#i-format&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;I-format instructions carry register operands and a short immediate. They are useful for identifying arithmetic, memory access, and small control operations.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;R-format&lt;a href=&quot;#r-format&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;R-format instructions carry multiple register fields. These are the best candidates for arithmetic and state-mixing handlers.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;19-bit Immediate&lt;a href=&quot;#19-bit-immediate&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The 19-bit immediate form is useful for medium-size constants or offsets. It appears when the VM needs more than the small immediate but does not need a full branch target.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;26-bit Branch&lt;a href=&quot;#26-bit-branch&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The branch form carries a larger control-flow target. It is the main format used when rebuilding the VM-level CFG.&lt;/p&gt;&lt;p&gt;The key point is that instruction format is not enough. The opcode still needs deobfuscation. The same raw shape can mean different things once IP-aware mapping is applied.&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Instruction Semantics&lt;a href=&quot;#instruction-semantics&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Instruction semantics should be recovered from handler behavior, not from names assigned too early.&lt;/p&gt;&lt;p&gt;A stable workflow is:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;Decode a candidate instruction word.&lt;/li&gt;
&lt;li&gt;Identify which handler block the native runner enters.&lt;/li&gt;
&lt;li&gt;Trace context reads and writes around that handler.&lt;/li&gt;
&lt;li&gt;Compare the behavior with a small set of semantic templates: move, add, xor, rotate, load, store, branch, compare, call-like transition.&lt;/li&gt;
&lt;li&gt;Add the handler to the offline runtime only after repeated samples agree.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;This is slower than naming everything from pseudo-code, but it avoids a common failure: one misleading Hex-Rays expression can create a wrong handler, and then every later algorithm-level conclusion is built on it.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Runner Execution Model&lt;a href=&quot;#runner-execution-model&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The runner is an interpreter hidden inside flattened native code. The useful mental model is:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;while running:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;raw_word = load(ip)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;opcode = decode(raw_word, ip, opcode_map)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;handler = dispatch(opcode)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;handler(context, raw_word)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ip = context.next_ip&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The real implementation is less clean. Dispatch state can be encoded in selector variables, multiple tails can be shared, and IP updates can be split across blocks. Still, the interpreter model gives us a target shape. Every recovered block should eventually fit into decode, dispatch, handler, or next-IP update.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;CFG Flattening&lt;a href=&quot;#cfg-flattening&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;CFG flattening makes the native runner look like a dense loop of selector updates. The recovery goal is not to produce beautiful native pseudo-code. It is to strip away the dispatcher skeleton until handler boundaries become visible.&lt;/p&gt;&lt;p&gt;The practical method is:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;collect dynamic block coverage under controlled inputs;&lt;/li&gt;
&lt;li&gt;identify the main dispatcher and sub-dispatcher states;&lt;/li&gt;
&lt;li&gt;remove common tails and selector plumbing from the analysis view;&lt;/li&gt;
&lt;li&gt;group blocks that always appear together as handler candidates;&lt;/li&gt;
&lt;li&gt;compare the grouped behavior with context diffs.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Once this is done, the runner stops looking like one giant function and starts looking like a table of VM handlers.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;No-CFG Recovery&lt;a href=&quot;#no-cfg-recovery&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The no-CFG view is a cleaned control-flow skeleton. It is not a recompiled program and should not be treated as one. It is an analysis view that keeps semantic blocks and removes dispatcher noise.&lt;/p&gt;&lt;p&gt;The value of this view is speed. It allows the analyst to ask simple questions:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;which block loads the next VM word;&lt;/li&gt;
&lt;li&gt;which block reads the opcode map;&lt;/li&gt;
&lt;li&gt;which block writes output;&lt;/li&gt;
&lt;li&gt;which block updates IP;&lt;/li&gt;
&lt;li&gt;which blocks only move selector state.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;That separation is enough to drive the offline runtime implementation.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Deep Runner Localization&lt;a href=&quot;#deep-runner-localization&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Two heuristics are especially useful when the runner is buried behind wrappers.&lt;/p&gt;&lt;section&gt;&lt;h3&gt;timestamp-wrapper heuristic&lt;a href=&quot;#timestamp-wrapper-heuristic&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Wrapper code often touches timing, watchdog, or bookkeeping state around the real work. The useful signal is not the timestamp itself. The signal is that a wrapper has a stable before/after shape around a deeper call that consumes the VM context.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;effective-call-list ranking&lt;a href=&quot;#effective-call-list-ranking&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Instead of ranking callees by static size, rank them by runtime effect: context mutation, blob access, IP movement, output write, and repeated presence under live calls. The runner scores highly because it changes the VM state in a dense and repeated way.&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Live Body&lt;a href=&quot;#live-body&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The live body stage connects the top-level request path with the VM. It receives normalized input, enters the RQTX calculation chain, and eventually produces the short result.&lt;/p&gt;&lt;p&gt;This boundary is important because it prevents two mistakes:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;treating request normalization as the protected algorithm itself;&lt;/li&gt;
&lt;li&gt;treating a low-level VM block as the public API boundary.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;The live body gives the offline runtime its external contract: normalized input in, short RQTX value out.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Recovery Workflow&lt;a href=&quot;#recovery-workflow&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;Entry Adaptation&lt;a href=&quot;#entry-adaptation&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Start with the stable business entry, follow the slot chain, and stop at the body wrapper that actually enters the RQTX calculation stage. Use dynamic hits to prove that the static chain is not a dead path.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;CFG Recovery&lt;a href=&quot;#cfg-recovery&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Use dynamic coverage to identify dispatcher blocks, shared tails, handler groups, and IP update blocks. Do not try to make the flattened native function look natural before handler behavior is known.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Runtime Reconstruction&lt;a href=&quot;#runtime-reconstruction&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Rebuild only what has been proven:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;packaged VM image loader;&lt;/li&gt;
&lt;li&gt;opcode map usage;&lt;/li&gt;
&lt;li&gt;context fields with stable behavior;&lt;/li&gt;
&lt;li&gt;instruction decoder;&lt;/li&gt;
&lt;li&gt;handler semantics;&lt;/li&gt;
&lt;li&gt;bridge input and output boundary.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;The offline runtime should be allowed to start incomplete. It becomes reliable as more handler tests and live-vector comparisons pass.&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Difficult Cases&lt;a href=&quot;#difficult-cases&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;1. Hex-Rays Pseudo-code Is Not Direct Evidence&lt;a href=&quot;#1-hex-rays-pseudo-code-is-not-direct-evidence&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Pseudo-code is a navigation aid. For flattened runners, it can merge unrelated selector states or hide real state changes. Use it to find candidates, then verify with traces.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;2. Hot-path Instrumentation Can Change Behavior&lt;a href=&quot;#2-hot-path-instrumentation-can-change-behavior&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Heavy instrumentation can slow the runner, alter timing, or trigger watchdog paths. Keep probes narrow and move from native-instruction tracing to block-level or context-diff tracing as early as possible.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;3. Watchdog And Re-entry Noise&lt;a href=&quot;#3-watchdog-and-re-entry-noise&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Repeated calls may include bookkeeping or re-entry paths that do not belong to the algorithm. Separate “called during the request” from “semantically required for the result.”&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;4. Version Address Drift&lt;a href=&quot;#4-version-address-drift&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Addresses drift between versions. Layout relationships, object roles, and dynamic behavior are more portable than raw addresses.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;5. Relocation Differences&lt;a href=&quot;#5-relocation-differences&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;A dump that looks byte-identical may still fail if relocation slots or runtime pointers are reconstructed incorrectly. Treat relocation as part of the VM image, not as external noise.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;6. Observed Mode Is Not Full Coverage&lt;a href=&quot;#6-observed-mode-is-not-full-coverage&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Observed behavior proves the executed path, not the whole VM. Mark unobserved handlers and branches as incomplete until they are hit or explained by another proof.&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Offline Runtime&lt;a href=&quot;#offline-runtime&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The offline runtime is the final integration point. It should not be a pile of copied pseudo-code. It should look like a small interpreter:&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;load_image(rqtx_dat)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;build_context(input)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;while context.running:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;instruction = decode(image, context.ip)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;execute(instruction, context)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;return context.output&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The runtime has three jobs:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;reproduce observed behavior;&lt;/li&gt;
&lt;li&gt;make handler semantics testable;&lt;/li&gt;
&lt;li&gt;serve as a version-migration oracle.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;It is acceptable for the runtime to contain unknown handlers during early recovery. What matters is that the known handlers are named, tested, and tied back to trace evidence.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Version Migration&lt;a href=&quot;#version-migration&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Version migration should start from the previous evidence chain:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;find the new stable entry;&lt;/li&gt;
&lt;li&gt;re-follow the slot chain;&lt;/li&gt;
&lt;li&gt;re-prove the body wrapper;&lt;/li&gt;
&lt;li&gt;rebuild the VM init and context layout;&lt;/li&gt;
&lt;li&gt;compare &lt;code&gt;rqtx.dat&lt;/code&gt; image structure;&lt;/li&gt;
&lt;li&gt;re-rank runner candidates by dynamic effect;&lt;/li&gt;
&lt;li&gt;port handler semantics only after decode and context behavior match.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;This approach avoids the most fragile migration pattern: copying addresses from one version into another and hoping the structure stayed identical.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;Review&lt;a href=&quot;#review&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The main lesson is that RQTX IRVMP recovery is not a single trick. It is a layered reconstruction problem. The useful output is not “we hooked the return value.” The useful output is a model where entry, data image, context, instruction decode, runner behavior, and offline verification all support each other.&lt;/p&gt;&lt;p&gt;That model also makes the next article possible: once the runtime can be observed and replayed, the next step is to lift the VM behavior into a semantic algorithm that can be compared with standard hashing structures.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;FAQ&lt;a href=&quot;#faq&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;What is RQTX?&lt;a href=&quot;#what-is-rqtx&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;RQTX is a protected computation path in the WeChat request chain. In the analyzed path, it takes normalized request-related input and produces a short integer used by the request-side verification flow.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;What is the core protection point of WeChat RQTX IRVMP?&lt;a href=&quot;#what-is-the-core-protection-point-of-wechat-rqtx-irvmp&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The core protection is the combination of a packaged VM image, IP-aware instruction decoding, objectized runtime context, and a CFG-flattened native interpreter.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;What does rqtx.dat contain?&lt;a href=&quot;#what-does-rqtxdat-contain&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The recovered model treats &lt;code&gt;rqtx.dat&lt;/code&gt; as a packaged VM image that contains the opcode map, payload image, relocation/export slots, and internal VM blocks.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;How can the VM runner be located?&lt;a href=&quot;#how-can-the-vm-runner-be-located&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Start from the stable entry, follow the wrapper chain, identify the bridge, then rank candidate callees by runtime effect: context mutation, VM image access, IP movement, and output writes.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Why is Hex-Rays F5 pseudo-code not enough?&lt;a href=&quot;#why-is-hex-rays-f5-pseudo-code-not-enough&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Flattened control flow can make pseudo-code merge dispatcher state with real handler logic. It is useful for navigation, but handler semantics must be verified with dynamic traces and context diffs.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;How does this method migrate to a newer WeChat version?&lt;a href=&quot;#how-does-this-method-migrate-to-a-newer-wechat-version&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Migrate the evidence chain instead of raw addresses. Re-prove the entry, slot chain, VM init, context layout, image structure, runner behavior, and handler decode relationship for the new version.&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item></channel></rss>