Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

omg it works

  • Loading branch information...
commit d8ffd259fcd21d2c378c6075af42f32c4837f622 1 parent 30ce92a
@comex authored
View
2,713 elf.h
0 additions, 2,713 deletions not shown
View
3  ent.plist
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0"><dict><key>get-task-allow</key><true/><key>run-unsigned-code</key><true/><key>task_for_pid-allow</key><true/></dict></plist>
View
6 kasm.S
@@ -1,6 +0,0 @@
-.thumb
-.syntax unified
-.section .init
-stub:
- b mysyscall
-
View
28 kcode.c
@@ -33,9 +33,9 @@ int weird_hook(char *buf, int size) {
int ret = weird_old(buf, size);
IOLog("weird_old: [%x] ", size);
while(size--) {
- IOLog("%02c ", *buf++);
+ IOLog("%02x ", (int) *buf++);
}
- IOLog("=> %d\n", ret);
+ IOLog("=> %x\n", ret);
return ret;
}
@@ -69,7 +69,25 @@ static int list_iosurfaces() {
return 0;
}
-__attribute__((externally_visible))
+// from the loader
+extern struct sysent sysent[];
+
+int mysyscall(void *p, struct mysyscall_args *uap, int32_t *retval);
+__attribute__((constructor))
+void init() {
+ IOLog("init\n");
+ sysent[8] = (struct sysent){ 1, 0, 0, (void *) mysyscall, NULL, NULL, _SYSCALL_RET_INT_T, 5 * sizeof(uint32_t) };
+
+}
+
+__attribute__((destructor))
+void fini() {
+ IOLog("fini\n");
+ unhook(logger_old); logger_old = NULL;
+ unhook(vm_fault_enter_old); vm_fault_enter_old = NULL;
+ unhook(weird_old); weird_old = NULL;
+}
+
int mysyscall(void *p, struct mysyscall_args *uap, int32_t *retval)
{
//IOLog("Hi mode=%d\n", uap->mode);
@@ -122,9 +140,7 @@ int mysyscall(void *p, struct mysyscall_args *uap, int32_t *retval)
break;
}
case 6: { // unhook
- unhook(logger_old); logger_old = NULL;
- unhook(vm_fault_enter_old); vm_fault_enter_old = NULL;
- unhook(weird_old); weird_old = NULL;
+ fini();
break;
}
case 7: { // hook a function, log args
View
35 kinc.h
@@ -1,7 +1,5 @@
#include <stdint.h>
#include <stdbool.h>
-// This is stupid and generates wasteful code, but is necessary. The BL instruction generated otherwise treats it as ARM and ignores the least-significant bit.
-// A proper solution is apparently making the generated symbol have the right attribute, but I can't do that without... manually generating an ELF file?
#define LC __attribute__((long_call))
typedef uint32_t user_addr_t, vm_size_t, vm_address_t, boolean_t, size_t, vm_offset_t, vm_prot_t;
@@ -33,19 +31,19 @@ typedef enum IODirection {
} IODirection;
LC void *IOMemoryDescriptor_withPhysicalAddress(unsigned long address, unsigned long withLength, IODirection withDirection)
-asm("_ZN18IOMemoryDescriptor19withPhysicalAddressEmm11IODirection");
+asm("__ZN18IOMemoryDescriptor19withPhysicalAddressEmm11IODirection");
LC void *IOMemoryDescriptor_map(void *descriptor, unsigned int options)
-asm("_ZN18IOMemoryDescriptor3mapEm");
+asm("__ZN18IOMemoryDescriptor3mapEm");
LC void *IOMemoryDescriptor_getPhysicalAddress(void *descriptor)
-asm("_ZN18IOMemoryDescriptor18getPhysicalAddressEv");
+asm("__ZN18IOMemoryDescriptor18getPhysicalAddressEv");
LC void *IOMemoryMap_getAddress(void *map)
-asm("_ZN11IOMemoryMap10getAddressEv");
+asm("__ZN11IOMemoryMap10getAddressEv");
LC void *IORegistryEntry_fromPath(const char *name, void *plane, char *residualPath, int *residualLength, void *fromEntry)
-asm("_ZN15IORegistryEntry8fromPathEPKcPK15IORegistryPlanePcPiPS_");
+asm("__ZN15IORegistryEntry8fromPathEPKcPK15IORegistryPlanePcPiPS_");
static inline void delete_object(void *object) {
((void (***)(void *)) object)[0][1](object);
@@ -60,6 +58,29 @@ static inline void *retain_object(void *object) {
return object;
}
+// copied from xnu
+
+struct proc;
+typedef int32_t sy_call_t(struct proc *, void *, int *);
+typedef void sy_munge_t(const void *, void *);
+
+struct sysent { /* system call table */
+ int16_t sy_narg; /* number of args */
+ int8_t sy_resv; /* reserved */
+ int8_t sy_flags; /* flags */
+ sy_call_t *sy_call; /* implementing function */
+ sy_munge_t *sy_arg_munge32; /* system call arguments munger for 32-bit process */
+ sy_munge_t *sy_arg_munge64; /* system call arguments munger for 64-bit process */
+ int32_t sy_return_type; /* system call return types */
+ uint16_t sy_arg_bytes; /* Total size of arguments in bytes for
+ * 32-bit system calls
+ */
+};
+#define _SYSCALL_RET_INT_T 1
+
+// end copied
+
+
#define prop(a, off, typ) *((typ *)(((char *) (a))+(off)))
#define NULL ((void *) 0)
View
360 loader.c
@@ -5,11 +5,17 @@
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
-#include "elf.h"
+#include <stdbool.h>
+#include <mach-o/loader.h>
+#include <mach-o/nlist.h>
+#include <mach-o/reloc.h>
+#include <mach/mach.h>
+#include <sys/mman.h>
+#include <sys/file.h>
-struct proc;
// copied from xnu
+struct proc;
typedef int32_t sy_call_t(struct proc *, void *, int *);
typedef void sy_munge_t(const void *, void *);
@@ -29,48 +35,328 @@ struct sysent { /* system call table */
// end copied
-// search for 01 00 00 00 0c 00 00 00
+const uint32_t SLIDE_START = 0xf0000000;
+
+mach_port_t kernel_task;
-struct sysent my_sysent = { 1, 0, 0, NULL, NULL, NULL, _SYSCALL_RET_INT_T, 5 * sizeof(uint32_t) };
+struct mach_header *hdr, *khdr;
+struct symtab_command symtab, ksymtab;
+struct dysymtab_command dysymtab;
+uint32_t slide;
-void xread(int fd, void *buf, size_t nbyte) {
- errno = 0;
- int ret = read(fd, buf, nbyte);
- if(errno) perror("xread");
- assert(ret == nbyte);
+uint32_t sysent; // :<
+
+void *map_file(const char *name) {
+ int fd = open(name, O_RDONLY);
+ if(fd <= 0) {
+ fprintf(stderr, "unable to open %s: %s\n", name, strerror(errno));
+ assert(false);
+ }
+ off_t end = lseek(fd, 0, SEEK_END);
+ void *result = mmap(NULL, (size_t) end, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ assert(result != MAP_FAILED);
+ return result;
}
+kern_return_t kr_assert_(kern_return_t kr, const char *name, int line) {
+ if(kr) {
+ fprintf(stderr, "kr_assert: result=%08x on line %d:\n%s\n", kr, line, name);
+ assert(false);
+ }
+ return kr;
+}
+#define kr_assert(x) kr_assert_((x), #x, __LINE__)
-int main() {
- assert(sizeof(struct sysent) == 0x18);
- int k = open("/dev/kmem", O_WRONLY);
- assert(k > 0);
-
- Elf32_Ehdr ehdr;
- Elf32_Shdr shdr;
- int fd = open("kcode.elf", O_RDONLY);
- assert(fd > 0);
- xread(fd, &ehdr, sizeof(ehdr));
- assert(ehdr.e_shentsize == sizeof(shdr));
- lseek(fd, ehdr.e_shoff, SEEK_SET);
- Elf32_Half shnum = ehdr.e_shnum;
- while(shnum--) {
- xread(fd, &shdr, sizeof(shdr));
- if(shdr.sh_type == SHT_PROGBITS) {
- if(!my_sysent.sy_call) my_sysent.sy_call = (void *) (shdr.sh_addr | 1);
- void *buf = malloc(shdr.sh_size);
- assert(pread(fd, buf, shdr.sh_size, shdr.sh_offset) == shdr.sh_size);
- assert(pwrite(k, buf, shdr.sh_size, shdr.sh_addr) == shdr.sh_size);
- free(buf);
- } else if(shdr.sh_type == SHT_NOBITS) {
- void *buf = calloc(1, shdr.sh_size);
- assert(pwrite(k, buf, shdr.sh_size, shdr.sh_addr) == shdr.sh_size);
- free(buf);
+#define CMD_ITERATE(hdr, cmd) for(struct load_command *cmd = (void *)((hdr) + 1), *end = (void *)((char *)(hdr) + (hdr)->sizeofcmds); cmd < end; cmd = (void *)((char *)(cmd) + cmd->cmdsize))
+
+uint32_t lookup_sym(const char *name) {
+ // I stole dyld's codez (and then my own)
+ if(!strcmp(name, "_sysent")) {
+ return sysent;
+ }
+ const struct nlist *base = (void *) ((char *)khdr + ksymtab.symoff);
+ for(uint32_t n = ksymtab.nsyms; n > 0; n /= 2) {
+ const struct nlist *pivot = base + n/2;
+ uint32_t strx = pivot->n_un.n_strx;
+ assert(strx < ksymtab.strsize);
+ const char *pivot_str = (char *)khdr + ksymtab.stroff + strx;
+ int cmp = strncmp(name, pivot_str, ksymtab.strsize - strx);
+ if(cmp == 0) {
+ // we found it
+ uint32_t result = pivot->n_value;
+ if(pivot->n_desc & N_ARM_THUMB_DEF) {
+ result |= 1;
+ }
+ return result;
+ } else if(cmp > 0) {
+ base = pivot + 1;
+ n--;
+ }
+ }
+ fprintf(stderr, "sym: symbol %s not found\n", name);
+ assert(false);
+}
+
+void do_kern(const char *filename) {
+ khdr = map_file(filename);
+
+ bool got_symtab = false;
+
+ CMD_ITERATE(khdr, cmd) {
+ switch(cmd->cmd) {
+ case LC_SYMTAB:
+ assert(!got_symtab);
+ ksymtab = *((struct symtab_command *) cmd);
+ got_symtab = true;
+ break;
+ case LC_SEGMENT: {
+ if(sysent) continue;
+ struct segment_command *seg = (void *) cmd;
+ struct section *sections = (void *) (seg + 1);
+ for(int i = 0; i < seg->nsects; i++) {
+ struct section *sect = &sections[i];
+ if(!strncmp(sect->sectname, "__data", 16)) {
+ uint32_t *things = (void *) ((char *)khdr + sect->offset);
+ for(int i = 0; i < sect->size / 4; i++) {
+ if(things[i] == 0x861000) {
+ sysent = sect->addr + 4*i + 4;
+ goto nextlc;
+ }
+ }
+ }
+ }
+ nextlc:
+ break;
+ }
+ }
+ }
+
+ assert(got_symtab);
+ assert(sysent);
+}
+
+void do_kcode(const char *filename) {
+ hdr = map_file(filename);
+
+ bool got_symtab = false, got_dysymtab = false;
+
+ CMD_ITERATE(hdr, cmd) {
+ switch(cmd->cmd) {
+ case LC_SYMTAB:
+ symtab = *((struct symtab_command *) cmd);
+ got_symtab = true;
+ break;
+ case LC_DYSYMTAB:
+ dysymtab = *((struct dysymtab_command *) cmd);
+ got_dysymtab = true;
+ break;
+ case LC_SEGMENT:
+ case LC_ID_DYLIB:
+ case LC_UUID:
+ break;
+ default:
+ fprintf(stderr, "unrecognized load command %08x\n", cmd->cmd);
+ assert(false);
+ }
+ }
+ assert(got_symtab);
+ assert(got_dysymtab);
+
+ // try to reserve some space
+ for(slide = SLIDE_START; slide < SLIDE_START + 0x01000000; slide += 0x10000) {
+ CMD_ITERATE(hdr, cmd) {
+ if(cmd->cmd == LC_SEGMENT) {
+ struct segment_command *seg = (void *) cmd;
+ if(seg->vmsize == 0) continue;
+ vm_address_t address = seg->vmaddr + slide;
+ printf("allocate %08x %08x\n", (int) address, (int) seg->vmsize);
+ kern_return_t kr = vm_allocate(kernel_task,
+ &address,
+ seg->vmsize,
+ VM_FLAGS_FIXED);
+ if(!kr) {
+ assert(address == seg->vmaddr + slide);
+ continue;
+ }
+ // Bother, it didn't work. So we need to increase the slide...
+ // But first we need to get rid of the gunk we did manage to allocate.
+ CMD_ITERATE(hdr, cmd2) {
+ if(cmd2 == cmd) break;
+ if(cmd2->cmd == LC_SEGMENT) {
+ struct segment_command *seg2 = (void *) cmd2;
+ printf("deallocate %08x %08x\n", (int) (seg->vmaddr + slide), (int) seg->vmsize);
+ kr_assert(vm_deallocate(kernel_task,
+ seg->vmaddr + slide,
+ seg->vmsize));
+ }
+ }
+ goto try_another_slide;
+ }
}
+ // If we got this far, it worked!
+ goto it_worked;
+ try_another_slide:;
}
+ // But if we got this far, we ran out of slides to try.
+ fprintf(stderr, "we couldn't find anywhere to put this thing and that is ridiculous\n");
+ assert(false);
+ it_worked:;
+ printf("slide=%x\n", slide);
+
+ struct nlist *syms = (void *) ((char *)hdr + symtab.symoff);
+ uint32_t *indirect = (void *) ((char *)hdr + dysymtab.indirectsymoff);
+
+ CMD_ITERATE(hdr, cmd) {
+ if(cmd->cmd == LC_SEGMENT) {
+ struct segment_command *seg = (void *) cmd;
+ seg->vmaddr += slide;
+ printf("%.16s %08x\n", seg->segname, seg->vmaddr);
+ struct section *sections = (void *) (seg + 1);
+ for(int i = 0; i < seg->nsects; i++) {
+ struct section *sect = &sections[i];
+ sect->addr += slide;
+ printf(" %.16s\n", sect->sectname);
+ uint8_t type = sect->flags & SECTION_TYPE;
+ switch(type) {
+ case S_NON_LAZY_SYMBOL_POINTERS: {
+ uint32_t indirect_table_offset = sect->reserved1;
+ uint32_t *things = (void *) ((char *)hdr + sect->offset);
+ for(int i = 0; i < sect->size / 4; i++) {
+ things[i] = lookup_sym((char *)hdr + symtab.stroff + syms[indirect[indirect_table_offset+i]].n_un.n_strx);
+ }
+ break;
+ }
+ case S_ZEROFILL: {
+ void *data = calloc(1, sect->size);
+ kr_assert(vm_write(kernel_task,
+ (vm_address_t) sect->addr,
+ (vm_offset_t) data,
+ sect->size));
+ free(data);
+ break;
+ }
+ case S_MOD_INIT_FUNC_POINTERS:
+ case S_MOD_TERM_FUNC_POINTERS: {
+ uint32_t *things = (void *) ((char *)hdr + sect->offset);
+ for(int i = 0; i < sect->size / 4; i++) {
+ things[i] += slide;
+ }
+ break;
+ }
+ case S_REGULAR:
+ case S_CSTRING_LITERALS:
+ case S_4BYTE_LITERALS:
+ case S_8BYTE_LITERALS:
+ case S_16BYTE_LITERALS:
+ break;
+ default:
+ fprintf(stderr, "unrecognized section type %02x\n", type);
+ assert(false);
+ }
+ struct relocation_info *things = (void *) ((char *)hdr + sect->reloff);
+ for(int i = 0; i < sect->nreloc; i++) {
+ assert(!things[i].r_extern && !things[i].r_pcrel && things[i].r_length == 2);
+ assert(things[i].r_type == 0);
+ *((uint32_t *) ((char *)hdr + sect->offset + things[i].r_address)) += slide;
+ }
+ }
+ int32_t fs = seg->filesize;
+ vm_offset_t of = (vm_offset_t)hdr + seg->fileoff;
+ vm_address_t ad = seg->vmaddr;
+ while(fs > 0) {
+ // complete headbang.
+ printf("reading %x -> %08x\n", fs, (uint32_t) of);
+ uint32_t tocopy = 0xfff;
+ if(fs < tocopy) tocopy = seg->filesize;
+ kr_assert(vm_write(kernel_task,
+ ad,
+ of,
+ tocopy));
+ fs -= tocopy;
+ of += tocopy;
+ ad += tocopy;
+ }
+ if(seg->vmsize > 0) {
+ kr_assert(vm_protect(kernel_task,
+ seg->vmaddr,
+ seg->vmsize,
+ true,
+ seg->maxprot));
+ kr_assert(vm_protect(kernel_task,
+ seg->vmaddr,
+ seg->vmsize,
+ false,
+ seg->initprot));
+
+ vm_machine_attribute_val_t val = MATTR_VAL_CACHE_FLUSH;
+ kr_assert(vm_machine_attribute(kernel_task,
+ seg->vmaddr,
+ seg->vmsize,
+ MATTR_CACHE,
+ &val));
+ }
+ }
+ }
+
+ // okay, now do the fancy syscall stuff
+ // how do I safely dispose of this file?
+ int lockfd = open("/tmp/.syscall-11", O_RDWR | O_CREAT);
+ assert(lockfd > 0);
+ assert(!flock(lockfd, LOCK_EX));
+
+ struct sysent orig_sysent;
+ vm_size_t whatever;
+ kr_assert(vm_read_overwrite(kernel_task,
+ sysent + 11 * sizeof(struct sysent),
+ sizeof(struct sysent),
+ (vm_offset_t) &orig_sysent,
+ &whatever));
+
+ CMD_ITERATE(hdr, cmd) {
+ if(cmd->cmd == LC_SEGMENT) {
+ struct segment_command *seg = (void *) cmd;
+ struct section *sections = (void *) (seg + 1);
+ for(int i = 0; i < seg->nsects; i++) {
+ struct section *sect = &sections[i];
+
+ if((sect->flags & SECTION_TYPE) == S_MOD_INIT_FUNC_POINTERS) {
+ void **things = (void *) ((char *)hdr + sect->offset);
+ for(int i = 0; i < sect->size / 4; i++) {
+ struct sysent my_sysent = { 1, 0, 0, things[i], NULL, NULL, _SYSCALL_RET_INT_T, 0 };
+ printf("--> %p\n", things[i]);
+ kr_assert(vm_write(kernel_task,
+ sysent + 11 * sizeof(struct sysent),
+ (vm_offset_t) &my_sysent,
+ sizeof(struct sysent)));
+ syscall(11);
+ }
+ }
+ }
+ }
+ }
+
+ kr_assert(vm_write(kernel_task,
+ sysent + 11 * sizeof(struct sysent),
+ (vm_offset_t) &orig_sysent,
+ sizeof(struct sysent)));
+
+ assert(!flock(lockfd, LOCK_UN));
+}
+
+int main() {
+ kr_assert(task_for_pid(mach_task_self(), 0, &kernel_task));
+#if 0
+ void *foo = malloc(4096);
+ printf("%p\n", foo);
+ mach_vm_address_t addr;
+ vm_prot_t cp, mp;
+ kr_assert(vm_remap(mach_task_self(), &addr, 4096, 0xfff, true, kernel_task, 0x8075d000, false, &cp, &mp, VM_INHERIT_NONE));
+ printf("%d %d\n", cp, mp);
+ printf("%x %x\n", *((uint32_t *) addr), *((uint32_t *) (addr + 4)));
+ return 0;
+#endif
+ do_kern("kern");
+ do_kcode("kcode.dylib");
- assert(pwrite(k, &my_sysent, sizeof(struct sysent), SYSENT + 8 * sizeof(struct sysent)) == sizeof(struct sysent));
- close(k);
-
return 0;
}
View
39 make.py
@@ -1,42 +1,15 @@
#!/usr/bin/env python
from fabricate import *
-sources = ['kcode.c', 'kasm.S', 'black.c']
-#scratch = 0xc06ed000
-#sysent = 0xc0255924
-#kern = '/Users/comex/star/bs/iPad1,1_3.2.1/kern'
-
-#scratch = 0xc076c000
-#sysent = 0xc021c678
-#kern = '/Users/comex/star/bs/iPhone1,x_3.1.3/kern'
-
-scratch = 0x8075d000
-sysent = 0x80256aac
-kern = '/Users/comex/star/bs/iPhone3,1_4.0.1/kern'
-
-#scratch = 0x806b4000
-#sysent = 0x80256aac
-#kern = '/Users/comex/star/bs/iPod3,1_4.0/kern'
+sources = ['kcode.c', 'black.c']
whole = True
def build():
- run('gcc-4.2', '-o', 'loader', 'loader.c', '-arch', 'armv7', '-isysroot', '/var/sdk', '-DSYSENT=0x%08x' % sysent)
- run('gcc-4.2', '-std=gnu99', '-o', 'stuff', 'stuff.c', '-arch', 'armv7', '-isysroot', '/var/sdk')
- #run('ldid', '-S', 'loader')
- #run('ldid', '-S', 'stuff')
-
- run('python', 'nm.py', kern, '0x%08x' % scratch)
-
- GCC = ['arm-none-eabi-gcc', '-mthumb', '-march=armv7', '-Os']
- OBJCOPY = 'arm-none-eabi-objcopy'
-
- if whole:
- run(GCC, '-o', 'kcode_.elf', sources, '-std=gnu99', '-fwhole-program', '-combine', '-nostdlib', '-nodefaultlibs', '-lgcc', '-T', 'nm.ld')
- else:
- for source in sources:
- run(GCC, '-std=gnu99', '-c', source)
+ GCC = ['/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2', '-arch', 'armv7', '-Os', '-isysroot', '/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.1.sdk/']
+ run(GCC, '-std=gnu99', '-o', 'loader_', 'loader.c')
+ run('bash', '-c', 'cp loader_ loader; ldid -Sent.plist loader')
+ run(GCC, '-std=gnu99', '-o', 'stuff', 'stuff.c')
- run(GCC, '-o', 'kcode_.elf', [source[:source.find('.')]+'.o' for source in sources], '-nostdlib', '-nodefaultlibs', '-lgcc', '-T', 'nm.ld')
- run('sh', '-c', 'cp kcode_.elf kcode.elf; gstrip kcode.elf')
+ run(GCC, '-dynamiclib', '-o', 'kcode.dylib', sources, '-std=gnu99', '-fwhole-program', '-combine', '-nostdlib', '-nodefaultlibs', '-lgcc', '-undefined', 'dynamic_lookup')
def clean():
autoclean()
View
59 nm.py
@@ -1,59 +0,0 @@
-import mmap, os, struct, re, sys
-# ripped from config.py
-
-class macho:
- 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 = struct.unpack('IIII', stuff.read(16))
- sects.append((vmaddr, foff, fsiz))
- 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 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: continue
- n_strx += self.stroff
- psym = self.stuff[n_strx:self.stuff.find('\0', n_strx)]
- if n_desc & 8:
- # thumb
- n_value |= 1
- yield psym, n_value
-
-filename = sys.argv[1]
-fp = open(filename, 'rb')
-stuff = mmap.mmap(fp.fileno(), os.path.getsize(filename), prot=mmap.PROT_READ)
-m = macho(filename, stuff)
-
-out = open('nm.ld', 'w')
-
-out.write('''SECTIONS {
- . = %s;
- .init : { *(.init) }
- /DISCARD/ : { *(.comment); *(.ARM.attributes) }
-}
-''' % sys.argv[2])
-
-for a, b in m.get_syms():
- if a.startswith('_') and re.match('^[a-zA-Z0-9_@\$]{2,}$', a):
- print >> out, '%s = 0x%08x;' % (a[1:], b)
View
4 stuff.c
@@ -47,7 +47,7 @@ int vmhook_address(uint32_t addr) {
}
int weirdhook_address(uint32_t addr) {
- return syscall(8, 8, addr);
+ return syscall(8, 9, addr);
}
static const char *cacheable(uint32_t flags) {
@@ -184,7 +184,7 @@ int main(int argc, char **argv) {
uint32_t ttbr0, ttbr1, ttbcr, contextidr;
assert(!get_regs(&ttbr0, &ttbr1, &ttbcr, &contextidr));
- while((c = getopt(argc, argv, "r01sl:uh:v:")) != -1)
+ while((c = getopt(argc, argv, "r01sl:uh:v:w:")) != -1)
switch(c) {
case 'r': {
printf("ttbr0=%x ttbr1=%x ttbcr=%x contextidr=%x\n", ttbr0, ttbr1, ttbcr, contextidr);
Please sign in to comment.
Something went wrong with that request. Please try again.