Example #1
0
func (e *Executor) run() {
	stackState := e.runner.prog.getStack()
	stackOffset := len(e.runner.stack) - len(stackState)
	copy(e.runner.stack[stackOffset:], stackState)

	resumeResult := 0 // don't resume
	if len(stackState) > 0 {
		resumeResult = -1 // resume; return this value to snapshot function caller
	}

	fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0)
	if err != nil {
		return
	}

	done := make(chan struct{})

	defer func() {
		syscall.Close(fds[1])
		<-done
	}()

	go func() {
		defer close(done)
		e.slave(fds[0], e.sigs, e.printer, e.cont)
	}()

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	setRunArg(e.arg)

	globalsMemoryAddr := (*reflect.SliceHeader)(unsafe.Pointer(&e.runner.globalsMemory)).Data
	memoryAddr := globalsMemoryAddr + uintptr(e.runner.memoryOffset)
	growMemorySize := len(e.runner.globalsMemory) - e.runner.memoryOffset

	trap, memorySize, stackPtr := run(e.runner.prog.getText(), int(e.runner.memorySize), memoryAddr, uintptr(growMemorySize), e.runner.stack, stackOffset, resumeResult, fds[1])

	e.runner.memorySize = wasm.MemorySize(memorySize)
	e.runner.lastTrap = traps.Id(trap)
	e.runner.lastStackPtr = stackPtr

	if trap == 0 {
		e.result = getRunResult()
	} else {
		e.err = e.runner.lastTrap
	}
	return
}
Example #2
0
func PrintTo(w io.Writer, text, funcMap []byte, ns *sections.NameSection) (err error) {
	var names []sections.FunctionName
	if ns != nil {
		names = ns.FunctionNames
	}

	engine, err := gapstone.New(gapstone.CS_ARCH_X86, gapstone.CS_MODE_64)
	if err != nil {
		return
	}
	defer engine.Close()

	err = engine.SetOption(gapstone.CS_OPT_SYNTAX, gapstone.CS_OPT_SYNTAX_ATT)
	if err != nil {
		return
	}

	insns, err := engine.Disasm(text, 0, 0)
	if err != nil {
		return
	}

	targets := map[uint]string{
		16: "start",
	}

	firstFuncAddr := uint(binary.LittleEndian.Uint32(funcMap))

	for i := 0; len(funcMap) > 0; i++ {
		addr := binary.LittleEndian.Uint32(funcMap)
		funcMap = funcMap[4:]

		var name string
		if i < len(names) {
			name = names[i].FunName
		} else {
			name = fmt.Sprintf("func_%d", i)
		}

		targets[uint(addr)] = name
	}

	sequence := 0

	for i := range insns {
		insn := insns[i]
		var name string

		switch {
		case insn.Mnemonic == "jmpq":
			continue

		case strings.HasPrefix(insn.Mnemonic, "j"):

		case insn.Mnemonic == "callq" && strings.HasPrefix(insn.OpStr, "0x"):

		case insn.Address < firstFuncAddr && insn.Mnemonic == "movl" && strings.HasPrefix(insn.OpStr, "$") && strings.HasSuffix(insn.OpStr, ", %eax"):
			var n uint
			fmt.Sscanf(insn.OpStr, "$%d, %%eax", &n)
			if id := traps.Id(n); id < traps.NumTraps {
				targets[insn.Address] = strings.Replace(id.String(), " ", "_", -1)
			}
			continue

		default:
			continue
		}

		addr, err := strconv.ParseUint(insn.OpStr, 0, 32)
		if err != nil {
			panic(err)
		}

		name, found := targets[uint(addr)]
		if !found {
			name = fmt.Sprintf(".L%d", sequence)
			sequence++

			targets[uint(addr)] = name
		}

		insns[i].OpStr = name
	}

	skip := false

	for _, insn := range insns {
		name, found := targets[insn.Address]
		if found {
			if !strings.HasPrefix(name, ".") && name != "exit" {
				fmt.Fprintln(w)
			}
			fmt.Fprintf(w, "%s:\n", name)
		}

		switch insn.Id {
		case gapstone.X86_INS_INT3:
			if skip {
				continue
			}
			skip = true
			fallthrough

		default:
			fmt.Fprintf(w, "\t%s\t%s\n", insn.Mnemonic, insn.OpStr)
		}
	}

	fmt.Fprintln(w)
	return
}