Kodewerx
http://www.kodewerx.org/forum/

GBA AR code encryption
http://www.kodewerx.org/forum/viewtopic.php?f=11&t=6814
Page 1 of 1

Author:  Parasyte [ Sat Jun 06, 2009 4:00 pm ]
Post subject:  GBA AR code encryption

This was brought up recently, so I thought I would [re]share the GBA AR code encryption algorithms. It's fairly simple, but tricky enough to obfuscate the address and data. Here's the C code I wrote back in December 2001 for a program called GBAcrypt. The program was eventually forgotten, as bigger and better programs were released which did even better things than just simple code encryption and decryption.

However, this information is still relevant. So here we go!

To initialize the encryption seeds, run:
Code:
deadface(0);


Then just run your codes through encrypt_code() or decrypt_code().

Code:
/* GBAcrypt - Gameboy Advance AR Crypto Program
 *
 * Copyright notice for this file:
 *  Copyright (C) 2001 Parasyte
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

unsigned long seeds[4];
unsigned int deadtable1[256] = {
   0x31, 0x1C, 0x23, 0xE5, 0x89, 0x8E, 0xA1, 0x37,
   0x74, 0x6D, 0x67, 0xFC, 0x1F, 0xC0, 0xB1, 0x94,
   0x3B, 0x05, 0x56, 0x86, 0x00, 0x24, 0xF0, 0x17,
   0x72, 0xA2, 0x3D, 0x1B, 0xE3, 0x17, 0xC5, 0x0B,
   0xB9, 0xE2, 0xBD, 0x58, 0x71, 0x1B, 0x2C, 0xFF,
   0xE4, 0xC9, 0x4C, 0x5E, 0xC9, 0x55, 0x33, 0x45,
   0x7C, 0x3F, 0xB2, 0x51, 0xFE, 0x10, 0x7E, 0x75,
   0x3C, 0x90, 0x8D, 0xDA, 0x94, 0x38, 0xC3, 0xE9,
   0x95, 0xEA, 0xCE, 0xA6, 0x06, 0xE0, 0x4F, 0x3F,
   0x2A, 0xE3, 0x3A, 0xE4, 0x43, 0xBD, 0x7F, 0xDA,
   0x55, 0xF0, 0xEA, 0xCB, 0x2C, 0xA8, 0x47, 0x61,
   0xA0, 0xEF, 0xCB, 0x13, 0x18, 0x20, 0xAF, 0x3E,
   0x4D, 0x9E, 0x1E, 0x77, 0x51, 0xC5, 0x51, 0x20,
   0xCF, 0x21, 0xF9, 0x39, 0x94, 0xDE, 0xDD, 0x79,
   0x4E, 0x80, 0xC4, 0x9D, 0x94, 0xD5, 0x95, 0x01,
   0x27, 0x27, 0xBD, 0x6D, 0x78, 0xB5, 0xD1, 0x31,
   0x6A, 0x65, 0x74, 0x74, 0x58, 0xB3, 0x7C, 0xC9,
   0x5A, 0xED, 0x50, 0x03, 0xC4, 0xA2, 0x94, 0x4B,
   0xF0, 0x58, 0x09, 0x6F, 0x3E, 0x7D, 0xAE, 0x7D,
   0x58, 0xA0, 0x2C, 0x91, 0xBB, 0xE1, 0x70, 0xEB,
   0x73, 0xA6, 0x9A, 0x44, 0x25, 0x90, 0x16, 0x62,
   0x53, 0xAE, 0x08, 0xEB, 0xDC, 0xF0, 0xEE, 0x77,
   0xC2, 0xDE, 0x81, 0xE8, 0x30, 0x89, 0xDB, 0xFE,
   0xBC, 0xC2, 0xDF, 0x26, 0xE9, 0x8B, 0xD6, 0x93,
   0xF0, 0xCB, 0x56, 0x90, 0xC0, 0x46, 0x68, 0x15,
   0x43, 0xCB, 0xE9, 0x98, 0xE3, 0xAF, 0x31, 0x25,
   0x4D, 0x7B, 0xF3, 0xB1, 0x74, 0xE2, 0x64, 0xAC,
   0xD9, 0xF6, 0xA0, 0xD5, 0x0B, 0x9B, 0x49, 0x52,
   0x69, 0x3B, 0x71, 0x00, 0x2F, 0xBB, 0xBA, 0x08,
   0xB1, 0xAE, 0xBB, 0xB3, 0xE1, 0xC9, 0xA6, 0x7F,
   0x17, 0x97, 0x28, 0x72, 0x12, 0x6E, 0x91, 0xAE,
   0x3A, 0xA2, 0x35, 0x46, 0x27, 0xF8, 0x12, 0x50
};
unsigned int deadtable2[256] = {
   0xD8, 0x65, 0x04, 0xC2, 0x65, 0xD5, 0xB0, 0x0C,
   0xDF, 0x9D, 0xF0, 0xC3, 0x9A, 0x17, 0xC9, 0xA6,
   0xE1, 0xAC, 0x0D, 0x14, 0x2F, 0x3C, 0x2C, 0x87,
   0xA2, 0xBF, 0x4D, 0x5F, 0xAC, 0x2D, 0x9D, 0xE1,
   0x0C, 0x9C, 0xE7, 0x7F, 0xFC, 0xA8, 0x66, 0x59,
   0xAC, 0x18, 0xD7, 0x05, 0xF0, 0xBF, 0xD1, 0x8B,
   0x35, 0x9F, 0x59, 0xB4, 0xBA, 0x55, 0xB2, 0x85,
   0xFD, 0xB1, 0x72, 0x06, 0x73, 0xA4, 0xDB, 0x48,
   0x7B, 0x5F, 0x67, 0xA5, 0x95, 0xB9, 0xA5, 0x4A,
   0xCF, 0xD1, 0x44, 0xF3, 0x81, 0xF5, 0x6D, 0xF6,
   0x3A, 0xC3, 0x57, 0x83, 0xFA, 0x8E, 0x15, 0x2A,
   0xA2, 0x04, 0xB2, 0x9D, 0xA8, 0x0D, 0x7F, 0xB8,
   0x0F, 0xF6, 0xAC, 0xBE, 0x97, 0xCE, 0x16, 0xE6,
   0x31, 0x10, 0x60, 0x16, 0xB5, 0x83, 0x45, 0xEE,
   0xD7, 0x5F, 0x2C, 0x08, 0x58, 0xB1, 0xFD, 0x7E,
   0x79, 0x00, 0x34, 0xAD, 0xB5, 0x31, 0x34, 0x39,
   0xAF, 0xA8, 0xDD, 0x52, 0x6A, 0xB0, 0x60, 0x35,
   0xB8, 0x1D, 0x52, 0xF5, 0xF5, 0x30, 0x00, 0x7B,
   0xF4, 0xBA, 0x03, 0xCB, 0x3A, 0x84, 0x14, 0x8A,
   0x6A, 0xEF, 0x21, 0xBD, 0x01, 0xD8, 0xA0, 0xD4,
   0x43, 0xBE, 0x23, 0xE7, 0x76, 0x27, 0x2C, 0x3F,
   0x4D, 0x3F, 0x43, 0x18, 0xA7, 0xC3, 0x47, 0xA5,
   0x7A, 0x1D, 0x02, 0x55, 0x09, 0xD1, 0xFF, 0x55,
   0x5E, 0x17, 0xA0, 0x56, 0xF4, 0xC9, 0x6B, 0x90,
   0xB4, 0x80, 0xA5, 0x07, 0x22, 0xFB, 0x22, 0x0D,
   0xD9, 0xC0, 0x5B, 0x08, 0x35, 0x05, 0xC1, 0x75,
   0x4F, 0xD0, 0x51, 0x2D, 0x2E, 0x5E, 0x69, 0xE7,
   0x3B, 0xC2, 0xDA, 0xFF, 0xF6, 0xCE, 0x3E, 0x76,
   0xE8, 0x36, 0x8C, 0x39, 0xD8, 0xF3, 0xE9, 0xA6,
   0x42, 0xE6, 0xC1, 0x4C, 0x05, 0xBE, 0x17, 0xF2,
   0x5C, 0x1B, 0x19, 0xDB, 0x0F, 0xF3, 0xF8, 0x49,
   0xEB, 0x36, 0xF6, 0x40, 0x6F, 0xAD, 0xC1, 0x8C
};

void decrypt_code(unsigned long *address, unsigned long *value) {
   unsigned long rollingseed = 0xC6EF3720;
   int bitsleft = 32;
   while (bitsleft > 0) {
      *value -= ((((*address << 4) + seeds[2]) ^ (*address + rollingseed)) ^ ((*address >> 5) + seeds[3]));
      *address -= ((((*value << 4) + seeds[0]) ^ (*value + rollingseed)) ^ ((*value >> 5) + seeds[1]));
      rollingseed -= 0x9E3779B9;
      bitsleft--;
   }
   if (*address == 0xDEADFACE) deadface(*value);
}

void encrypt_code(unsigned long *address, unsigned long *value) {
   unsigned long rollingseed = 0, oldaddr, oldval;
   int bitsleft = 32;

   oldaddr = *address;
   oldval = *value;

   while (bitsleft > 0) {
      rollingseed += 0x9E3779B9;
      *address += ((((*value << 4) + seeds[0]) ^ (*value + rollingseed)) ^ ((*value >> 5) + seeds[1]));
      *value += ((((*address << 4) + seeds[2]) ^ (*address + rollingseed)) ^ ((*address >> 5) + seeds[3]));
      bitsleft--;
   }
   if (oldaddr == 0xDEADFACE) deadface(oldval);
}

void deadface(unsigned long value) {
   int i, rollingseed;

   rollingseed = (value & 0xFF);
   for (i = 0; i < 4; i++) {
      seeds[i] = seed_gen(((value & 0xFF00) >> 8), rollingseed);
      rollingseed++;
   }
   printf("Encryption Seeds Have Changed!\n");
}

unsigned long seed_gen(int upper, int seed) {
   unsigned long newseed;
   int pass = 0;

   while (pass < 4) {
      newseed = (newseed << 8) | ((deadtable1[((pass + upper) & 0xFF)] + deadtable2[(seed & 0xFF)]) & 0xFF);
      pass++;
   }
   return newseed;
}

Author:  Parasyte [ Sat Jun 06, 2009 4:11 pm ]
Post subject:  Re: GBA AR code encryption

Update: In 2003, I modified the code to support AR v3.

Usage is similar, but a variable was added that changes the algorithm between AR v1 and AR v3.

Code:
v3enc = 0; // Use AR v1 algorithm

Code:
v3enc = 1; // Use AR v3 algorithm


Code:
/* GSAcrypt - Gameboy Advance AR Crypto Program
 *
 * Copyright notice for this file:
 *  Copyright (C) 2001-2003 Parasyte
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;


u32 seeds[4];
u8 v3enc;

//seed tables for AR v1
u8 v1_deadtable1[256] = {
   0x31, 0x1C, 0x23, 0xE5, 0x89, 0x8E, 0xA1, 0x37, 0x74, 0x6D, 0x67, 0xFC, 0x1F, 0xC0, 0xB1, 0x94,
   0x3B, 0x05, 0x56, 0x86, 0x00, 0x24, 0xF0, 0x17, 0x72, 0xA2, 0x3D, 0x1B, 0xE3, 0x17, 0xC5, 0x0B,
   0xB9, 0xE2, 0xBD, 0x58, 0x71, 0x1B, 0x2C, 0xFF, 0xE4, 0xC9, 0x4C, 0x5E, 0xC9, 0x55, 0x33, 0x45,
   0x7C, 0x3F, 0xB2, 0x51, 0xFE, 0x10, 0x7E, 0x75, 0x3C, 0x90, 0x8D, 0xDA, 0x94, 0x38, 0xC3, 0xE9,
   0x95, 0xEA, 0xCE, 0xA6, 0x06, 0xE0, 0x4F, 0x3F, 0x2A, 0xE3, 0x3A, 0xE4, 0x43, 0xBD, 0x7F, 0xDA,
   0x55, 0xF0, 0xEA, 0xCB, 0x2C, 0xA8, 0x47, 0x61, 0xA0, 0xEF, 0xCB, 0x13, 0x18, 0x20, 0xAF, 0x3E,
   0x4D, 0x9E, 0x1E, 0x77, 0x51, 0xC5, 0x51, 0x20, 0xCF, 0x21, 0xF9, 0x39, 0x94, 0xDE, 0xDD, 0x79,
   0x4E, 0x80, 0xC4, 0x9D, 0x94, 0xD5, 0x95, 0x01, 0x27, 0x27, 0xBD, 0x6D, 0x78, 0xB5, 0xD1, 0x31,
   0x6A, 0x65, 0x74, 0x74, 0x58, 0xB3, 0x7C, 0xC9, 0x5A, 0xED, 0x50, 0x03, 0xC4, 0xA2, 0x94, 0x4B,
   0xF0, 0x58, 0x09, 0x6F, 0x3E, 0x7D, 0xAE, 0x7D, 0x58, 0xA0, 0x2C, 0x91, 0xBB, 0xE1, 0x70, 0xEB,
   0x73, 0xA6, 0x9A, 0x44, 0x25, 0x90, 0x16, 0x62, 0x53, 0xAE, 0x08, 0xEB, 0xDC, 0xF0, 0xEE, 0x77,
   0xC2, 0xDE, 0x81, 0xE8, 0x30, 0x89, 0xDB, 0xFE, 0xBC, 0xC2, 0xDF, 0x26, 0xE9, 0x8B, 0xD6, 0x93,
   0xF0, 0xCB, 0x56, 0x90, 0xC0, 0x46, 0x68, 0x15, 0x43, 0xCB, 0xE9, 0x98, 0xE3, 0xAF, 0x31, 0x25,
   0x4D, 0x7B, 0xF3, 0xB1, 0x74, 0xE2, 0x64, 0xAC, 0xD9, 0xF6, 0xA0, 0xD5, 0x0B, 0x9B, 0x49, 0x52,
   0x69, 0x3B, 0x71, 0x00, 0x2F, 0xBB, 0xBA, 0x08, 0xB1, 0xAE, 0xBB, 0xB3, 0xE1, 0xC9, 0xA6, 0x7F,
   0x17, 0x97, 0x28, 0x72, 0x12, 0x6E, 0x91, 0xAE, 0x3A, 0xA2, 0x35, 0x46, 0x27, 0xF8, 0x12, 0x50
};
u8 v1_deadtable2[256] = {
   0xD8, 0x65, 0x04, 0xC2, 0x65, 0xD5, 0xB0, 0x0C, 0xDF, 0x9D, 0xF0, 0xC3, 0x9A, 0x17, 0xC9, 0xA6,
   0xE1, 0xAC, 0x0D, 0x14, 0x2F, 0x3C, 0x2C, 0x87, 0xA2, 0xBF, 0x4D, 0x5F, 0xAC, 0x2D, 0x9D, 0xE1,
   0x0C, 0x9C, 0xE7, 0x7F, 0xFC, 0xA8, 0x66, 0x59, 0xAC, 0x18, 0xD7, 0x05, 0xF0, 0xBF, 0xD1, 0x8B,
   0x35, 0x9F, 0x59, 0xB4, 0xBA, 0x55, 0xB2, 0x85, 0xFD, 0xB1, 0x72, 0x06, 0x73, 0xA4, 0xDB, 0x48,
   0x7B, 0x5F, 0x67, 0xA5, 0x95, 0xB9, 0xA5, 0x4A, 0xCF, 0xD1, 0x44, 0xF3, 0x81, 0xF5, 0x6D, 0xF6,
   0x3A, 0xC3, 0x57, 0x83, 0xFA, 0x8E, 0x15, 0x2A, 0xA2, 0x04, 0xB2, 0x9D, 0xA8, 0x0D, 0x7F, 0xB8,
   0x0F, 0xF6, 0xAC, 0xBE, 0x97, 0xCE, 0x16, 0xE6, 0x31, 0x10, 0x60, 0x16, 0xB5, 0x83, 0x45, 0xEE,
   0xD7, 0x5F, 0x2C, 0x08, 0x58, 0xB1, 0xFD, 0x7E, 0x79, 0x00, 0x34, 0xAD, 0xB5, 0x31, 0x34, 0x39,
   0xAF, 0xA8, 0xDD, 0x52, 0x6A, 0xB0, 0x60, 0x35, 0xB8, 0x1D, 0x52, 0xF5, 0xF5, 0x30, 0x00, 0x7B,
   0xF4, 0xBA, 0x03, 0xCB, 0x3A, 0x84, 0x14, 0x8A, 0x6A, 0xEF, 0x21, 0xBD, 0x01, 0xD8, 0xA0, 0xD4,
   0x43, 0xBE, 0x23, 0xE7, 0x76, 0x27, 0x2C, 0x3F, 0x4D, 0x3F, 0x43, 0x18, 0xA7, 0xC3, 0x47, 0xA5,
   0x7A, 0x1D, 0x02, 0x55, 0x09, 0xD1, 0xFF, 0x55, 0x5E, 0x17, 0xA0, 0x56, 0xF4, 0xC9, 0x6B, 0x90,
   0xB4, 0x80, 0xA5, 0x07, 0x22, 0xFB, 0x22, 0x0D, 0xD9, 0xC0, 0x5B, 0x08, 0x35, 0x05, 0xC1, 0x75,
   0x4F, 0xD0, 0x51, 0x2D, 0x2E, 0x5E, 0x69, 0xE7, 0x3B, 0xC2, 0xDA, 0xFF, 0xF6, 0xCE, 0x3E, 0x76,
   0xE8, 0x36, 0x8C, 0x39, 0xD8, 0xF3, 0xE9, 0xA6, 0x42, 0xE6, 0xC1, 0x4C, 0x05, 0xBE, 0x17, 0xF2,
   0x5C, 0x1B, 0x19, 0xDB, 0x0F, 0xF3, 0xF8, 0x49, 0xEB, 0x36, 0xF6, 0x40, 0x6F, 0xAD, 0xC1, 0x8C
};


//seed tables for AR v3
u8 v3_deadtable1[256] = {
   0xD0, 0xFF, 0xBA, 0xE5, 0xC1, 0xC7, 0xDB, 0x5B, 0x16, 0xE3, 0x6E, 0x26, 0x62, 0x31, 0x2E, 0x2A,
   0xD1, 0xBB, 0x4A, 0xE6, 0xAE, 0x2F, 0x0A, 0x90, 0x29, 0x90, 0xB6, 0x67, 0x58, 0x2A, 0xB4, 0x45,
   0x7B, 0xCB, 0xF0, 0x73, 0x84, 0x30, 0x81, 0xC2, 0xD7, 0xBE, 0x89, 0xD7, 0x4E, 0x73, 0x5C, 0xC7,
   0x80, 0x1B, 0xE5, 0xE4, 0x43, 0xC7, 0x46, 0xD6, 0x6F, 0x7B, 0xBF, 0xED, 0xE5, 0x27, 0xD1, 0xB5,
   0xD0, 0xD8, 0xA3, 0xCB, 0x2B, 0x30, 0xA4, 0xF0, 0x84, 0x14, 0x72, 0x5C, 0xFF, 0xA4, 0xFB, 0x54,
   0x9D, 0x70, 0xE2, 0xFF, 0xBE, 0xE8, 0x24, 0x76, 0xE5, 0x15, 0xFB, 0x1A, 0xBC, 0x87, 0x02, 0x2A,
   0x58, 0x8F, 0x9A, 0x95, 0xBD, 0xAE, 0x8D, 0x0C, 0xA5, 0x4C, 0xF2, 0x5C, 0x7D, 0xAD, 0x51, 0xFB,
   0xB1, 0x22, 0x07, 0xE0, 0x29, 0x7C, 0xEB, 0x98, 0x14, 0xC6, 0x31, 0x97, 0xE4, 0x34, 0x8F, 0xCC,
   0x99, 0x56, 0x9F, 0x78, 0x43, 0x91, 0x85, 0x3F, 0xC2, 0xD0, 0xD1, 0x80, 0xD1, 0x77, 0xA7, 0xE2,
   0x43, 0x99, 0x1D, 0x2F, 0x8B, 0x6A, 0xE4, 0x66, 0x82, 0xF7, 0x2B, 0x0B, 0x65, 0x14, 0xC0, 0xC2,
   0x1D, 0x96, 0x78, 0x1C, 0xC4, 0xC3, 0xD2, 0xB1, 0x64, 0x07, 0xD7, 0x6F, 0x02, 0xE9, 0x44, 0x31,
   0xDB, 0x3C, 0xEB, 0x93, 0xED, 0x9A, 0x57, 0x05, 0xB9, 0x0E, 0xAF, 0x1F, 0x48, 0x11, 0xDC, 0x35,
   0x6C, 0xB8, 0xEE, 0x2A, 0x48, 0x2B, 0xBC, 0x89, 0x12, 0x59, 0xCB, 0xD1, 0x18, 0xEA, 0x72, 0x11,
   0x01, 0x75, 0x3B, 0xB5, 0x56, 0xF4, 0x8B, 0xA0, 0x41, 0x75, 0x86, 0x7B, 0x94, 0x12, 0x2D, 0x4C,
   0x0C, 0x22, 0xC9, 0x4A, 0xD8, 0xB1, 0x8D, 0xF0, 0x55, 0x2E, 0x77, 0x50, 0x1C, 0x64, 0x77, 0xAA,
   0x3E, 0xAC, 0xD3, 0x3D, 0xCE, 0x60, 0xCA, 0x5D, 0xA0, 0x92, 0x78, 0xC6, 0x51, 0xFE, 0xF9, 0x30
};
u8 v3_deadtable2[256] = {
   0xAA, 0xAF, 0xF0, 0x72, 0x90, 0xF7, 0x71, 0x27, 0x06, 0x11, 0xEB, 0x9C, 0x37, 0x12, 0x72, 0xAA,
   0x65, 0xBC, 0x0D, 0x4A, 0x76, 0xF6, 0x5C, 0xAA, 0xB0, 0x7A, 0x7D, 0x81, 0xC1, 0xCE, 0x2F, 0x9F,
   0x02, 0x75, 0x38, 0xC8, 0xFC, 0x66, 0x05, 0xC2, 0x2C, 0xBD, 0x91, 0xAD, 0x03, 0xB1, 0x88, 0x93,
   0x31, 0xC6, 0xAB, 0x40, 0x23, 0x43, 0x76, 0x54, 0xCA, 0xE7, 0x00, 0x96, 0x9F, 0xD8, 0x24, 0x8B,
   0xE4, 0xDC, 0xDE, 0x48, 0x2C, 0xCB, 0xF7, 0x84, 0x1D, 0x45, 0xE5, 0xF1, 0x75, 0xA0, 0xED, 0xCD,
   0x4B, 0x24, 0x8A, 0xB3, 0x98, 0x7B, 0x12, 0xB8, 0xF5, 0x63, 0x97, 0xB3, 0xA6, 0xA6, 0x0B, 0xDC,
   0xD8, 0x4C, 0xA8, 0x99, 0x27, 0x0F, 0x8F, 0x94, 0x63, 0x0F, 0xB0, 0x11, 0x94, 0xC7, 0xE9, 0x7F,
   0x3B, 0x40, 0x72, 0x4C, 0xDB, 0x84, 0x78, 0xFE, 0xB8, 0x56, 0x08, 0x80, 0xDF, 0x20, 0x2F, 0xB9,
   0x66, 0x2D, 0x60, 0x63, 0xF5, 0x18, 0x15, 0x1B, 0x86, 0x85, 0xB9, 0xB4, 0x68, 0x0E, 0xC6, 0xD1,
   0x8A, 0x81, 0x2B, 0xB3, 0xF6, 0x48, 0xF0, 0x4F, 0x9C, 0x28, 0x1C, 0xA4, 0x51, 0x2F, 0xD7, 0x4B,
   0x17, 0xE7, 0xCC, 0x50, 0x9F, 0xD0, 0xD1, 0x40, 0x0C, 0x0D, 0xCA, 0x83, 0xFA, 0x5E, 0xCA, 0xEC,
   0xBF, 0x4E, 0x7C, 0x8F, 0xF0, 0xAE, 0xC2, 0xD3, 0x28, 0x41, 0x9B, 0xC8, 0x04, 0xB9, 0x4A, 0xBA,
   0x72, 0xE2, 0xB5, 0x06, 0x2C, 0x1E, 0x0B, 0x2C, 0x7F, 0x11, 0xA9, 0x26, 0x51, 0x9D, 0x3F, 0xF8,
   0x62, 0x11, 0x2E, 0x89, 0xD2, 0x9D, 0x35, 0xB1, 0xE4, 0x0A, 0x4D, 0x93, 0x01, 0xA7, 0xD1, 0x2D,
   0x00, 0x87, 0xE2, 0x2D, 0xA4, 0xE9, 0x0A, 0x06, 0x66, 0xF8, 0x1F, 0x44, 0x75, 0xB5, 0x6B, 0x1C,
   0xFC, 0x31, 0x09, 0x48, 0xA3, 0xFF, 0x92, 0x12, 0x58, 0xE9, 0xFA, 0xAE, 0x4F, 0xE2, 0xB4, 0xCC
};


void decrypt_code(u32 *address, u32 *value);
void encrypt_code(u32 *address, u32 *value);
void deadface(u16 value);
u32 seed_gen(u8 upper, u8 seed, u8 *deadtable1, u8 *deadtable2);


void decrypt_code(u32 *address, u32 *value) {
   int i;
   u32 rollingseed = 0xC6EF3720;

   for (i = 0; i < 32; i++) {
      *value -= ((((*address << 4) + seeds[2]) ^ (*address + rollingseed)) ^ ((*address >> 5) + seeds[3]));
      *address -= ((((*value << 4) + seeds[0]) ^ (*value + rollingseed)) ^ ((*value >> 5) + seeds[1]));
      rollingseed -= 0x9E3779B9;
   }
   if (*address == 0xDEADFACE) deadface(*value);
}

void encrypt_code(u32 *address, u32 *value) {
   int i;
   u32 rollingseed = 0, oldaddr = *address, oldval = *value;

   for (i = 0; i < 32; i++) {
      rollingseed += 0x9E3779B9;
      *address += ((((*value << 4) + seeds[0]) ^ (*value + rollingseed)) ^ ((*value >> 5) + seeds[1]));
      *value += ((((*address << 4) + seeds[2]) ^ (*address + rollingseed)) ^ ((*address >> 5) + seeds[3]));
   }
   if (oldaddr == 0xDEADFACE) deadface(oldval);
}

void deadface(u16 value) {
   int i;
   u8 *deadtable1, *deadtable2;

   if (v3enc) {
      deadtable1 = (u8*)(&v3_deadtable1);
      deadtable2 = (u8*)(&v3_deadtable2);
   }
   else {
      deadtable1 = (u8*)(&v1_deadtable1);
      deadtable2 = (u8*)(&v1_deadtable2);
   }

   for (i = 0; i < 4; i++)
      seeds[i] = seed_gen(((value & 0xFF00) >> 8), (value & 0xFF) + i, deadtable1, deadtable2);
   //printf("Encryption Seeds Have Changed!\n");
}

u32 seed_gen(u8 upper, u8 seed, u8 *deadtable1, u8 *deadtable2) {
   int i;
   u32 newseed;

   for (i = 0; i < 4; i++)
      newseed = ((newseed << 8) | ((deadtable1[(i + upper) & 0xFF] + deadtable2[seed]) & 0xFF));
   return newseed;
}

Author:  Parasyte [ Mon Apr 12, 2010 4:48 pm ]
Post subject:  Re: GBA AR code encryption

Here's some more blast-from-the-past goodies! The hardware information I gathered back in 2002 (and 2005, apparently!) as well as some RE'd disassemblies and usable source code. This is for the original AR/GS (v1/v2) and AR v3.

Attachments:
gsa-hacking.tar.gz [4.04 KiB]
Downloaded 166 times

Page 1 of 1 All times are UTC - 8 hours [ DST ]
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/