ARZL: Difference between revisions

From Vita Development Wiki
Jump to navigation Jump to search
 
No edit summary
Line 1: Line 1:
ARZL is a (standard ?) compressed format which is used by the [[Boot Sequence|secure bootloader]] to load the non-secure bootloader and the secure kernel.
ARZL is a (standard ?) compression format used for example by the [[Boot Sequence|secure kernel bootloader]] to load the non-secure kernel bootloader and the secure kernel. It is also used by /sce_sys/right/right.suprx for embedding GIM texture data.
 
== Header ==
 
It is simply the string "ARZL" (41 52 5A 4C).


== Obfuscation ==
== Obfuscation ==

Revision as of 17:01, 28 August 2018

ARZL is a (standard ?) compression format used for example by the secure kernel bootloader to load the non-secure kernel bootloader and the secure kernel. It is also used by /sce_sys/right/right.suprx for embedding GIM texture data.

Header

It is simply the string "ARZL" (41 52 5A 4C).

Obfuscation

The raw decompressed ARZL output is obfuscated. Although there are three versions of the obfuscation, the basic operation is the same. The obfuscation is just bit swaps as well as some deterministic changes using information from the offset.

int arzl_deobfuscate(unsigned char *buffer, int len)
{
  unsigned char *buf, *bufend;
  uint32_t data;
  int change_stride;

  buf = buffer;
  bufend = &buffer[len];

  do
  {
    data = *(uint32_t *)buf;
    buf += 4;
    change_stride = (data & 0xF800F800) >> 27;
    if ( (data & 0xF800F800) == 0xF800F000 )
    {
      data = (((data >> 16) & 0xFFC007FF) | ((data & 0x7FF) << 11)) - ((buf - buffer) >> 1);
      *((uint32_t *)buf - 1) = ((((data & 0x7FF) << 16) | 0xF800F000) & 0xFFFFF800) | ((data >> 11) & 0x7FF);
    }
    else if ( change_stride == 30 )
    {
      buf -= 2;
    }
  }
  while ( bufend > buf );
}

Version 1

The only change is that the offset information is added instead of subtracted.

data = (((data >> 16) & 0xFFC007FF) | ((data & 0x7FF) << 11)) + ((buf - buffer) >> 1);

Version 2

Version 2 is the same as version 0 but in addition, there's an additional operation to swap two nibbles in certain conditions. The condition is found through a learning process and may be overfitted.

      else if ( (data & 0x8000FBF0) == 0x0000F2C0 )
      {
        data = (data & 0xF0FFFFF0) | ((data & 0xF) << 24) | ((data >> 24) & 0xF);
        *((uint32_t *)buf - 1) = data;
      }