func NewUnicorn(arch *models.Arch, os *models.OS, order binary.ByteOrder) (*Unicorn, error) { Uc, err := uc.NewUnicorn(arch.UC_ARCH, arch.UC_MODE) if err != nil { return nil, err } return &Unicorn{ Unicorn: Uc, arch: arch, OS: os, bits: arch.Bits, Bsz: arch.Bits / 8, order: order, memio: memio.NewMemIO( // ReadAt() callback func(p []byte, addr uint64) (int, error) { if err := Uc.MemReadInto(p, addr); err != nil { return 0, err } return len(p), nil }, // WriteAt() callback func(p []byte, addr uint64) (int, error) { if err := Uc.MemWrite(addr, p); err != nil { return 0, err } return len(p), nil }, ), }, nil }
func NewUsercornRaw(l models.Loader, config *models.Config) (*Usercorn, error) { config = config.Init() a, OS, err := arch.GetArch(l.Arch(), l.OS()) if err != nil { return nil, err } unicorn, err := NewUnicorn(a, OS, l.ByteOrder()) if err != nil { return nil, err } u := &Usercorn{ Unicorn: unicorn, traceMatching: true, config: config, loader: l, exit: 0xffffffffffffffff, } if config.Output == os.Stderr && readline.IsTerminal(int(os.Stderr.Fd())) { config.Color = true } u.memio = memio.NewMemIO( // ReadAt() callback func(p []byte, addr uint64) (int, error) { if err := u.MemReadInto(p, addr); err != nil { return 0, err } if u.config.TraceMemBatch { u.memlog.UpdateBytes(addr, p, false) } return len(p), nil }, // WriteAt() callback func(p []byte, addr uint64) (int, error) { if err := u.MemWrite(addr, p); err != nil { return 0, err } if u.config.TraceMemBatch { u.memlog.UpdateBytes(addr, p, true) } return len(p), nil }, ) // load kernels // the array cast is a trick to work around circular imports if OS.Kernels != nil { kernelI := OS.Kernels(u) kernels := make([]co.Kernel, len(kernelI)) for i, k := range kernelI { kernels[i] = k.(co.Kernel) } u.kernels = kernels } u.status = models.StatusDiff{U: u} if u.config.LoopCollapse > 0 { u.blockloop = models.NewLoopDetect(u.config.LoopCollapse) } // TODO: if we error, should close Usercorn/Unicorn instance? // GC might take its time if err := u.mapStack(); err != nil { return nil, err } if err := u.addHooks(); err != nil { return nil, err } return u, nil }