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 StackArgs(u models.Usercorn) func(n int) ([]uint64, error) { return func(n int) ([]uint64, error) { sp, _ := u.RegRead(u.Arch().SP) // starts with an empty slot s := u.StrucAt(sp + uint64(u.Bits()/8)) ret := make([]uint64, n) for i := 0; i < n; i++ { var arg uint64 var err error // TODO: simplify this when struc issue #47 is fixed if u.Bits() == 64 { err = s.Unpack(&arg) } else { var arg32 uint32 err = s.Unpack(&arg32) arg = uint64(arg32) } if err != nil { return nil, err } ret[i] = arg } return ret, nil } }
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 }