mirror of
https://gitlab.com/riglol/rigolee/hdo-tools.git
synced 2025-04-28 18:27:28 +09:00
Add AlphaRne key decoder
See https://www.eevblog.com/forum/testgear/hacking-the-hdo1khdo4k-rigol-12-bit-scope/msg4499302/#msg4499302 Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>
This commit is contained in:
parent
4c0beb9d88
commit
70db47cbbc
199
kd2.go
Normal file
199
kd2.go
Normal file
@ -0,0 +1,199 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"io/ioutil"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var dataFile string
|
||||
var xxKey string
|
||||
|
||||
func initCmdline() {
|
||||
flag.StringVar(&dataFile, "f", "Key.data", "file to decode")
|
||||
flag.StringVar(&xxKey, "key", "", "key data")
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
func Expand(path string) string {
|
||||
if len(path) == 0 || path[0] != '~' {
|
||||
return path
|
||||
}
|
||||
|
||||
usr, err := user.Current()
|
||||
if err != nil {
|
||||
return path
|
||||
}
|
||||
return filepath.Join(usr.HomeDir, path[1:])
|
||||
}
|
||||
|
||||
func HexString(data []byte) string {
|
||||
var buf bytes.Buffer
|
||||
for i := 0; i < len(data)-1; i++ {
|
||||
buf.WriteString(fmt.Sprintf("%02X ", data[i]))
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf("%02X", data[len(data)-1]))
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
const delta = 0x9E3779B9
|
||||
|
||||
func mx(sum uint32, y uint32, z uint32, p uint32, e uint32, k []uint32) uint32 {
|
||||
return ((z>>5 ^ y<<2) + (y>>3 ^ z<<4)) ^ ((sum ^ y) + (k[p&3^e] ^ z))
|
||||
}
|
||||
|
||||
func fixk(k []uint32) []uint32 {
|
||||
if len(k) < 4 {
|
||||
key := make([]uint32, 4)
|
||||
copy(key, k)
|
||||
return key
|
||||
}
|
||||
return k
|
||||
}
|
||||
|
||||
func XXTeaDecrypt(v []uint32, k []uint32) []uint32 {
|
||||
length := uint32(len(v))
|
||||
n := length - 1
|
||||
k = fixk(k)
|
||||
var y, z, sum, e, p, q uint32
|
||||
y = v[0]
|
||||
q = 6 + 52/length
|
||||
for sum = q * delta; sum != 0; sum -= delta {
|
||||
e = sum >> 2 & 3
|
||||
for p = n; p > 0; p-- {
|
||||
z = v[p-1]
|
||||
v[p] -= mx(sum, y, z, p, e, k)
|
||||
y = v[p]
|
||||
}
|
||||
z = v[n]
|
||||
v[0] -= mx(sum, y, z, p, e, k)
|
||||
y = v[0]
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
var fileKey = []uint32{0xAB12CD34, 0xAB12CD34, 0xAB12CD34, 0xAB12CD34}
|
||||
var defaultKey = []uint32{0x03920001, 0x08410841, 0x18C32104, 0x318639C7}
|
||||
|
||||
func decodeXXTEA(data []byte, key []uint32) []byte {
|
||||
N := len(data)
|
||||
u32 := make([]uint32, N>>2)
|
||||
for i, _ := range u32 {
|
||||
u32[i] = binary.LittleEndian.Uint32(data[i*4:])
|
||||
}
|
||||
u32d := XXTeaDecrypt(u32, key)
|
||||
res := make([]uint8, N)
|
||||
for i, v := range u32d {
|
||||
binary.LittleEndian.PutUint32(res[i*4:], v)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func parseKey(k string) ([]uint32, error) {
|
||||
parts := strings.Split(k, ",")
|
||||
if len(parts) == 0 {
|
||||
return nil, errors.New("invalid key data")
|
||||
}
|
||||
res := make([]uint32, len(parts))
|
||||
for i, s := range parts {
|
||||
if strings.HasPrefix(s, "0x") {
|
||||
s = s[2:]
|
||||
}
|
||||
x, err := strconv.ParseUint(s, 16, 64)
|
||||
if nil != err {
|
||||
return nil, err
|
||||
}
|
||||
res[i] = uint32(x)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func DecryptFile(name string, key []uint32) ([]uint8, error) {
|
||||
data, err := ioutil.ReadFile(Expand(name))
|
||||
if nil != err {
|
||||
return nil, err
|
||||
}
|
||||
dd := decodeXXTEA(data, key)
|
||||
if bytes.Index(dd, []uint8{0}) < 0x10 {
|
||||
fmt.Printf("raw data:\n%v\n", HexString(dd))
|
||||
} else {
|
||||
fmt.Printf("string data:%v\n", string(dd))
|
||||
}
|
||||
return dd, nil
|
||||
}
|
||||
|
||||
func parseVendorData(data []uint8) error {
|
||||
crc1 := binary.LittleEndian.Uint32(data)
|
||||
size := binary.LittleEndian.Uint32(data[4:])
|
||||
crc2 := crc32.ChecksumIEEE(data[8 : 8+size])
|
||||
if crc1 != crc2 {
|
||||
return errors.New("vendor crc mismatch")
|
||||
}
|
||||
fmt.Printf("vendor crc ok %x\n", crc1)
|
||||
ofs := 8
|
||||
for ofs < len(data) {
|
||||
l1 := binary.LittleEndian.Uint32(data[ofs:])
|
||||
ofs += 4
|
||||
id := binary.LittleEndian.Uint32(data[ofs:])
|
||||
ofs += int(l1)
|
||||
l2 := binary.LittleEndian.Uint32(data[ofs:])
|
||||
ofs += 4
|
||||
item := data[ofs : ofs+int(l2)]
|
||||
crc1 = binary.LittleEndian.Uint32(item)
|
||||
size = binary.LittleEndian.Uint32(item[4:])
|
||||
strSize := binary.LittleEndian.Uint32(item[8:])
|
||||
crc2 := crc32.ChecksumIEEE(item[8 : 12+size])
|
||||
if crc1 != crc2 {
|
||||
fmt.Printf("crc mismatch id:%x crc:%x,%x\n", id, crc1, crc2)
|
||||
continue
|
||||
}
|
||||
dd := decodeXXTEA(item[12:], defaultKey)
|
||||
ofs += int(l2)
|
||||
//n := bytes.Index(dd,[]uint8{0})
|
||||
n := int(strSize)
|
||||
name := string(dd[:n])
|
||||
n = (n + 3) & (^0x3)
|
||||
edata := make([]uint32, (int(size)-n)>>2)
|
||||
for i := 0; i < len(edata); i++ {
|
||||
edata[i] = binary.LittleEndian.Uint32(dd[n+4*i:])
|
||||
}
|
||||
fmt.Printf("id:%x | str:%v | data:%x\n", id, name, edata)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
initCmdline()
|
||||
k, _ := parseKey(xxKey)
|
||||
if nil != k {
|
||||
N := len(k)
|
||||
if N < 4 {
|
||||
for i := N; i < 4; i++ {
|
||||
k = append(k, k[N-1])
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if strings.HasSuffix(dataFile, "vendor.bin") {
|
||||
k = fileKey
|
||||
} else {
|
||||
k = defaultKey
|
||||
}
|
||||
}
|
||||
fmt.Printf("using key %x\n", k)
|
||||
data, err := DecryptFile(dataFile, k)
|
||||
if nil != err {
|
||||
fmt.Printf("error %v\n", err)
|
||||
return
|
||||
}
|
||||
if strings.HasSuffix(dataFile, "vendor.bin") {
|
||||
parseVendorData(data)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user