176 lines
4.2 KiB
C
176 lines
4.2 KiB
C
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
//#include <sys/mount.h>
|
|
//#include <sys/socket.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <CoreFoundation/CoreFoundation.h>
|
|
#include "ioflash/ioflash.h"
|
|
#include "util.h"
|
|
|
|
struct IMG2
|
|
{
|
|
uint32_t magic;
|
|
uint32_t block_size;
|
|
uint32_t images_offset;
|
|
uint32_t images_block;
|
|
uint32_t images_length;
|
|
uint8_t padding[0x1c];
|
|
uint32_t crc32;
|
|
};
|
|
|
|
struct IMG3
|
|
{
|
|
uint32_t magic;
|
|
uint32_t fullSize;
|
|
uint32_t sizeNoPack;
|
|
uint32_t sigCheckArea;
|
|
uint32_t iden;
|
|
};
|
|
|
|
struct IMG3_TLV
|
|
{
|
|
uint32_t tag;
|
|
uint32_t total_length;
|
|
uint32_t data_length;
|
|
uint8_t payload[1];
|
|
};
|
|
|
|
void printIMG2(struct IMG2* s)
|
|
{
|
|
printf("magic= %x\n", s->magic);
|
|
printf("block_size= %x\n", s->block_size);
|
|
printf("images_offset= %x\n", s->images_offset);
|
|
printf("images_block= %x\n", s->images_block);
|
|
printf("images_length= %x\n", s->images_length);
|
|
}
|
|
void printIMG3(struct IMG3* s)
|
|
{
|
|
char iden[10]={0};
|
|
memcpy(iden, &s->iden, 4);
|
|
printf("magic= %x\n", s->magic);
|
|
printf("fullSize= %x\n", s->fullSize);
|
|
printf("iden= %s\n", iden);
|
|
}
|
|
|
|
CFDataRef getIMG3Data(struct IMG3* img3)
|
|
{
|
|
CFDataRef data = NULL;
|
|
uint8_t* p = (uint8_t*) img3;
|
|
uint8_t* z = &p[20];
|
|
|
|
if(img3->magic != 'Img3')
|
|
return NULL;
|
|
|
|
while(z < &p[img3->fullSize])
|
|
{
|
|
struct IMG3_TLV* item = (struct IMG3_TLV*) z;
|
|
if( item->tag == 'DATA')
|
|
{
|
|
data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, item->payload, item->data_length, NULL);
|
|
return data;
|
|
}
|
|
z += item->total_length;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
extern uint32_t gPagesPerBlock;
|
|
extern uint32_t gBytesPerPage ;
|
|
extern uint32_t gBootloaderBytes ;
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
int one=1;
|
|
int cmd=0;
|
|
|
|
CFMutableDictionaryRef dict = FSDGetInfo(1);
|
|
if (dict == NULL)
|
|
{
|
|
fprintf(stderr, "FAILed to get NAND infos");
|
|
return -1;
|
|
}
|
|
if(!IOFlashStorage_kernel_patch())
|
|
return -1;
|
|
|
|
struct kIOFlashControllerOut out;
|
|
uint32_t bootSize = gBootloaderBytes * gPagesPerBlock * 8;
|
|
|
|
printf("Mallocing %x bytes for boot partition\n", bootSize);
|
|
uint8_t* boot = malloc(bootSize);
|
|
if( boot == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
uint8_t* buffer = malloc(gBytesPerPage);
|
|
if( buffer == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
uint32_t block, page, off=0;
|
|
|
|
for(block=8; block < 16; block++)
|
|
{
|
|
for(page=0; page < gPagesPerBlock; page++)
|
|
{
|
|
if(FSDReadBootPage(0, block*gPagesPerBlock + page, buffer, &out))
|
|
{
|
|
//printf("FSDReadBootPage error %x\n", block*gPagesPerBlock + page);
|
|
//return -1;
|
|
}
|
|
memcpy(&boot[off], buffer, gBootloaderBytes);
|
|
off += gBootloaderBytes;
|
|
}
|
|
}
|
|
|
|
printIMG2((struct IMG2*) boot);
|
|
struct IMG2* img2 = (struct IMG2*) boot;
|
|
|
|
if( img2->magic != 0x494d4732)
|
|
{
|
|
printf("Bag IMG2 magic : %x\n", img2->magic);
|
|
return -1;
|
|
}
|
|
uint32_t start = img2->block_size * img2->images_block;
|
|
|
|
uint32_t end = start + img2->block_size * img2->images_length;
|
|
|
|
if( end < start)
|
|
{
|
|
return -1;
|
|
}
|
|
printf("start %x end %x\n", start, end);
|
|
uint8_t* p = &boot[start];
|
|
|
|
CFMutableDictionaryRef resultsDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
|
|
|
if(dict == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
while(p < &boot[end])
|
|
{
|
|
struct IMG3* img3 = (struct IMG3*) p;
|
|
if(img3->magic != 'Img3')
|
|
break;
|
|
printIMG3(img3);
|
|
|
|
if(img3->iden == 'SCAB')
|
|
{
|
|
CFDataRef data = getIMG3Data(img3);
|
|
if(data)
|
|
{
|
|
CFDictionaryAddValue(resultsDict, CFSTR("APTicket"), data);
|
|
writePlistToStdout(resultsDict);
|
|
CFRelease(data);
|
|
}
|
|
}
|
|
p += img3->fullSize;
|
|
|
|
}
|
|
return 0;
|
|
} |