Skip to content

Instantly share code, notes, and snippets.

@raptium
Created November 28, 2012 15:49
Show Gist options
  • Save raptium/4162103 to your computer and use it in GitHub Desktop.
Save raptium/4162103 to your computer and use it in GitHub Desktop.
SOLITON Stupid DRM
package main
import (
"crypto/rc4"
"encoding/base64"
"fmt"
"io"
"log"
"os"
"path/filepath"
"strings"
)
func fix_filename(s string) string {
invalid_chars := [11]string{"/", "\\", "?", "*", "%", ":", "|", "\"", "<", ">", "."}
result := s
for _, ch := range invalid_chars {
result = strings.Replace(result, ch, "-", -1)
}
return result
}
func decrypt_sol_file(path string) error {
log.Printf("file path: %s", path)
if filepath.Ext(path) != ".sol" {
log.Printf("file extension not match: %s", filepath.Ext(path))
return nil
}
file, err := os.Open(path)
if err != nil {
log.Printf("cannot open file")
return err
}
defer file.Close()
filename := filepath.Base(path)
ext_name := filepath.Ext(path)
encoded_name := filename[:len(filename)-len(ext_name)]
decoded_bytes, err := base64.StdEncoding.DecodeString(encoded_name)
var decoded_name string
if err == nil {
decoded_name = string(decoded_bytes)
} else {
log.Printf("cannot decode filename, fallback to original name")
decoded_name = encoded_name
}
decoded_name = fix_filename(decoded_name) // incase there are invalid chars in track title
output_path := filepath.Join(filepath.Dir(path), decoded_name+".mp3")
log.Printf("output_path: %s", output_path)
output_file, err := os.Create(output_path)
if err != nil {
log.Printf("cannot open file to write")
return err
}
defer output_file.Close()
key := make([]byte, 4)
key[3] = 4 // this is stupid, but the key is 0x00000004
cipher, err := rc4.NewCipher(key)
if err != nil {
log.Printf("cannot open RC4 cipher")
return err
}
read_buf := make([]byte, 1024)
decode_buf := make([]byte, 1024)
for {
n, err := file.Read(read_buf)
cipher.XORKeyStream(decode_buf, read_buf)
output_file.Write(decode_buf[:n])
if err == io.EOF {
break
}
}
return nil
}
func main() {
if len(os.Args) < 2 {
fmt.Printf("not enough args\n")
return
}
c := make(chan int)
n := len(os.Args) - 1
for i := 1; i <= n; i++ {
go func(k int) {
err := decrypt_sol_file(os.Args[k])
if err != nil {
c <- 0
} else {
c <- 1
}
}(i)
}
s := 0
for j := 1; j <= n; j++ {
s += <-c
}
log.Printf("Finished. %d tracks decoded.", s)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment