In memory of Ben “bushing” Byer, who passed away on Monday, February 8th, 2016.

Difference between revisions of "WiiPax"

From WiiBrew
Jump to navigation Jump to search
(→‎Obfuscation REing: details on the algorithm for closed source (haven't figured out key generation yet))
(→‎Closed source unpacking algorithm: documented value key generation)
Line 10: Line 10:
 
The standalone version copies itself to MEM2, and has a total of 33 functions (3662 instructions).
 
The standalone version copies itself to MEM2, and has a total of 33 functions (3662 instructions).
  
Through an unknown algorithm, 3 keys are generated: an index key (32-bit entries), a value key (32-bit entries), and a finalization value key (8-bit entries).
+
=== Key generation ===
 +
3 keys exist: an index key (32-bit entries), a value key (32-bit entries), and a finalization value key (8-bit entries).
  
 +
The value key is generated by first building a two-way lookup table for a function that leftshifts a byte by one bit and XORs the result with 0x1B if the removed bit is 1. Another two-way lookup table is then built where each value is obtained by finding <code>lookup1[255 - inverseLookup1[index]]</code> and XORing the result with the result leftrotated 1, 2, 3, and 4 bits, as well as the constant 99. Finally, each entry in the value key is the joining of 4 bytes, each of which is found by applying a function where the first argument is the respective value in (11, 13, 9, 14), and the second argument is the reverse lookup in the second table. This function performs a reverse lookup in the first table on both arguments, then adds the two results together and performs a division-like operation, before looking up the result in forward table 1.
 +
 +
=== Unpacking ===
 
For each 16-byte chunk of the ciphertext, the 16 bytes are XORed with the first 16 bytes of the index key. Then, a transformation is repeated 10 times where each word is mapped to <code>indexKey[4 + 4*transformationIteration + index] ^ valueKey[preimage[4*index]] ^ (valueKey[preimage[4*C]] r<< 24) ^ (valueKey[preimage[4*A+2]] r<< 8) ^ (valueKey[preimage[4*B+1]] r<< 16)</code> (the array (A,B,C) rotates between (3,2,1), (0,3,2), (1,0,3), and (2,1,0) to reduce consistency). Finally, each word in the ciphertext is mapped to <code>indexKey[44 + index] ^ finalizationValueKey[preimage[index]] ^ (finalizationValueKey[preimage[4*C]] << 24) ^ (finalizationValueKey[preimage[4*A+2]] << 8) ^ (finalizationValueKey[preimage[4*C+1]] << 16)</code>.
 
For each 16-byte chunk of the ciphertext, the 16 bytes are XORed with the first 16 bytes of the index key. Then, a transformation is repeated 10 times where each word is mapped to <code>indexKey[4 + 4*transformationIteration + index] ^ valueKey[preimage[4*index]] ^ (valueKey[preimage[4*C]] r<< 24) ^ (valueKey[preimage[4*A+2]] r<< 8) ^ (valueKey[preimage[4*B+1]] r<< 16)</code> (the array (A,B,C) rotates between (3,2,1), (0,3,2), (1,0,3), and (2,1,0) to reduce consistency). Finally, each word in the ciphertext is mapped to <code>indexKey[44 + index] ^ finalizationValueKey[preimage[index]] ^ (finalizationValueKey[preimage[4*C]] << 24) ^ (finalizationValueKey[preimage[4*A+2]] << 8) ^ (finalizationValueKey[preimage[4*C+1]] << 16)</code>.
  
 
After this algorithm is applied to individual chunks, the state is XORed with the plaintext from 1 or 2 chunks before depending on the WiiPax version.
 
After this algorithm is applied to individual chunks, the state is XORed with the plaintext from 1 or 2 chunks before depending on the WiiPax version.

Revision as of 06:07, 5 September 2022

WiiPax
General
Author(s)fail0verflow
TypePC utility
Version0.2
Links
Source

WiiPax is the tool used to obfuscate the Homebrew Channel, CEIL1NG_CAT, and the HackMii Installer. The open source version uses LZMA to compress ELF files, with a loader stub added to decompress it.

Closed source unpacking algorithm

The standalone version copies itself to MEM2, and has a total of 33 functions (3662 instructions).

Key generation

3 keys exist: an index key (32-bit entries), a value key (32-bit entries), and a finalization value key (8-bit entries).

The value key is generated by first building a two-way lookup table for a function that leftshifts a byte by one bit and XORs the result with 0x1B if the removed bit is 1. Another two-way lookup table is then built where each value is obtained by finding lookup1[255 - inverseLookup1[index]] and XORing the result with the result leftrotated 1, 2, 3, and 4 bits, as well as the constant 99. Finally, each entry in the value key is the joining of 4 bytes, each of which is found by applying a function where the first argument is the respective value in (11, 13, 9, 14), and the second argument is the reverse lookup in the second table. This function performs a reverse lookup in the first table on both arguments, then adds the two results together and performs a division-like operation, before looking up the result in forward table 1.

Unpacking

For each 16-byte chunk of the ciphertext, the 16 bytes are XORed with the first 16 bytes of the index key. Then, a transformation is repeated 10 times where each word is mapped to indexKey[4 + 4*transformationIteration + index] ^ valueKey[preimage[4*index]] ^ (valueKey[preimage[4*C]] r<< 24) ^ (valueKey[preimage[4*A+2]] r<< 8) ^ (valueKey[preimage[4*B+1]] r<< 16) (the array (A,B,C) rotates between (3,2,1), (0,3,2), (1,0,3), and (2,1,0) to reduce consistency). Finally, each word in the ciphertext is mapped to indexKey[44 + index] ^ finalizationValueKey[preimage[index]] ^ (finalizationValueKey[preimage[4*C]] << 24) ^ (finalizationValueKey[preimage[4*A+2]] << 8) ^ (finalizationValueKey[preimage[4*C+1]] << 16).

After this algorithm is applied to individual chunks, the state is XORed with the plaintext from 1 or 2 chunks before depending on the WiiPax version.