import
base64
import
random
import
string
import
xml.etree.ElementTree as ET
import
zlib
from
Crypto.Cipher
import
AES
from
cryptography.hazmat.backends
import
default_backend
from
cryptography.hazmat.primitives
import
hashes
from
cryptography.hazmat.primitives.kdf.pbkdf2
import
PBKDF2HMAC
SERVER_DERIVE_KEY
=
"N|[%^^m@#ç:!Ah*~"
.encode(
"utf-8"
)
REQUEST_DERIVE_KEY
=
"j%*£$[8f3Kv'{^ç\\".encode("
utf
-
8
")
ITERATIONS
=
1000
KEY_LENGTH
=
16
BS
=
16
XML_FILE_PATH
=
r
"C:\Users\user\Downloads\NDepend_2024.1.1.9735\Lib\DownloadInfo.xml"
ACTIVATION_EVAL_PATH
=
r
"C:\ProgramData\NDepend\ActivationEval"
def
pkcs7_padding(text):
length
=
len
(text)
bytes_length
=
len
(text)
padding_size
=
length
if
(bytes_length
=
=
length)
else
bytes_length
padding
=
BS
-
padding_size
%
BS
padding_text
=
padding.to_bytes(
1
,
'little'
)
*
padding
return
text
+
padding_text
def
data_response_decrypt(key, iv, ciphertext):
base64_text
=
AES.new(key, AES.MODE_CBC, iv).decrypt(ciphertext)
compressed_data
=
base64.b64decode(base64_text)
plaintext
=
zlib.decompress(compressed_data,
-
zlib.MAX_WBITS)
return
plaintext
def
data_response_encrypt(key, iv, plaintext):
compressor
=
zlib.compressobj(wbits
=
-
zlib.MAX_WBITS)
compressed_data
=
compressor.compress(plaintext.encode(
"utf-8"
))
+
compressor.flush()
base64_cipher
=
base64.b64encode(compressed_data)
return
AES.new(key, AES.MODE_CBC, iv).encrypt(pkcs7_padding(base64_cipher))
def
derive_key(password, salt, iterations, key_length):
kdf
=
PBKDF2HMAC(
algorithm
=
hashes.SHA1(),
length
=
key_length,
salt
=
salt,
iterations
=
iterations,
backend
=
default_backend()
)
return
kdf.derive(password)
def
decrypt_server_data(cipher):
text
=
base64.b64decode(cipher)
key
=
derive_key(SERVER_DERIVE_KEY, text[:
16
], ITERATIONS, KEY_LENGTH)
iv
=
text[
16
:
32
]
ciphertext
=
text[
32
:]
plaintext
=
data_response_decrypt(key, iv, ciphertext)
return
plaintext.decode(
"utf-8"
)
def
decrypt_data_request(cipher):
text
=
base64.b64decode(cipher)
key
=
derive_key(REQUEST_DERIVE_KEY, text[:
16
], ITERATIONS, KEY_LENGTH)
iv
=
text[
16
:
32
]
ciphertext
=
text[
32
:]
plaintext
=
data_response_decrypt(key, iv, ciphertext)
return
plaintext.decode(
"utf-8"
)
def
generate_activation_eval():
random_bytes
=
bytes(random.getrandbits(
8
)
for
_
in
range
(
32
))
key
=
derive_key(SERVER_DERIVE_KEY, random_bytes[:
16
], ITERATIONS, KEY_LENGTH)
iv
=
random_bytes[
16
:
32
]
with
open
(XML_FILE_PATH,
"r"
) as f:
plaintext
=
f.read()
all_data
=
random_bytes
+
data_response_encrypt(key, iv, plaintext)
with
open
(ACTIVATION_EVAL_PATH,
"wb"
) as f:
f.write(base64.b64encode(all_data))
def
decrypt_activation_eval(activation_eval_path):
with
open
(activation_eval_path,
"rb"
) as f:
all_data
=
base64.b64decode(f.read())
random_bytes
=
all_data[:
32
]
key
=
derive_key(SERVER_DERIVE_KEY, random_bytes[:
16
], ITERATIONS, KEY_LENGTH)
iv
=
random_bytes[
16
:
32
]
ciphertext
=
all_data[
32
:]
plaintext
=
data_response_decrypt(key, iv, ciphertext)
return
plaintext.decode(
"utf-8"
)
def
generate_random_string(length
=
16
):
letters_and_digits
=
string.ascii_letters
+
string.digits
return
''.join(random.choice(letters_and_digits)
for
_
in
range
(length))
def
randomize_email_and_tracking(xml_path):
tree
=
ET.parse(xml_path)
root
=
tree.getroot()
email_element
=
root.find(
'.//EmailAddress'
)
tracking_data_element
=
root.find(
'.//TrackingData'
)
if
email_element
is
not
None
:
email_element.text
=
f
"user{random.randint(10000000, 90000000)}@mail.com"
if
tracking_data_element
is
not
None
:
tracking_data_element.text
=
generate_random_string(
16
)
tree.write(xml_path, encoding
=
'utf-8'
, xml_declaration
=
True
)
generate_activation_eval()
if
__name__
=
=
"__main__"
:
randomize_email_and_tracking(XML_FILE_PATH)
print
(f
"XML file updated: {XML_FILE_PATH}"
)
plaintext
=
decrypt_activation_eval(ACTIVATION_EVAL_PATH)
print
(plaintext)