Difference between revisions of "GenPass"

From The iPhone Wiki
Jump to: navigation, search
(New page: <pre> // genpass // get asr key for 3.x firmware // // by posixninja, geohot, chronic, and #iphone-rce #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #incl...)
 
m (GenPass Usage: This actually has to be lowercase.)
 
(17 intermediate revisions by 10 users not shown)
Line 1: Line 1:
  +
GenPass generates the RootFS keys for the filesystem image of an iDevice. It requires a decrypted [[ramdisk]].
<pre>
 
// genpass
 
// get asr key for 3.x firmware
 
//
 
// by posixninja, geohot, chronic, and #iphone-rce
 
   
  +
== Notices ==
#include <stdio.h>
 
  +
* The decryption happens in <code>/usr/sbin/asr</code> in the decrypted ramdisk.
#include <stdlib.h>
 
  +
* Mounting the decrypted ramdisk messes with the structure of the image rending GenPass's keys false.
#include <string.h>
 
#include <unistd.h>
 
#include <sys/types.h>
 
#include <sys/stat.h>
 
#include <openssl/sha.h>
 
#include <openssl/evp.h>
 
   
  +
== GenPass Usage ==
#define BUF_SIZE 0x100000
 
  +
./genpass <platform> <ramdisk> <filesystem>
#define SHA256_DIGEST_LENGTH 32
 
  +
Platform is the applications processor (i.e.- [[S5L8900|s5l8900]]x, [[S5L8720|s5l8720]]x, [[S5L8920|s5l8920]]x, [[S5L8922|s5l8922]]x, [[S5L8930|s5l8930]]x, [[S5L8940|s5l8940]]x)
   
  +
== See also ==
typedef unsigned char uint8;
 
  +
* [[0rangefreeze]]
typedef unsigned int uint32;
 
typedef unsigned long long uint64;
 
   
  +
== External Links ==
uint64 u32_to_u64(uint32 msq, uint32 lsq) {
 
  +
* [https://github.com/posixninja/genpass Source]
uint64 ms = (uint64)msq;
 
uint64 ls = (uint64)lsq;
 
return ls | (ms << 32);
 
}
 
   
  +
[[Category:Decryption]]
uint64 hash_platform(const char* platform) {
 
  +
[[Category:Hacking Software]]
uint8* md = malloc(SHA_DIGEST_LENGTH);
 
SHA1(platform, strlen(platform), md);
 
 
uint64 hash = u32_to_u64(
 
((md[0] << 24) | (md[1] << 16) | (md[2] << 8) | md[3]),
 
((md[4] << 24) | (md[5] << 16) | (md[6] << 8) | md[7])
 
);
 
free(md);
 
return hash;
 
}
 
 
uint64 ramdisk_size(const char* ramdisk) {
 
struct stat filestat;
 
if(stat(ramdisk, &filestat) < 0) {
 
return 0;
 
}
 
 
return (uint64)filestat.st_size;
 
}
 
 
void keydump(uint8* passphrase,int l) {
 
int i=0;
 
for(i=0; i<l; i++) {
 
printf("%02x", passphrase[i]);
 
} printf("\n");
 
}
 
 
 
int compare(const uint32* a, const uint32* b) {
 
if(*a < *b) return -1;
 
if(*a > *b) return 1;
 
return 0;
 
}
 
 
const char platform[]="s5l8900x";
 
const char ramdisk[]="ramdisk.dmg";
 
 
 
int main(int argc, char* argv[]) {
 
 
if(argc<3) {printf("%s: <platform> <ramdisk> <main>\n", argv[0]); return -1;}
 
 
uint32 saltedHash[4];
 
uint64 salt[4];
 
 
salt[0] = 0xad79d29de5e2ac9e;
 
salt[1] = 0xe6af2eb19e23925b;
 
salt[2] = 0x3f1375b4bd88815c;
 
salt[3] = 0x3bdff4e5564a9f87;
 
 
FILE* fd = fopen(argv[2], "rb");
 
int i = 0;
 
int x = 0;
 
SHA256_CTX ctx;
 
uint8* buffer = NULL;
 
uint8* passphrase = NULL;
 
uint64 totalSize = ramdisk_size(argv[2]);
 
uint64 platformHash = hash_platform(argv[1]);
 
 
/*printf("size: %I64x plat: %s plathash %I64x\n", totalSize,
 
platform,platformHash);*/
 
 
for(i=0;i<4;i++)
 
{
 
salt[i]+=platformHash;
 
//printf("%d: %I64x\n", i, salt[i]);
 
}
 
 
for(i = 0; i < 4; i++) {
 
saltedHash[i] = ((uint32)(salt[i] % totalSize)) & 0xFFFFFE00;
 
}
 
 
qsort(&saltedHash, 4, 4, &compare);
 
 
SHA256_Init(&ctx);
 
SHA256_Update(&ctx, salt, 32);
 
 
 
int r=0;
 
i=0; //hash count
 
 
buffer = malloc(BUF_SIZE);
 
passphrase = malloc(SHA256_DIGEST_LENGTH);
 
 
while(r<totalSize) {
 
x = fread(buffer, 1, BUF_SIZE, fd);
 
SHA256_Update(&ctx, buffer, x);
 
 
if(i<4) //some salts remain
 
{
 
if(r >= (saltedHash[i]+0x4000)) i++;
 
else if( r < saltedHash[i] && saltedHash[i] < (r+x) )
 
{
 
if( (saltedHash[i]+0x4000) < r )
 
SHA256_Update(&ctx, buffer, saltedHash[i]-r);
 
else SHA256_Update(&ctx, buffer+(saltedHash[i]-r),
 
( (x-(saltedHash[i]-r))<0x4000) ? (x-(saltedHash[i]-r)) : 0x4000 );
 
}
 
}
 
r+=x;
 
}
 
 
fclose(fd);
 
 
SHA256_Final(passphrase, &ctx);
 
printf("passphrase: ");
 
keydump(passphrase, SHA256_DIGEST_LENGTH);
 
 
if(buffer) free(buffer);
 
 
if(argc==4) //do main as well
 
{
 
fd=fopen(argv[3],"rb");
 
EVP_CIPHER_CTX ctx;
 
 
int offset=0x1D4;
 
uint8 data[0x30];
 
uint8 out[0x30]; int outlen,tmplen;
 
int a;
 
for(a=0;a<7;a++)
 
{
 
fseek(fd, offset, SEEK_SET); offset+=0x268;
 
fread(data, 1, 0x30, fd);
 
EVP_CIPHER_CTX_init(&ctx);
 
EVP_DecryptInit_ex(&ctx, EVP_des_ede3_cbc(),
 
NULL, passphrase, &passphrase[24]);
 
EVP_DecryptUpdate(&ctx, out, &outlen, data, 0x30);
 
if(!EVP_DecryptFinal_ex(&ctx, out + outlen, &tmplen))
 
printf("not block %d\n", a);
 
else
 
break;
 
}
 
printf("vfdecryptk: ");
 
keydump(out, 0x24);
 
}
 
 
if(passphrase) free(passphrase);
 
 
return 0;
 
}
 
</pre>
 

Latest revision as of 23:02, 4 January 2016

GenPass generates the RootFS keys for the filesystem image of an iDevice. It requires a decrypted ramdisk.

Notices

  • The decryption happens in /usr/sbin/asr in the decrypted ramdisk.
  • Mounting the decrypted ramdisk messes with the structure of the image rending GenPass's keys false.

GenPass Usage

./genpass <platform> <ramdisk> <filesystem>

Platform is the applications processor (i.e.- s5l8900x, s5l8720x, s5l8920x, s5l8922x, s5l8930x, s5l8940x)

See also

External Links