Skip to content

Commit

Permalink
-3
Browse files Browse the repository at this point in the history
  • Loading branch information
comex committed Jul 13, 2011
1 parent bd67c89 commit 057d8eb
Show file tree
Hide file tree
Showing 15 changed files with 392 additions and 148 deletions.
12 changes: 9 additions & 3 deletions catalog/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@ def dbg_result():
sysent = dmini.cur.find('- 00 10 86 00') + 4

code_addr = 0x80000400
weirdfile = dmini.Connection(kcode, rw=True).relocate(dmini.cur, code_addr).nth_segment(0).data()[:-8]
def my_ls(binary, sym):
if sym == '_chgproccnt':
# I'm lazy, make this strref later
result = dmini.cur.find('+ f0 b5 03 af 2d e9 00 0d .. .. .. .. 05 46 8a 46 4f f0 00 08')
print hex(result)
return result
weirdfile = dmini.Connection(kcode, rw=True).relocate(dmini.cur, code_addr, my_ls).nth_segment(0).data()[:-8]
count = 0
stuff = ''
while True:
Expand Down Expand Up @@ -122,7 +128,7 @@ def seek_kernel_ldm(reg):
set_fwd('PC', code_addr)


kstuff = finalize(None, must_be_simple=False, should_heapdump=True);
kstuff = finalize(None, must_be_simple=False, should_heapdump=False)
kstuff.append('\0'*1024)

def set_cache(cachefile):
Expand Down Expand Up @@ -313,6 +319,6 @@ def do_main_thing():
init_sp = 0x10031000
address = 0x8000

final = finalize(address, should_heapdump=True)
final = finalize(address, should_heapdump=False)
open(outfile, 'w').write(pickle.dumps({'segment': final, 'initializer': initializer, 'init_sp': init_sp, 'rop_address': address, 'libs': lib_paths, 'dylib': False}))

4 changes: 4 additions & 0 deletions catalog/kcode.S
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ syscall_0:
ldr r0, [r0, #c(0x6c, 0x80)]
cmp r0, #0
strne r1, [r0, #8]
# I don't care about mobile staying alive, but I do care about the reference count dropping
#mov r0, #0
#mov r1, #1
#bl _chgproccnt
#endif
ldr r0, sysent
ldr r1, [r0, #0xc4]
Expand Down
23 changes: 15 additions & 8 deletions common/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,33 @@
#ifndef _log
#define _log(args...) fprintf(stderr, args)
#endif
#ifndef _fail
#define _fail(name) exit(1)
#endif

#define LINENO lineno1(__FILE__, __LINE__)
#define lineno1(f, l) lineno2(f, l)
#define lineno2(f, l) f ":" #l

#define _assert(expr, arg...) ((expr) ?: (_assert_helper(#expr, arg + 0), (typeof(expr)) 0))
#define _assert(expr, arg...) ((expr) ?: (_assert_helper(#expr, LINENO, arg + 0), (typeof(expr)) 0))
#define _assert_zero(expr, arg...) do { typeof(expr) _value = (expr); \
if(_value) _assert_zero_helper(#expr, arg + 0, (unsigned int) _value); \
if(_value) _assert_zero_helper(#expr, LINENO, arg + 0, (unsigned int) _value); \
} while(0)
#ifdef NO_ASSERT_MESSAGES
#define _assert_helper(...) abort()
#define _assert_zero_helper(...) abort()
#else

__attribute__((noreturn))
static void _assert_helper(const char name[], const char *arg) {
_log("assertion failed: %s%s%s%s (errno=%s)\n", name, arg ? "[" : "", arg ? arg : "", arg ? "]" : "", strerror(errno));
exit(1);
static void _assert_helper(const char name[], const char lineno[], const char *arg) {
_log("assertion failed (%s): %s%s%s%s (errno=%s)\n", lineno, name, arg ? "[" : "", arg ? arg : "", arg ? "]" : "", strerror(errno));
_fail(name);
}

__attribute__((noreturn))
static void _assert_zero_helper(const char name[], const char *arg, unsigned int value) {
_log("assertion failed: %s%s%s%s (value=0x%x, errno=%s)\n", name, arg ? "[" : "", arg ? arg : "", arg ? "]" : "", value, strerror(errno));
exit(1);
static void _assert_zero_helper(const char name[], const char lineno[], const char *arg, unsigned int value) {
_log("assertion failed (%s): %s%s%s%s (value=0x%x, errno=%s)\n", lineno, name, arg ? "[" : "", arg ? arg : "", arg ? "]" : "", value, strerror(errno));
_fail(name);
}

#endif
Expand Down
2 changes: 1 addition & 1 deletion data
Submodule data updated 2 files
+1 −1 Makefile.common
+12 −11 mach-o/binary.c
4 changes: 2 additions & 2 deletions fs/fs.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// whether to spam the syslog/dmesg with printfs
#define DEBUG_PRINTF 0
#define LOCKSPAM 0

#define IS_64BIT_PROCESS(x) 0
#include <sys/buf_internal.h>
Expand All @@ -26,8 +27,7 @@ asm("$strref_22_76_6e_6f_64_65_5f_63_72_65_61_74_65_3a_20_75_6e_6b_6e_6f_77_6e_2
// '"vnode_create: unknown vtype %d'
#define vn_create x_vn_create

#if 0

#if LOCKSPAM
static void x_lck_mtx_lock(lck_mtx_t *lck) {
printf("About to lock %p\n", lck);
lck_mtx_lock(lck);
Expand Down
130 changes: 130 additions & 0 deletions fs/union/splice.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/kauth.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/vnode_internal.h>
#include <sys/mount_internal.h>
#include <sys/namei.h>
#include <sys/malloc.h>
#include <sys/buf_internal.h>
#include <sys/queue.h>
#include <sys/lock.h>
#include "union.h"
#include <sys/mount_internal.h>
#include <stdbool.h>
#include <mach-o/loader.h>
#include <mach-o/nlist.h>

#define CMD_ITERATE(hdr, cmd) for(struct load_command *cmd = (struct load_command *)((hdr) + 1), *end = (struct load_command *)((char *)(hdr + 1) + (hdr)->sizeofcmds); cmd < end; cmd = (struct load_command *)((char *)cmd + cmd->cmdsize))

extern struct {
int maxvfsconf;
struct vfstable *vfsconf;
} stuff

#ifdef IPAD2
// this stuff was modified prior to the dump, it's not a real difference
asm("$in___DATA__11_00_00_00_03_00_00_00_C_15_00_00_00");
#else
asm("$in___DATA__11_00_00_00_00_00_00_00_C_11_00_00_00");
#endif

extern int union_lookup(struct vnop_lookup_args *ap);
extern lck_mtx_t * union_mtxp;
extern LIST_HEAD(unhead, union_node) *unhead;
extern int *unvplock;
extern int (**union_vnodeop_p)(void *);

static void *sym(void *ptr, const char *find) {
union {
uintptr_t addr;
struct mach_header *mh;
} u;
u.addr = ((uintptr_t) ptr) & ~0xfff;
// search for the header
while(!(u.mh->magic == MH_MAGIC && u.mh->cputype == CPU_TYPE_ARM && u.mh->cpusubtype == CPU_SUBTYPE_ARM_V7)) {
u.addr -= 0x1000;
}
uint32_t le_begin = 0, le_end = 0;
void *le_ptr = NULL;
struct nlist *syms;
const char *strs;
uint32_t nsyms;
uint32_t slide = 0;

CMD_ITERATE(u.mh, cmd) {
if(cmd->cmd == LC_SEGMENT) {
struct segment_command *sc = (void *) cmd;
if(!slide) slide = sc->vmaddr;
if(!strncmp(sc->segname, "__LINKEDIT", 16)) {
le_begin = sc->fileoff;
le_end = le_begin + sc->filesize;
le_ptr = (void *) sc->vmaddr;
}
} else if(cmd->cmd == LC_SYMTAB) {
struct symtab_command *sc = (void *) cmd;
if(le_ptr && sc->symoff >= le_begin && sc->symoff < le_end && sc->stroff >= le_begin && sc->stroff < le_end) {
syms = le_ptr + (sc->symoff - le_begin);
strs = le_ptr + (sc->stroff - le_begin);
nsyms = sc->nsyms;
goto ok;
}
}
}
IOLog("couldn't find syms\n");
return 0;
ok:;
size_t findlen = strlen(find);
for(uint32_t i = 0; i < nsyms; i++) {
const char *name = strs + syms[i].n_un.n_strx;
if(!strncmp(name, find, findlen) && (name[findlen] == 0 || name[findlen] == '.')) {
return (void *) syms[i].n_value + slide;
}
}
return NULL;
}

bool splice() {
int real_maxvfsconf = 0;
struct vfstable *union_tbl = NULL;
for(struct vfstable *tbl = stuff.vfsconf; tbl; tbl = tbl->vfc_next) {
if(tbl->vfc_typenum >= real_maxvfsconf) real_maxvfsconf = tbl->vfc_typenum;
if(!strncmp(tbl->vfc_name, "unionfs", MFSNAMELEN)) union_tbl = tbl;
}
stuff.maxvfsconf = real_maxvfsconf + 1;

if(!union_tbl) return false;

IOLog("Replacing union_lookup...\n");

struct nameidata nd;
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, (user_addr_t) "/Applications", vfs_context_current());
int error;
if(error = namei(&nd)) {
IOLog("couldn't look up /Applications\n");
return true;
}
nameidone(&nd);
if(nd.ni_vp->v_mount->mnt_vtable != union_tbl) {
IOLog("/Applications is not unionfs\n");
goto end;
}
void **lookup = (void **) &nd.ni_vp->v_op[vnop_lookup_desc.vdesc_offset];

void *old = *lookup;
union_mtxp = *(void **)sym(*lookup, "_union_mtxp");
unhead = sym(*lookup, "_unhead_storage") ?: sym(*lookup, "_unhead");
unvplock = sym(*lookup, "_unvplock_storage") ?: sym(*lookup, "_unvplock");
union_vnodeop_p = *(void **)sym(*lookup, "_union_vnodeop_p");

IOLog("union_mtxp = %p head=%p vplock=%p ul=%p\n", union_mtxp, unhead, unvplock, union_lookup);
*lookup = &union_lookup;
end:
vnode_put(nd.ni_vp);

return true;
}
7 changes: 3 additions & 4 deletions fs/union/union_subr.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@
#include <security/mac_framework.h>
#endif


static int union_vn_close(struct vnode *vp, int fmode, vfs_context_t ctx);

/* must be power of two, otherwise change UNION_HASH() */
Expand All @@ -105,13 +104,13 @@ static int union_vn_close(struct vnode *vp, int fmode, vfs_context_t ctx);
#define UNION_HASH(u, l) \
(((((uintptr_t) (u)) + ((uintptr_t) l)) >> 8) & (NHASH-1))

static LIST_HEAD(unhead, union_node) unhead[NHASH];
static int unvplock[NHASH];
LIST_HEAD(unhead, union_node) unhead_storage[NHASH], *unhead = unhead_storage;
int unvplock_storage[NHASH], *unvplock = unvplock_storage;

static lck_grp_t * union_lck_grp;
static lck_grp_attr_t * union_lck_grp_attr;
static lck_attr_t * union_lck_attr;
static lck_mtx_t * union_mtxp;
lck_mtx_t * union_mtxp;

static int union_dircheck(struct vnode **, struct fileproc *, vfs_context_t ctx);
static void union_newlower(struct union_node *, struct vnode *);
Expand Down
8 changes: 7 additions & 1 deletion fs/union/union_vfsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@
#include <sys/malloc.h>
#include <sys/filedesc.h>
#include <sys/queue.h>
#include <stdbool.h>
#include <sys/mount_internal.h>
#include "union.h"

static int union_itercallback(vnode_t, void *);
Expand Down Expand Up @@ -574,15 +576,18 @@ struct vfs_fsentry fe = {
descs,
15,
"unionfs",
VFS_TBLTHREADSAFE,
VFS_TBLTHREADSAFE | VFS_TBLNOTYPENUM,
{NULL, NULL}
};

extern void init_vnodeop_entries();

extern bool splice();

vfstable_t ft;
__attribute__((constructor))
static void init() {
if(splice()) return;
init_vnodeop_entries();
printf("vfs_fsadd: %d\n", vfs_fsadd(&fe, &ft));
printf("whiteout: %p\n", &vnop_whiteout_desc);
Expand All @@ -594,3 +599,4 @@ static void fini() {
printf("vfs_fsremove: %d\n", vfs_fsremove(ft));
union_dircheckp = NULL;
}

Loading

0 comments on commit 057d8eb

Please sign in to comment.