Browse files

more chain stuff

  • Loading branch information...
1 parent 0721920 commit 737fd79331697e95f8daef9921f7d4e6964030bd @comex committed Dec 30, 2010
Showing with 175 additions and 21 deletions.
  1. +155 −0 binary/binary.py
  2. +20 −21 chain/chain.c
View
155 binary/binary.py
@@ -0,0 +1,155 @@
+#!/opt/local/bin/python2.6
+
+class basebin:
+ def lookup_addr(self, off):
+ for startaddr, startoff, size, prot in self.sects:
+ if off >= startoff and off < (startoff + size):
+ return startaddr + (off - startoff)
+ raise ValueError('No address for offset %x' % off)
+
+ def lookup_addr_and_prot(self, off):
+ for startaddr, startoff, size, prot in self.sects:
+ if off >= startoff and off < (startoff + size):
+ return (startaddr + (off - startoff), prot)
+ raise ValueError('No address for offset %x' % off)
+
+ def lookup_off(self, addr):
+ for startaddr, startoff, size, prot in self.sects:
+ if addr >= startaddr and addr < (startaddr + size):
+ return startoff + (addr - startaddr)
+ raise ValueError('No offset for address %x' % addr)
+
+ def deref(self, addr):
+ off = self.lookup_off(addr)
+ return struct.unpack('I', self.stuff[off:off+4])[0]
+
+ def get_sym(self, sym):
+ if self.name is None:
+ return self.get_sym_uncached(sym)
+ cachekey = hashlib.sha1(str(self.name) + struct.pack('f', os.path.getmtime(self.name)) + sym).digest()
+ if cache_has_key(cachekey):
+ return cache[cachekey]
+ value = self.get_sym_uncached(sym)
+ cache[cachekey] = value
+ return value
+
+ def __getitem__(self, sym):
+ return self.get_sym(sym)
+
+class macho(basebin):
+ def __init__(self, name, stuff):
+ self.name = name
+ self.stuff = stuff
+ xbase = stuff.tell()
+ magic, cputype, cpusubtype, \
+ filetype, filetype, ncmds, sizeofcmds, \
+ flags = struct.unpack('IHHIIIII', stuff.read(0x1c))
+ self.sects = sects = []
+ self.nsyms = None
+ self.syms = None
+ while True:
+ xoff = stuff.tell()
+ if xoff >= xbase + sizeofcmds: break
+ cmd, clen = struct.unpack('II', stuff.read(8))
+ if cmd == 1: # LC_SEGMENT
+ name = stuff.read(16).rstrip('\0')
+ vmaddr, vmsize, foff, fsiz, maxprot, initprot = struct.unpack('IIIIii', stuff.read(24))
+ # why is the prot wrong in the file?
+ if name == '__PRELINK_TEXT': initprot = 5
+ sects.append((vmaddr, foff, fsiz, initprot))
+ elif cmd == 2: # LC_SYMTAB
+ self.symoff, self.nsyms, self.stroff, self.strsize = struct.unpack('IIII', stuff.read(16))
+ elif cmd == 11: # LC_DYSYMTAB
+ self.ilocalsym, self.nlocalsym = struct.unpack('II', stuff.read(8))
+ self.iextdefsym, self.nextdefsym = struct.unpack('II', stuff.read(8))
+ self.iundefsym, self.nundefsym = struct.unpack('II', stuff.read(8))
+ stuff.seek(xoff + clen)
+
+ def print_all_syms(self):
+ print 'local:', self.ilocalsym, self.nlocalsym
+ print 'extdef:', self.iextdefsym, self.nextdefsym
+ print 'undef:', self.iundefsym, self.nundefsym
+ for i in xrange(self.nsyms):
+ off = self.symoff + 12*i
+ n_strx, n_type, n_sect, n_desc, n_value = struct.unpack('IBBhI', self.stuff[off:off+12])
+ n_strx += self.stroff
+ psym = self.stuff[n_strx:self.stuff.find('\0', n_strx)]
+ print '%d: %s' % (i, psym)
+
+ def get_syms(self):
+ syms = {}
+ for off in xrange(self.symoff, self.symoff + 12*self.nsyms, 12):
+ n_strx, n_type, n_sect, n_desc, n_value = struct.unpack('IBBhI', self.stuff[off:off+12])
+ if n_value == 0 or n_strx == 0: continue
+ if n_strx > self.strsize: break # wtf
+ n_strx += self.stroff
+ psym = self.stuff[n_strx:self.stuff.find('\0', n_strx)]
+ if n_desc & 8:
+ # thumb
+ n_value |= 1
+ syms[psym] = n_value
+ return syms
+
+ def get_sym_uncached(self, sym):
+ # Local syms aren't sorted. So I can't use a binary search.
+ if self.nsyms is None:
+ raise KeyError, sym
+ if self.syms is None:
+ self.syms = self.get_syms()
+ return self.syms[sym]
+
+
+class dyldcache(basebin):
+ def __init__(self, name, stuff):
+ self.name = name
+ self.stuff = stuff
+ stuff.seek(0)
+ magic = stuff.read(16)
+ assert re.match('dyld_v1 armv.\0' , magic)
+
+ mappingOffset, mappingCount = struct.unpack('II', stuff.read(8))
+ imagesOffset, imagesCount = struct.unpack('II', stuff.read(8))
+
+ stuff.seek(mappingOffset)
+ self.sects = []
+ for i in xrange(mappingCount):
+ sfm_address, sfm_size, sfm_file_offset, sfm_max_prot, sfm_init_prot = struct.unpack('QQQII', stuff.read(32))
+ self.sects.append((sfm_address, sfm_file_offset, sfm_size, sfm_init_prot))
+
+ self.files = {}
+ for i in xrange(imagesCount):
+ stuff.seek(imagesOffset + 32*i)
+ address, modTime, inode, pathFileOffset, pad = struct.unpack('QQQII', stuff.read(32))
+ stuff.seek(self.lookup_off(address))
+ self.files[stuff[pathFileOffset:stuff.find('\0', pathFileOffset)]] = macho(None, stuff)
+
+ def get_sym_uncached(self, sym):
+ for name, macho in self.files.iteritems():
+ try:
+ result = macho.get_sym(sym)
+ except KeyError:
+ continue
+ else:
+ return result
+ raise KeyError, sym
+
+class nullbin(basebin):
+ name = None
+ def get_sym_uncached(self, sym):
+ raise KeyError, sym
+
+###
+def binary_open(filename):
+ if filename is None:
+ return nullbin()
+ fp = open(filename, 'rb')
+ magic = fp.read(4)
+ stuff = mmap.mmap(fp.fileno(), os.path.getsize(filename), prot=mmap.PROT_READ)
+ if magic == 'dyld':
+ binary = dyldcache(filename, stuff)
+ elif magic == struct.pack('I', 0xfeedface):
+ binary = macho(filename, stuff)
+ else:
+ raise Exception('Unknown magic %r in %s' % (magic, filename))
+ return binary
+
View
41 chain/chain.c
@@ -20,7 +20,13 @@ static char *devicetree_final;
static uint32_t *pagetable_final;
static struct boot_args args_storage;
-static char pagetable_storage[0x4000] __attribute__((section("__STORAGE,__storage"), aligned(0x4000)));
+// WARNING WARNING WARNING WARNING
+// If you use __attribute__((aligned)), you can get a binary like this:
+// http://pastie.org/private/qamosrgse9ufzsxsvyehaw
+// The section is outside of the segment!
+// To easily see if that's happening, run check_sanity from the data repository.
+
+static char *pagetable_storage;
struct boot_args {
uint16_t something; // 0 - 1
@@ -100,10 +106,6 @@ static void vita(uint32_t args_phys, uint32_t jump_phys) {
invalidate_tlb();
-#if DEBUG
- my_memset((void *) args_final->v_baseAddr, 0x88, args_final->v_height * args_final->v_rowBytes);
-#endif
-
// This appears to work (and avoid GCC complaining about noreturn functions returning), but it also generates a warning. I don't know how to get rid of it.
//((void (__attribute__((noreturn)) *)(uint32_t)) jump_phys)(args_phys);
__attribute__((noreturn)) void (*ptr)(uint32_t) = (void *) jump_phys;
@@ -163,14 +165,6 @@ static int phase_1() {
uart_set_rate(115200);
- // bam
- memset((void *) 0x80342930, 0, 0x16);
- flush_cache((void *) 0x80342900, 0x100);
- memset((void *) 0x8034320a, 0, 0x10);
- flush_cache((void *) 0x80343200, 0x100);
- place_putc();
- *((uint32_t *) 0x8000011c) = 0;
-
serial_putstring("Hello... I am at ");
serial_puthex((uint32_t) phase_1);
serial_putstring(" aka ");
@@ -376,11 +370,11 @@ static void place_annoyance(uint32_t addr, uint32_t hookaddr, uint32_t hooksize)
}
}
-static void place_bxsp(uint32_t addr) {
+static void place_blxsp(uint32_t addr) {
if(addr & 1) {
- *((uint16_t *) (addr - 1)) = 0x4768;
+ *((uint16_t *) (addr - 1)) = 0x47e8;
} else {
- *((uint32_t *) addr) = 0xe12fff1d;
+ *((uint32_t *) addr) = 0xe12fff3d;
}
}
#endif // DEBUG || PUTC
@@ -397,7 +391,7 @@ static void place_putc() {
static int phase_2(unsigned int type) {
// no kanye
- asm volatile("cpsid aif");
+ asm volatile("cpsid if");
// stuff from openiboot
for(int i = 0; i <= 3; i++) {
@@ -516,7 +510,7 @@ static int phase_2(unsigned int type) {
#endif
*/
- static const char c[] = "-v io=4095 sdio.log.level=65535 sdio.log.flags=1 kdp_match_name=serial "
+ static const char c[] = "-v io=8 " //sdio.log.level=65535 sdio.log.flags=1 "
#if 0
"sdio.debug.init-delay=10000 "
#endif
@@ -550,12 +544,15 @@ static int phase_2(unsigned int type) {
place_annoyance(SCRATCH + 0x1d00, 0x80791429, 8);*/
//place_annoyance(SCRATCH + 0x1e00, 0x80791447, 12);
//place_annoyance(SCRATCH + 0x1f00, 0x80791453, 12);
- //place_bxsp(0x80791453);
//place_annoyance(SCRATCH + 0x2000, 0x807914bf, 10);
//place_annoyance(SCRATCH + 0x2100, 0x807914d1, 8);
//place_annoyance(SCRATCH + 0x2200, 0x807914f9, 12);
- place_bxsp(0x807914cf);
- place_bxsp(0x8079152b);
+ //place_blxsp(0x80791453);
+ //place_blxsp(0x80791481);
+ place_blxsp(0x80791499);
+ place_blxsp(0x807914cf);
+ place_blxsp(0x8079152b);
+ place_blxsp(0x807914f9);
#endif
#if PUTC
@@ -601,6 +598,7 @@ struct args {
int ok_go(void *p, struct args *uap, int32_t *retval) {
kern_hdr = IOMallocContiguous(uap->kern_size, 1, NULL);
+ pagetable_storage = IOMallocContiguous(0x4000, 0x4000, NULL);
copyin(uap->kern, kern_hdr, uap->kern_size);
devicetree = kalloc(uap->devicetree_size);
devicetree_size = uap->devicetree_size;
@@ -612,6 +610,7 @@ int ok_go(void *p, struct args *uap, int32_t *retval) {
*retval = phase_1();
if(*retval) {
IOFreeContiguous(kern_hdr, uap->kern_size);
+ IOFreeContiguous(pagetable_storage, 0x4000);
kfree(devicetree, uap->devicetree_size);
}
return 0;

0 comments on commit 737fd79

Please sign in to comment.