@@ -29,7 +29,7 @@ def lcm_rand() -> collections.abc.Generator[int, Any, Never]:
2929
3030
3131@functools .cache
32- def xor_encrypt (code : bytes , offset : int = 0 , key = OBFUSCATION_NOISE_CYCLE_XOR ) -> bytes :
32+ def xor_encrypt (code : bytes , offset : int = 0 , key : bytes = OBFUSCATION_NOISE_CYCLE_XOR ) -> bytes :
3333 l = len (key )
3434 return bytes (
3535 c ^ key [i % l ]
@@ -71,6 +71,78 @@ def create_hash(vertices: bytes, indices: bytes, salt: bytes = b'\0'*16) -> byte
7171 return hash_buffer
7272
7373
74+ def recalculate_hash (data : bytes ) -> bytes :
75+ data_xor = xor_encrypt (data )
76+
77+ hash_base = 0x0a
78+ hash_size = 0x20
79+
80+ hash_salt_base = hash_base + 0x10
81+ hash_salt_size = 0x10
82+ hash_salt = data_xor [
83+ hash_salt_base :
84+ hash_salt_base + hash_salt_size
85+ ]
86+
87+ vertex_count_base = hash_base + hash_size
88+ vertex_count_size = INT_SIZE
89+ vertex_count = int .from_bytes (
90+ bytes = data_xor [
91+ vertex_count_base :
92+ vertex_count_base + vertex_count_size
93+ ],
94+ byteorder = 'little' ,
95+ )
96+
97+ vertex_stride_size_base = vertex_count_base + vertex_count_size
98+ vertex_stride_size_size = INT_SIZE
99+ vertex_stride_size = int .from_bytes (
100+ bytes = data_xor [
101+ vertex_stride_size_base :
102+ vertex_stride_size_base + vertex_stride_size_size
103+ ],
104+ byteorder = 'little' ,
105+ )
106+ assert vertex_stride_size == 84
107+
108+ vertex_data_base = vertex_stride_size_base + vertex_stride_size_size
109+ vertex_data_size = vertex_count * vertex_stride_size
110+ vertex_data = data_xor [
111+ vertex_data_base :
112+ vertex_data_base + vertex_data_size
113+ ]
114+
115+ index_count_base = vertex_data_base + vertex_data_size
116+ index_count_size = INT_SIZE
117+ index_count = int .from_bytes (
118+ bytes = data_xor [
119+ index_count_base :
120+ index_count_base + index_count_size
121+ ],
122+ byteorder = 'little' ,
123+ )
124+
125+ index_data_base = index_count_base + index_count_size
126+ index_data_size = index_count * INT_SIZE
127+ index_data = data_xor [
128+ index_data_base :
129+ index_data_base + index_data_size
130+ ]
131+
132+ new_hash = create_hash (
133+ vertices = vertex_data ,
134+ indices = index_data ,
135+ salt = hash_salt ,
136+ )
137+
138+ result = b'' .join ([
139+ data [:hash_base ],
140+ xor_encrypt (new_hash , offset = hash_base ),
141+ data [hash_base + hash_size :],
142+ ])
143+ return result
144+
145+
74146class CSG_HEADER (enum .Enum ):
75147 MDL2 = xor_encrypt (get_header (b'CSGMDL' , 2 ))
76148 MDL4 = xor_encrypt (get_header (b'CSGMDL' , 4 ))
0 commit comments