The iPhone Wiki is no longer updated. Visit this article on The Apple Wiki for current information. |
GIDecrypt
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; }