Skip to content

Commit

Permalink
more chain stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
comex committed Dec 30, 2010
1 parent 0721920 commit 737fd79
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 21 deletions.
155 changes: 155 additions & 0 deletions binary/binary.py
Original file line number Diff line number Diff line change
@@ -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

41 changes: 20 additions & 21 deletions chain/chain.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 ");
Expand Down Expand Up @@ -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
Expand All @@ -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++) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down

0 comments on commit 737fd79

Please sign in to comment.