Пример #1
0
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
}
Пример #2
0
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
}
Пример #3
0
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)
}
Пример #4
0
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
}
Пример #5
0
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
}
Пример #6
0
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
}
Пример #7
0
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
}