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 (s *Emulator) CreateUnicorn() *errors.Error { if s.mu != nil { s.Close() } mu, err2 := uc.NewUnicorn(s.Config.Arch.ToUnicornArchDescription(), s.Config.Arch.ToUnicornModeDescription()) s.WorkingSet = NewWorkingSet(s.Config.MaxTracePages) if err2 != nil { return errors.Wrap(err2, 0) } s.mu = mu err := s.addHooks() if err != nil { return errors.Wrap(err, 0) } if err := s.ResetMemoryImage(); err != nil { return err } if err := s.ResetWorkingSet(); err != nil { return err } if err := s.ResetRegisters(); err != nil { return err } return nil }
func (a *Arch) SmokeTest(t *testing.T) { u, err := uc.NewUnicorn(a.UC_ARCH, a.UC_MODE) if err != nil { t.Fatal(err) } var testReg = func(name string, enum int) { if u.RegWrite(enum, 0x1000); err != nil { t.Fatal(err) } val, err := u.RegRead(enum) if err != nil { t.Fatal(err) } if val != 0x1000 { t.Fatal(a.Radare + " failed to read/write register " + name) } // clear the register in case registers are aliased if u.RegWrite(enum, 0); err != nil { t.Fatal(err) } } for _, r := range a.getRegList() { testReg(r.Name, r.Enum) } testReg("PC", a.PC) testReg("SP", a.SP) }
func New(ws *W.Workspace) (*Emulator, error) { logrus.Debug("emulator: new") if ws.Arch != W.ARCH_X86 { return nil, W.InvalidArchError } if !(ws.Mode == W.MODE_32 || ws.Mode == W.MODE_64) { return nil, W.InvalidModeError } var u uc.Unicorn var e error if ws.Mode == W.MODE_32 { u, e = uc.NewUnicorn(uc.ARCH_X86, uc.MODE_32) } else if ws.Mode == W.MODE_64 { u, e = uc.NewUnicorn(uc.ARCH_X86, uc.MODE_64) } if e != nil { return nil, e } disassembler, e := ws.GetDisassembler() emu := &Emulator{ ws: ws, u: u, disassembler: disassembler, maps: make([]AS.MemoryRegion, 0), } e = AS.CopyAddressSpace(emu, ws) check(e) if e != nil { return nil, e } stackAddress := AS.VA(0x69690000) stackSize := uint64(0x40000) e = emu.MemMap(AS.VA(uint64(stackAddress)-(stackSize/2)), stackSize, "stack") check(e) emu.SetStackPointer(stackAddress) return emu, nil }
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, }, nil }
func run() error { code, err := hex.DecodeString(asm) if err != nil { return err } // set up unicorn instance and add hooks mu, err := uc.NewUnicorn(uc.ARCH_X86, uc.MODE_64) if err != nil { return err } addHooks(mu) // map and write code to memory if err := mu.MemMap(0x1000, 0x1000); err != nil { return err } if err := mu.MemWrite(0x1000, code); err != nil { return err } // map scratch space if err := mu.MemMap(0x4000, 0x1000); err != nil { return err } // set example register if err := mu.RegWrite(uc.X86_REG_RDX, 1); err != nil { return err } rdx, err := mu.RegRead(uc.X86_REG_RDX) if err != nil { return err } fmt.Printf("RDX is: %d\n", rdx) // start emulation if err := mu.Start(0x1000, 0x1000+uint64(len(code))); err != nil { return err } // read back example register rdx, err = mu.RegRead(uc.X86_REG_RDX) if err != nil { return err } fmt.Printf("RDX is now: %d\n", rdx) return nil }
func NewEmulator(codepages map[uint64]([]byte), conf Config) (*Emulator, error) { res := new(Emulator) res.config = conf res.codepages = codepages res.Events = make(map[uint64]bool) res.WorkingSet = NewWorkingSet(conf.MaxTracePages) mu, err := uc.NewUnicorn(conf.Arch, conf.Mode) if err != nil { return nil, err } res.mu = mu if err = res.AddHooks(); err != nil { return nil, err } if err = res.WriteMemory(codepages); err != nil { return nil, err } if err = res.WriteRegisters(); err != nil { return nil, err } return res, nil }