github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/kd/kd.go (about) 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 9 package kd 10 11 import ( 12 "bytes" 13 "fmt" 14 "unsafe" 15 ) 16 17 var ( 18 dataHeader = []byte{0x30, 0x30, 0x30, 0x30} 19 ) 20 21 const ( 22 typStateChange64 = 7 23 ) 24 25 type packet struct { 26 header uint32 27 typ uint16 28 size uint16 29 id uint32 30 csum uint32 31 } 32 33 func 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 67 type 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 78 type 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 89 type 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 }