Created
December 21, 2025 17:38
-
-
Save ceres-c/1d5e777c57f74ff0975c9a4a4cdecbe1 to your computer and use it in GitHub Desktop.
Playing around with the ZTE H6645P v2
This file contains hidden or 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
| from pathlib import Path | |
| import sys | |
| from Crypto.Cipher import AES # pycryptodome | |
| def hc_get_ver_val(hardcode_path: Path, hardcoded_input_size: int) -> bytes | None: | |
| """ | |
| Python equivalent of the HCGetVerVal function. | |
| Reads the hardcode file, strips newlines, and returns the bytes | |
| constrained by hardcoded_input_size. | |
| """ | |
| with hardcode_path.open('rb') as f: | |
| line = f.read(64) | |
| if not line: | |
| raise OSError(f"Can't read data from {hardcode_path}") | |
| clean_line = line.splitlines()[0] | |
| # Respect the destination buffer size (snprintf behavior) | |
| return clean_line[:hardcoded_input_size] | |
| def decrypt_file(input_file: Path, output_file: Path, key: bytes): | |
| print(f"Decrypting {input_file} to {output_file}...") | |
| try: | |
| with input_file.open('rb') as f_in: | |
| ciphertext = f_in.read() | |
| cipher = AES.new(key, AES.MODE_ECB) | |
| # The C code zero-padded the buffer, so we do the same if needed. | |
| if len(ciphertext) % 16 != 0: | |
| ciphertext = ciphertext.ljust(len(ciphertext) + (16 - len(ciphertext) % 16), b'\0') | |
| decrypted_data = cipher.decrypt(ciphertext) | |
| # The C code used strlen to determine output length, effectively stripping trailing nulls. | |
| decrypted_data = decrypted_data.rstrip(b'\0') | |
| with output_file.open('wb') as f_out: | |
| f_out.write(decrypted_data) | |
| print("Decryption complete.") | |
| except Exception as e: | |
| print(f"Decryption failed: {e}") | |
| if __name__ == "__main__": | |
| import argparse | |
| parser = argparse.ArgumentParser(description="Decrypt enhardcodefile.") | |
| parser.add_argument("hardcode_file", type=Path, help="Path to the /etc/hardcode file") | |
| parser.add_argument("encrypted_file", type=Path, help="Path to the encrypted file") | |
| args = parser.parse_args() | |
| hardcode_path = args.hardcode_file.resolve() | |
| if not hardcode_path.exists(): | |
| print(f"Error: {hardcode_path} does not exist") | |
| exit(1) | |
| ver_val = hc_get_ver_val(hardcode_path, 0x20) | |
| if not ver_val: | |
| print(f"Could not read ver_val from {hardcode_path}") | |
| exit(1) | |
| key = b'0x18600x0001' + ver_val # 0x1860 and 0x0001 are hardcoded values found in 'CspHardCodeParamGet' in libhardcode.so | |
| key = key.ljust(32, b'\0') | |
| print(f"AES key: {key}") | |
| # Try to decrypt the provided file | |
| encrypted_path = args.encrypted_file.resolve() | |
| decrypted_path = encrypted_path.parent / (encrypted_path.name + '_decrypted') | |
| if encrypted_path.exists(): | |
| decrypt_file(encrypted_path, decrypted_path, key) | |
| else: | |
| print(f"File {encrypted_path} not found.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment