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