Protocols/MSNP/TCL (Challenge Implementation): Difference between revisions
Jump to navigation
Jump to search
No edit summary |
m (1 revision imported) |
||
(No difference)
|
Revision as of 00:23, 29 May 2020
proc CreateQRYHash {chldata} { set prodid "PROD0090YUAUV\{2B" set prodkey "YMM8C_H7KCQ2S_KL"
# Create an MD5 hash out of the given data, then form 32 bit integers from it set md5hash [::md5::md5 -hex $chldata$prodkey] set md5parts [MD5HashToInt $md5hash]
# Then create a valid productid string, divisable by 8, then form 32 bit integers from it set nrPadZeros [expr 8 - [string length $chldata$prodid] % 8] set padZeros [string repeat 0 $nrPadZeros] set chlprodid [CHLProdToInt $chldata$prodid$padZeros]
# Create the key we need to XOR set key [KeyFromInt $md5parts $chlprodid]
set low 0x[string range $md5hash 0 15] set high 0x[string range $md5hash 16 32] set low [expr {$low ^ $key}] set high [expr {$high ^ $key}]
set p1 [format %8.8x [expr {$low / 0x100000000}]] set p2 [format %8.8x [expr {$low % 0x100000000}]] set p3 [format %8.8x [expr {$high / 0x100000000}]] set p4 [format %8.8x [expr {$high % 0x100000000}]]
return $p1$p2$p3$p4 }
proc KeyFromInt { md5parts chlprod } { # Create a new series of numbers set key_temp 0 set key_high 0 set key_low 0
# Then loop on the entries in the second array we got in the parameters for {set i 0} {$i < [llength $chlprod]} {incr i 2} {
# Make $key_temp zero again and perform calculation as described in the documents set key_temp [lindex $chlprod $i] set key_temp [expr {(wide(0x0E79A9C1) * wide($key_temp)) % wide(0x7FFFFFFF)}] set key_temp [expr {wide($key_temp) + wide($key_high)}] set key_temp [expr {(wide([lindex $md5parts 0]) * wide($key_temp)) + wide([lindex $md5parts 1])}] set key_temp [expr {wide($key_temp) % wide(0x7FFFFFFF)}]
set key_high [lindex $chlprod [expr {$i+1}]] set key_high [expr {(wide($key_high) + wide($key_temp)) % wide(0x7FFFFFFF)}] set key_high [expr {(wide([lindex $md5parts 2]) * wide($key_high)) + wide([lindex $md5parts 3])}] set key_high [expr {wide($key_high) % wide(0x7FFFFFFF)}] set key_low [expr {wide($key_low) + wide($key_temp) + wide($key_high)}] }
set key_high [expr {(wide($key_high) + wide([lindex $md5parts 1])) % wide(0x7FFFFFFF)}] set key_low [expr {(wide($key_low) + wide([lindex $md5parts 3])) % wide(0x7FFFFFFF)}]
set key_high 0x[byteInvert [format %8.8X $key_high]] set key_low 0x[byteInvert [format %8.8X $key_low]]
set long_key [expr {(wide($key_high) << 32) + wide($key_low)}]
return $long_key }
# Takes an CHLData + ProdID + Padded string and chops it in 4 bytes. Then converts to 32 bit integers proc CHLProdToInt { CHLProd } { set hexs {} set result {} while {[string length $CHLProd] > 0} { lappend hexs [string range $CHLProd 0 3] set CHLProd [string range $CHLProd 4 end] } for {set i 0} {$i < [llength $hexs]} {incr i} { binary scan [lindex $hexs $i] H8 int lappend result 0x[byteInvert $int] } return $result }
# Takes an MD5 string and chops it in 4. Then "decodes" the HEX and converts to 32 bit integers. After that it ANDs proc MD5HashToInt { md5hash } { binary scan $md5hash a8a8a8a8 hash1 hash2 hash3 hash4 set hash1 [expr "0x[byteInvert $hash1]" & 0x7FFFFFFF] set hash2 [expr "0x[byteInvert $hash2]" & 0x7FFFFFFF] set hash3 [expr "0x[byteInvert $hash3]" & 0x7FFFFFFF] set hash4 [expr "0x[byteInvert $hash4]" & 0x7FFFFFFF]
return [list $hash1 $hash2 $hash3 $hash4] }
proc byteInvert { hex } { set hexs {} while {[string length $hex] > 0} { lappend hexs [string range $hex 0 1] set hex [string range $hex 2 end] } set hex "" for {set i [expr [llength $hexs] -1]} {$i >= 0} {incr i -1} { append hex [lindex $hexs $i] } return $hex }