github.com/iDigitalFlame/xmt@v0.5.4/device/regedit/v_no_implant.go (about) 1 //go:build !implant 2 // +build !implant 3 4 // Copyright (C) 2020 - 2023 iDigitalFlame 5 // 6 // This program is free software: you can redistribute it and/or modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation, either version 3 of the License, or 9 // any later version. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with this program. If not, see <https://www.gnu.org/licenses/>. 18 // 19 20 package regedit 21 22 import ( 23 "encoding/hex" 24 "unsafe" 25 26 "github.com/iDigitalFlame/xmt/device/winapi" 27 "github.com/iDigitalFlame/xmt/device/winapi/registry" 28 "github.com/iDigitalFlame/xmt/util" 29 ) 30 31 // String returns the string representation of the data held in the Data buffer. 32 // Invalid values of keys return an empty string. 33 func (e Entry) String() string { 34 if e.Type == 0 { 35 if len(e.Name) == 0 { 36 return "<invalid>" 37 } 38 return "" 39 } 40 switch e.Type { 41 case registry.TypeDword: 42 if len(e.Data) != 4 { 43 return "" 44 } 45 _ = e.Data[3] 46 return util.Uitoa(uint64(e.Data[0]) | uint64(e.Data[1])<<8 | uint64(e.Data[2])<<16 | uint64(e.Data[3])<<24) 47 case registry.TypeQword: 48 if len(e.Data) != 8 { 49 return "" 50 } 51 _ = e.Data[7] 52 return util.Uitoa( 53 uint64(e.Data[0]) | uint64(e.Data[1])<<8 | uint64(e.Data[2])<<16 | uint64(e.Data[3])<<24 | 54 uint64(e.Data[4])<<32 | uint64(e.Data[5])<<40 | uint64(e.Data[6])<<48 | uint64(e.Data[7])<<56, 55 ) 56 case registry.TypeBinary: 57 return hex.EncodeToString(e.Data) 58 case registry.TypeStringList: 59 if len(e.Data) < 3 { 60 return "" 61 } 62 var ( 63 b util.Builder 64 v = (*[1 << 29]uint16)(unsafe.Pointer(&e.Data[0]))[: len(e.Data)/2 : len(e.Data)/2] 65 ) 66 if len(v) == 0 { 67 return "" 68 } 69 if v[len(v)-1] == 0 { 70 v = v[:len(v)-1] 71 } 72 for i, n := 0, 0; i < len(v); i++ { 73 if v[i] > 0 { 74 continue 75 } 76 if n > 0 { 77 b.WriteByte(',') 78 b.WriteByte(' ') 79 } 80 b.WriteString(string(winapi.UTF16Decode(v[n:i]))) 81 n = i + 1 82 } 83 return b.Output() 84 case registry.TypeString, registry.TypeExpandString: 85 if len(e.Data) < 3 { 86 return "" 87 } 88 return winapi.UTF16ToString((*[1 << 29]uint16)(unsafe.Pointer(&e.Data[0]))[: len(e.Data)/2 : len(e.Data)/2]) 89 } 90 return "" 91 } 92 93 // TypeName returns a string representation of the Type value, which represents 94 // the value data type. 95 func (e Entry) TypeName() string { 96 if e.Type == 0 { 97 return "KEY" 98 } 99 switch e.Type { 100 case registry.TypeDword: 101 return "DWORD" 102 case registry.TypeQword: 103 return "QWORD" 104 case registry.TypeBinary: 105 return "BINARY" 106 case registry.TypeStringList: 107 return "MULTI_STRING" 108 case registry.TypeString, registry.TypeExpandString: 109 return "STRING" 110 } 111 return "" 112 }