GIDecrypt

From The iPhone Wiki
Revision as of 03:04, 18 June 2009 by Posixninja (talk | contribs) (and perfectionist)
Jump to: navigation, search

This is a quick and simple program I wrote to automatically decrypt KBAG and print the key/iv pair for a given 3.0 IMG3. This hasn't been throughly tested on anything other then 32bit linux, so there might be some bugs. I figured since this was already out in the open, I might as well make it easier for everybody. Also, this requires libcrypto to compile properly.

/*
 * gidecrypt.c
 *
 *  Created on: Jun 17, 2009
 *      Author: posixninja
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/aes.h>

typedef struct {
  unsigned int magic;
  unsigned int total_size;
  unsigned int data_size;
  unsigned int state;
  unsigned int type;
  unsigned char iv[16];
  unsigned char key[32];
} kbag_struct;

void hexdump(unsigned char* hex, int size) {
  int i = 0;
  for (i = 0; i < size; i++) {
    printf("%02x", hex[i]);
  }
  printf("\n");
}

int main(int argc, char* argv[]) {
  unsigned char gid_key[] = { 0x5F, 0x65, 0x02, 0x95, 0xE1, 0xFF, 0xFC, 0x97,
      0xCE, 0x77, 0xAB, 0xD4, 0x9D, 0xD9, 0x55, 0xB3 };
  unsigned char gid_iv[]  = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

  unsigned char kbag_tag[4] = { 0x47, 0x41, 0x42, 0x4B };
  unsigned char outbuf[32];
  char* input;
  char* output;

  if (argc <= 1) {
    printf("Usage: ./gidecrypt <input.img3>\n");
    return 1;
  }
  input = argv[1];
  output = argv[2];

  FILE* in_file = fopen(input, "rb");
  if (in_file == NULL) {
    printf("Can't open file %s\n", input);
    return 1;
  }
  fseek(in_file, 0, SEEK_END);
  int file_size = ftell(in_file);
  fseek(in_file, 0, SEEK_SET);

  unsigned char* file_buffer = malloc(file_size);
  fread(file_buffer, 1, file_size, in_file);
  fclose(in_file);

  int i = 0;
  kbag_struct* kbag;
  for (i = 0; i < file_size; i++) {
    if (memcmp(&file_buffer[i], &kbag_tag, 4) == 0) {
      kbag = malloc(sizeof(kbag_struct));
      memcpy(kbag, &file_buffer[i], sizeof(kbag_struct));
      break;
    }
  }

  AES_KEY aeskey;
  AES_set_decrypt_key(gid_key, kbag->type ,&aeskey);
  AES_cbc_encrypt((unsigned char*)&kbag->iv, outbuf, 0x30, &aeskey, gid_iv, AES_DECRYPT);

  printf("IV:  ");
  hexdump(outbuf, 16);
  printf("Key: ");
  hexdump(&outbuf[16], 16);

  free(kbag);
  free(file_buffer);
  return 0;
}