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 }
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 }
// 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 }
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 (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 }