void initGoQmlLib() { HookHandlers p[1]; p->hookIdleTimer = cgoHookIdleTimer; p->hookLogHandler = cgoHookLogHandler; p->hookGoValueReadField = cgoHookGoValueReadField; p->hookGoValueWriteField = cgoHookGoValueWriteField; p->hookGoValueCallMethod = cgoHookGoValueCallMethod; p->hookGoValueDestroyed = cgoHookGoValueDestroyed; p->hookGoValuePaint = cgoHookGoValuePaint; p->hookRequestImage = cgoHookRequestImage; p->hookGoValueTypeNew = cgoHookGoValueTypeNew; p->hookWindowHidden = cgoHookWindowHidden; p->hookSignalCall = cgoHookSignalCall; p->hookSignalDisconnect = cgoHookSignalDisconnect; p->hookPanic = cgoHookPanic; p->hookListPropertyCount = cgoHookListPropertyCount; p->hookListPropertyAt = cgoHookListPropertyAt; p->hookListPropertyAppend = cgoHookListPropertyAppend; p->hookListPropertyClear = cgoHookListPropertyClear; initHooks(p); }
static void *find_lazy(uint32_t ncmds, const struct load_command *cmds, uintptr_t slide) { uint32_t symoff = 0, stroff = 0, isymoff = 0, lazy_index = 0, lazy_size = 0; void **lazy = 0; uint32_t cmdsleft; const struct load_command *lc; uintptr_t thisimage = (uintptr_t) &find_lazy - slide; for(lc = cmds, cmdsleft = ncmds; cmdsleft--;) { if(lc->cmd == LC_SYMTAB) { const struct symtab_command *sc = (void *) lc; stroff = sc->stroff; symoff = sc->symoff; } else if(lc->cmd == LC_DYSYMTAB) { const struct dysymtab_command *dc = (void *) lc; isymoff = dc->indirectsymoff; } else if(lc->cmd == LC_SEGMENT_NATIVE) { const struct segment_command_native *sc = (void *) lc; const struct section_native *sect = (void *) (sc + 1); uint32_t i; if(sc->vmaddr <= thisimage && thisimage < (sc->vmaddr + sc->vmsize)) return 0; for(i = 0; i < sc->nsects; i++) { if((sect->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) { lazy_index = sect->reserved1; lazy_size = sect->size / sizeof(*lazy); lazy = (void *) sect->addr + slide; } sect++; } } lc = (void *) ((char *) lc + lc->cmdsize); } if(!stroff || !symoff || !isymoff || !lazy_index) return 0; #define CATCH(off, addr) if(sc->fileoff <= (off) && (sc->fileoff + sc->filesize) >= (off)) (addr) = (void *) (sc->vmaddr + slide + (off) - sc->fileoff); struct nlist_native *syms = 0; const char *strs = 0; uint32_t *isyms = 0; for(lc = cmds, cmdsleft = ncmds; cmdsleft--;) { if(lc->cmd == LC_SEGMENT_NATIVE) { struct segment_command_native *sc = (void *) lc; CATCH(symoff, syms); CATCH(stroff, strs); CATCH(isymoff, isyms); } lc = (void *) ((char *) lc + lc->cmdsize); } if(!syms || !strs || !isyms) return 0; uint32_t i; for(i = lazy_index; i < lazy_index + lazy_size; i++) { const struct nlist_native *sym = syms + isyms[i]; void *newfunc = initHooks((char *) (strs + sym->n_un.n_strx) + 0x1); if (newfunc != NULL) { *lazy = newfunc; } else { // printf("Unhooked symbol %s\n", (char *) (strs + sym->n_un.n_strx) + 0x1); } lazy++; } return 0; }