• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 syzkaller project authors. All rights reserved.
2// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
3
4// Minimal KD protocol decoder.
5// KD protocol is used by windows to talk to debuggers. Here are some links:
6// https://github.com/radare/radare2/issues/1246#issuecomment-135565901
7// http://articles.sysprogs.org/kdvmware/kdcom/
8// https://doxygen.reactos.org/df/de3/windbgkd_8h_source.html
9package kd
10
11import (
12	"bytes"
13	"fmt"
14	"unsafe"
15)
16
17var (
18	dataHeader = []byte{0x30, 0x30, 0x30, 0x30}
19)
20
21const (
22	typStateChange64 = 7
23)
24
25type packet struct {
26	header uint32
27	typ    uint16
28	size   uint16
29	id     uint32
30	csum   uint32
31}
32
33func Decode(data []byte) (start, size int, decoded []byte) {
34	if len(data) < len(dataHeader) {
35		return
36	}
37	start = bytes.Index(data, dataHeader)
38	if start == -1 {
39		start = len(data) - len(dataHeader) - 1
40		return
41	}
42	packetSize := int(unsafe.Sizeof(packet{}))
43	if len(data)-start < packetSize {
44		return // incomplete header
45	}
46	// Note: assuming little-endian machine.
47	pkt := (*packet)(unsafe.Pointer(&data[start]))
48	if len(data)-start < packetSize+int(pkt.size) {
49		return // incomplete data
50	}
51	size = packetSize + int(pkt.size) // skip whole packet
52	if pkt.typ == typStateChange64 {
53		if int(pkt.size) < int(unsafe.Sizeof(stateChange64{})) {
54			return
55		}
56		payload := (*stateChange64)(unsafe.Pointer(&data[start+packetSize]))
57		chance := "second"
58		if payload.exception.firstChance != 0 {
59			chance = "first"
60		}
61		decoded = []byte(fmt.Sprintf("\n\nBUG: %v chance exception 0x%x\n\n%#v\n\n",
62			chance, payload.exception.code, payload))
63	}
64	return
65}
66
67type stateChange64 struct {
68	state          uint32
69	processorLevel uint16
70	processor      uint16
71	numProcessors  uint32
72	thread         uint64
73	pc             uint64
74	exception      exception64
75	report         controlReport
76}
77
78type exception64 struct {
79	code        uint32
80	flags       uint32
81	record      uint64
82	address     uint64
83	numParams   uint32
84	unused      uint32
85	params      [15]uint64
86	firstChance uint32
87}
88
89type controlReport struct {
90	dr6         uint64
91	dr7         uint64
92	eflags      uint32
93	numInstr    uint16
94	reportFlags uint16
95	instr       [16]byte
96	cs          uint16
97	ds          uint16
98	es          uint16
99	fs          uint16
100}
101