func Disas(mem []byte, addr uint64, arch *Arch, pad ...int) (string, error) { if len(mem) == 0 { return "", nil } engine, err := gapstone.New(arch.CS_ARCH, arch.CS_MODE) if err != nil { return "", err } defer engine.Close() asm, err := engine.Disasm(mem, addr, 0) if err != nil { return "", err } var width uint if len(pad) > 0 { width = uint(pad[0]) } for _, insn := range asm { if insn.Size > width { width = insn.Size } } var out []string for _, insn := range asm { pad := strings.Repeat(" ", int(width-insn.Size)*2) data := pad + hex.EncodeToString(insn.Bytes) out = append(out, fmt.Sprintf("0x%x: %s %s %s", insn.Address, data, insn.Mnemonic, insn.OpStr)) } return strings.Join(out, "\n"), nil }
func Disasm(code io.Reader, asm io.Writer, address uint64, arch string) (err error) { gapArch, gapMode := int(0), uint(0) switch arch { case "386": gapArch = gapstone.CS_ARCH_X86 gapMode = gapstone.CS_MODE_32 case "amd64": gapArch = gapstone.CS_ARCH_X86 gapMode = gapstone.CS_MODE_64 } engine, err := gapstone.New(gapArch, gapMode) if err != nil { return } defer engine.Close() err = engine.SetOption(gapstone.CS_OPT_SYNTAX, gapstone.CS_OPT_SYNTAX_ATT) if err != nil { return } codeBuf, err := ioutil.ReadAll(code) if err != nil { return } insns, err := engine.Disasm(codeBuf, address, 0) if err != nil { return } for _, insn := range insns { fmt.Fprintf(asm, "%x:\t% -32x\t%s\t\t%s\n", insn.Address, insn.Bytes, insn.Mnemonic, insn.OpStr) } return }
func Disas(mem []byte, addr uint64, arch *Arch, pad ...int) (string, error) { var asm []gapstone.Instruction cacheKey := fmt.Sprintf("%d|%s", addr, mem) if len(mem) == 0 { return "", nil } if cached, ok := discache[cacheKey]; ok { return cached, nil } if arch.cs == nil { engine, err := gapstone.New(arch.CS_ARCH, arch.CS_MODE) if err != nil { return "", err } arch.cs = &engine } asm, err := arch.cs.Disasm(mem, addr, 0) if err != nil { return "", err } var width uint if len(pad) > 0 { width = uint(pad[0]) } for _, insn := range asm { if insn.Size > width { width = insn.Size } } var out []string for _, insn := range asm { pad := strings.Repeat(" ", int(width-insn.Size)*2) data := pad + hex.EncodeToString(insn.Bytes) out = append(out, fmt.Sprintf("0x%x: %s %s %s", insn.Address, data, insn.Mnemonic, insn.OpStr)) } ret := strings.Join(out, "\n") discache[cacheKey] = ret return ret, nil }
func main() { /* init engine */ engine, err := gapstone.New(gapstone.CS_ARCH_X86, gapstone.CS_MODE_64) /* detailed options. enables parsing jump arguments*/ engine.SetOption(gapstone.CS_OPT_DETAIL, gapstone.CS_OPT_ON) if err == nil { defer engine.Close() /* disassemble code */ instrs, err := engine.Disasm([]byte(code), 0x10000, 0) /* build basic blocks */ if err == nil { blocks := discover_basic_blocks(instrs) print_blocks(blocks) return } } }
func Fuzz(data []byte) int { var m wag.Module err := m.Load(bytes.NewReader(data), env{}, nil, nil, roDataAddr, nil) if err != nil { return 0 } text := m.Text() if len(text) != 0 { engine, err := gapstone.New(gapstone.CS_ARCH_X86, gapstone.CS_MODE_64) if err != nil { panic(err) } defer engine.Close() _, err = engine.Disasm(text, 0, 0) if err != nil { panic(err) } } return 1 }
func (ws *Workspace) GetDisassembler() (dis.Disassembler, error) { if ws.Arch != ARCH_X86 { return nil, InvalidArchError } if !(ws.Mode == MODE_32 || ws.Mode == MODE_64) { return nil, InvalidModeError } disassembler, e := gapstone.New( GAPSTONE_ARCH_MAP[ws.Arch], GAPSTONE_MODE_MAP[ws.Mode], ) if e != nil { return nil, e } e = disassembler.SetOption(gapstone.CS_OPT_DETAIL, gapstone.CS_OPT_ON) check(e) if e != nil { return nil, e } d := dis.GapstoneDisassembler(disassembler) return &d, nil }
func PrintTo(w io.Writer, text, funcMap []byte, ns *sections.NameSection) (err error) { var names []sections.FunctionName if ns != nil { names = ns.FunctionNames } engine, err := gapstone.New(gapstone.CS_ARCH_X86, gapstone.CS_MODE_64) if err != nil { return } defer engine.Close() err = engine.SetOption(gapstone.CS_OPT_SYNTAX, gapstone.CS_OPT_SYNTAX_ATT) if err != nil { return } insns, err := engine.Disasm(text, 0, 0) if err != nil { return } targets := map[uint]string{ 16: "start", } firstFuncAddr := uint(binary.LittleEndian.Uint32(funcMap)) for i := 0; len(funcMap) > 0; i++ { addr := binary.LittleEndian.Uint32(funcMap) funcMap = funcMap[4:] var name string if i < len(names) { name = names[i].FunName } else { name = fmt.Sprintf("func_%d", i) } targets[uint(addr)] = name } sequence := 0 for i := range insns { insn := insns[i] var name string switch { case insn.Mnemonic == "jmpq": continue case strings.HasPrefix(insn.Mnemonic, "j"): case insn.Mnemonic == "callq" && strings.HasPrefix(insn.OpStr, "0x"): case insn.Address < firstFuncAddr && insn.Mnemonic == "movl" && strings.HasPrefix(insn.OpStr, "$") && strings.HasSuffix(insn.OpStr, ", %eax"): var n uint fmt.Sscanf(insn.OpStr, "$%d, %%eax", &n) if id := traps.Id(n); id < traps.NumTraps { targets[insn.Address] = strings.Replace(id.String(), " ", "_", -1) } continue default: continue } addr, err := strconv.ParseUint(insn.OpStr, 0, 32) if err != nil { panic(err) } name, found := targets[uint(addr)] if !found { name = fmt.Sprintf(".L%d", sequence) sequence++ targets[uint(addr)] = name } insns[i].OpStr = name } skip := false for _, insn := range insns { name, found := targets[insn.Address] if found { if !strings.HasPrefix(name, ".") && name != "exit" { fmt.Fprintln(w) } fmt.Fprintf(w, "%s:\n", name) } switch insn.Id { case gapstone.X86_INS_INT3: if skip { continue } skip = true fallthrough default: fmt.Fprintf(w, "\t%s\t%s\n", insn.Mnemonic, insn.OpStr) } } fmt.Fprintln(w) return }