Exemple #1
0
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
}
Exemple #2
0
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
}
Exemple #3
0
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
}
Exemple #4
0
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
		}
	}
}
Exemple #5
0
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
}
Exemple #7
0
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
}