func StackInit(u models.Usercorn, args, env []string, auxv []byte) error { // push argv and envp strings envp, err := pushStrings(u, env...) if err != nil { return err } argv, err := pushStrings(u, args...) if err != nil { return err } // align stack pointer sp, _ := u.RegRead(u.Arch().SP) u.RegWrite(u.Arch().SP, (sp & ^uint64(15))) // end marker if _, err := u.Push(0); err != nil { return err } // auxv if len(auxv) > 0 { if _, err := u.PushBytes(auxv); err != nil { return err } } // envp if err := pushAddrs(u, envp); err != nil { return err } // argv if err := pushAddrs(u, argv); err != nil { return err } // argc _, err = u.Push(uint64(len(args))) return err }
func pushStrings(u models.Usercorn, args ...string) ([]uint64, error) { addrs := make([]uint64, 0, len(args)+1) for _, arg := range args { if addr, err := u.PushBytes([]byte(arg + "\x00")); err != nil { return nil, err } else { addrs = append(addrs, addr) } } return addrs, nil }
func setupElfAuxv(u models.Usercorn) ([]Elf64Auxv, error) { // set up AT_RANDOM var tmp [16]byte if _, err := rand.Read(tmp[:]); err != nil { return nil, err } randAddr, err := u.PushBytes(tmp[:]) if err != nil { return nil, err } // insert platform string platformAddr, err := u.PushBytes([]byte(u.Loader().Arch() + "\x00")) if err != nil { return nil, err } // main auxv table auxv := []Elf64Auxv{ // TODO: set/track a page size somewhere - on Arch.OS? {ELF_AT_PAGESZ, 4096}, {ELF_AT_BASE, u.InterpBase()}, {ELF_AT_FLAGS, 0}, {ELF_AT_ENTRY, uint64(u.BinEntry())}, {ELF_AT_UID, uint64(os.Getuid())}, {ELF_AT_EUID, uint64(os.Geteuid())}, {ELF_AT_GID, uint64(os.Getgid())}, {ELF_AT_EGID, uint64(os.Getegid())}, {ELF_AT_PLATFORM, platformAddr}, {ELF_AT_CLKTCK, 100}, // 100hz, totally fake {ELF_AT_RANDOM, randAddr}, {ELF_AT_NULL, 0}, } // add phdr information if present in binary phdrOff, _, phdrCount := u.Loader().Header() segments, _ := u.Loader().Segments() for _, s := range segments { if s.ContainsPhys(phdrOff) { phdrOff += s.Addr break } } phdrEnt := 56 if u.Bits() == 32 { phdrEnt = 56 // FIXME } if phdrOff > 0 { auxv = append(auxv, []Elf64Auxv{ {ELF_AT_PHDR, phdrOff}, {ELF_AT_PHENT, uint64(phdrEnt)}, {ELF_AT_PHNUM, uint64(phdrCount)}, }...) } return auxv, nil }
func StackInit(u models.Usercorn, args, env []string) error { exe := u.Exe() addr, err := u.PushBytes([]byte(exe + "\x00")) if err != nil { return err } var tmp [8]byte auxv, err := u.PackAddr(tmp[:], addr) if err != nil { return err } err = posix.StackInit(u, args, env, auxv) if err != nil { return err } // offset to mach_header at exe[0:] in guest memory textOffset, _, _ := u.Loader().Header() offset := u.Base() + textOffset _, err = u.Push(offset) return err }
func StackInit(u models.Usercorn, args, env []string, auxv []byte) error { if _, err := u.Push(0); err != nil { return err } if len(args) > 0 { if _, err := u.PushBytes([]byte(args[0] + "\x00")); err != nil { return err } } // push argv and envp strings envp, err := pushStrings(u, env...) if err != nil { return err } argv, err := pushStrings(u, args...) if err != nil { return err } // precalc envp -> argc for stack alignment envpb, err := packAddrs(u, envp) if err != nil { return err } argvb, err := packAddrs(u, argv) if err != nil { return err } var tmp [8]byte argcb, err := u.PackAddr(tmp[:], uint64(len(argv))) init := append(argcb, argvb...) init = append(init, envpb...) // align stack pointer sp, _ := u.RegRead(u.Arch().SP) sp &= ^uint64(15) off := len(init) & 15 if off > 0 { sp -= uint64(16 - off) } u.RegWrite(u.Arch().SP, sp) // auxv if len(auxv) > 0 { if _, err := u.PushBytes(auxv); err != nil { return err } } // write envp -> argc u.PushBytes(init) return err }