FreeCalypso > hg > freecalypso-reveng
view pirollback/journal.c @ 161:237bb836521d
starting to examine Tracfone's locked C139 bootloader
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Thu, 15 May 2014 20:10:25 +0000 |
parents | 78ac405716db |
children |
line wrap: on
line source
#include <sys/types.h> #include <endian.h> #include <stdio.h> #include <string.h> #include <strings.h> #include <stdlib.h> #include <unistd.h> #include "types.h" #include "struct.h" extern u8 image[0x480000]; extern struct inode_info inode[]; extern int last_inode; extern u8 blank_flash_line[16]; int journal_start_ino; find_journal() { int ino; struct inode_info *inf; for (ino = 2; ino <= last_inode; ino++) { inf = inode + ino; if (inf->type == 0xE1 && inf->parent == 1 && !strcmp(inf->dataptr, ".journal")) return(ino); } fprintf(stderr, "error: cannot find /.journal\n"); exit(1); } parse_journal() { struct inode_info *inf; struct journal_entry *jr, *endp; int ino = 0; u16 tempu16; s16 temps16; inf = inode + find_journal(); if (inf->len != 0x4010) { fprintf(stderr, "error: /.journal file length differs from expected\n"); exit(1); } jr = (struct journal_entry *)(inf->dataptr + 0xC); for (endp = jr + 0x3FF; jr < endp; jr++) { if (!bcmp(jr, blank_flash_line, 16)) break; if (jr->status != 0xF1) { fprintf(stderr, "journal record at %x: status byte != F1\n", (u8 *) jr - image); exit(1); } tempu16 = le16toh(jr->this_ino); if (ino) { ino++; if (ino != tempu16) { fprintf(stderr, "journal record at %x: break in inode # sequence\n", (u8 *) jr - image); exit(1); } } else { ino = tempu16; journal_start_ino = ino; } if (ino < 3 || ino > last_inode) { fprintf(stderr, "journal record at %x: inode # out of range\n", (u8 *) jr - image); exit(1); } inf = inode + ino; inf->jflash = jr; if (inf->type) { if (jr->objtype != inf->type) { fprintf(stderr, "journal record at %x: type mismatch\n", (u8 *) jr - image); exit(1); } } else { switch (jr->objtype) { case 0xE1: case 0xF1: case 0xF2: case 0xF4: break; default: fprintf(stderr, "journal record at %x: unexpected type byte value\n", (u8 *) jr - image); exit(1); } inf->type = jr->objtype; } if (le32toh(jr->location) != inf->rawloc) { fprintf(stderr, "journal record at %x: location field mismatch\n", (u8 *) jr - image); exit(1); } if (le16toh(jr->size) != inf->len) { fprintf(stderr, "journal record at %x: size field mismatch\n", (u8 *) jr - image); exit(1); } temps16 = le16toh(jr->link_ptr); if (temps16 < -last_inode || temps16 > last_inode) { fprintf(stderr, "journal record at %x: linkptr field out of range\n", (u8 *) jr - image); exit(1); } inf->j_unlink_ptr = temps16; temps16 = le16toh(jr->replacee); if (temps16 < 0 || temps16 > last_inode) { fprintf(stderr, "journal record at %x: replacee field out of range\n", (u8 *) jr - image); exit(1); } inf->j_oldver = temps16; if (jr->repli) { fprintf(stderr, "journal record at %x: last 16-bit word is not zero as expected\n", (u8 *) jr - image); exit(1); } } if (!ino) { fprintf(stderr, "error: journal is empty!\n"); exit(1); } if (ino != last_inode) { fprintf(stderr, "error: journal end != inode block end\n"); exit(1); } }