Created
November 28, 2012 15:49
-
-
Save raptium/4162103 to your computer and use it in GitHub Desktop.
SOLITON Stupid DRM
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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