mirror of
https://gitlab.com/riglol/rigolee/hdo-tools.git
synced 2025-04-29 02:37:20 +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