예제 #1
0
func RegisterDefaultAnalyzers(ws *W.Workspace) error {
	function_analyzers, e := getFunctionAnalyzers(ws)
	check(e)
	for name, a := range function_analyzers {
		logrus.Infof("registering: %s", name)
		_, e := ws.RegisterFunctionAnalysis(a)
		check(e)
		// we're leaking these guys...
		// defer ws.UnregisterFunctionAnalysis(hA)
	}

	file_analyzers, e := getFileAnalyzers(ws)
	check(e)
	for name, a := range file_analyzers {
		found := false
		// blacklist
		// TODO: make this configurable
		for _, n := range []string{} { //"analysis.file.entry_point", "analysis.file.prologue"} {
			if name == n {
				found = true
				break
			}
		}
		if !found {
			logrus.Infof("registering: %s", name)
			_, e := ws.RegisterFileAnalysis(a)
			check(e)
			// we're leaking these guys...
			// defer ws.UnregisterFileAnalysis(hA)
		}
	}
	return nil
}
예제 #2
0
func (loader *PELoader) loadPESection(
	ws *workspace.Workspace,
	mod *workspace.LoadedModule,
	section *pe.Section) error {

	h := section.SectionHeader

	logrus.Infof("section: %s", section.SectionHeader.Name)
	logrus.Infof("  virtual address: 0x%x", section.SectionHeader.VirtualAddress)
	logrus.Infof("  virtual size: 0x%x", section.SectionHeader.VirtualSize)
	logrus.Infof("  file offset: 0x%x", section.SectionHeader.Offset)
	logrus.Infof("  file size: 0x%x", section.SectionHeader.Size)

	rvaSecStart := AS.RVA(h.VirtualAddress)
	secStart := mod.VA(rvaSecStart)
	secLength := roundUpToPage(uint64(h.VirtualSize))
	e := ws.MemMap(secStart, secLength, fmt.Sprintf("%s/%s", mod.Name, section.SectionHeader.Name))
	check(e)

	d, e := section.Data()
	check(e)

	e = mod.MemWrite(ws, rvaSecStart, d)
	check(e)

	// TODO: apply permissions

	return nil
}
// New creates a new LinearDisassembler instance.
func New(ws *w.Workspace) (*LinearDisassembler, error) {
	// maybe the disassembler shouldn't come from the workspace directly?
	d, e := ws.GetDisassembler()
	if e != nil {
		return nil, e
	}
	ev, e := function_analysis.NewFunctionEventDispatcher()
	if e != nil {
		return nil, e
	}

	return &LinearDisassembler{
		FunctionEventDispatcher: *ev,
		disassembler:            d,
	}, nil
}
예제 #4
0
// New creates a new EmulatingDisassembler instance.
func New(ws *W.Workspace) (*EmulatingDisassembler, error) {
	// maybe the disassembler shouldn't come from the workspace directly?
	d, e := ws.GetDisassembler()
	if e != nil {
		return nil, e
	}

	// note: we could easily emulate over a memory/debugger/emulator state
	// by using a different address space here.
	emu, e := emulator.New(ws)
	if e != nil {
		return nil, e
	}

	sman, e := emulator.NewSnapshotManager(emu)
	check(e)

	unmappedHook, e := emu.HookMemUnmapped(func(access int, addr AS.VA, size int, value int64) bool {
		logrus.Warnf("Unmapped: %d %s %d %d", access, addr, size, value)
		return true
	})

	ev, e := function_analysis.NewFunctionEventDispatcher()
	if e != nil {
		return nil, e
	}

	ed := &EmulatingDisassembler{
		ws:             ws,
		symbolResolver: ws,
		disassembler:   d,
		emulator:       emu,
		sman:           sman,
		FunctionEventDispatcher: *ev,
		unmappedHook:            unmappedHook,
	}

	ed.codeHook, e = emu.HookCode(func(addr AS.VA, size uint32) {
		insn, e := ed.disassembler.ReadInstruction(ws, addr)
		check(e)
		ev.EmitInstruction(insn)
	})
	check(e)

	return ed, nil
}
예제 #5
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
}
예제 #6
0
func (loader *PELoader) Load(ws *workspace.Workspace) (*workspace.LoadedModule, error) {
	var imageBase AS.VA
	var addressOfEntryPoint AS.RVA
	var dataDirectory [16]pe.DataDirectory

	if optionalHeader, ok := loader.file.OptionalHeader.(*pe.OptionalHeader32); ok {
		imageBase = AS.VA(optionalHeader.ImageBase)
		addressOfEntryPoint = AS.RVA(optionalHeader.AddressOfEntryPoint)
		dataDirectory = optionalHeader.DataDirectory
	} else {
		return nil, workspace.InvalidModeError
	}

	mod := &workspace.LoadedModule{
		Name:             loader.name,
		BaseAddress:      imageBase,
		EntryPoint:       addressOfEntryPoint.VA(imageBase),
		Imports:          map[AS.RVA]workspace.LinkedSymbol{},
		ExportsByName:    map[string]workspace.ExportedSymbol{},
		ExportsByOrdinal: map[uint16]workspace.ExportedSymbol{},
	}

	for _, section := range loader.file.Sections {
		e := loader.loadPESection(ws, mod, section)
		check(e)
	}

	e := loader.resolveImports(ws, mod, dataDirectory)
	check(e)

	e = loader.resolveExports(ws, mod, dataDirectory)
	check(e)

	e = ws.AddLoadedModule(mod)
	check(e)

	return mod, nil
}