#include #include //#include //#include #include #include #include #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; }