|
13 | 13 | from urllib.parse import urlparse |
14 | 14 | import win32security |
15 | 15 | import sys |
| 16 | +import base64 |
| 17 | +from Crypto.Cipher import AES |
16 | 18 |
|
17 | 19 |
|
18 | 20 | class DgpSession: |
@@ -65,20 +67,28 @@ def gen_rand_address(self): |
65 | 67 | return address[:-1] |
66 | 68 |
|
67 | 69 | def write(self): |
| 70 | + aes_key = self.get_aes_key() |
68 | 71 | for cookie_row in self.db.cursor().execute("select * from cookies"): |
69 | | - name = cookie_row[3] |
70 | | - value = self.session.cookies.get(name) |
71 | | - if value != None: |
72 | | - self.db.execute( |
73 | | - f"update cookies set value = '{value}' where name = '{name}'" |
74 | | - ) |
| 72 | + value = self.session.cookies.get(cookie_row[3]) |
| 73 | + v10, nonce, _, _ = self.split_encrypted_data(cookie_row[5]) |
| 74 | + cipher = AES.new(aes_key, AES.MODE_GCM, nonce) |
| 75 | + decrypt_data, mac = cipher.encrypt_and_digest(value.encode()) |
| 76 | + data = self.join_encrypted_data(v10, nonce, decrypt_data, mac) |
| 77 | + self.db.execute( |
| 78 | + "update cookies set encrypted_value = ? where name = ?", |
| 79 | + (memoryview(data), cookie_row[3]), |
| 80 | + ) |
75 | 81 | self.db.commit() |
76 | 82 |
|
77 | 83 | def read(self): |
| 84 | + aes_key = self.get_aes_key() |
78 | 85 | for cookie_row in self.db.cursor().execute("select * from cookies"): |
| 86 | + _, nonce, data, mac = self.split_encrypted_data(cookie_row[5]) |
| 87 | + cipher = AES.new(aes_key, AES.MODE_GCM, nonce) |
| 88 | + value = cipher.decrypt_and_verify(data, mac).decode() |
79 | 89 | cookie_data = { |
80 | 90 | "name": cookie_row[3], |
81 | | - "value": cookie_row[4], |
| 91 | + "value": value, |
82 | 92 | "domain": cookie_row[1], |
83 | 93 | "path": cookie_row[6], |
84 | 94 | "secure": cookie_row[8], |
@@ -149,6 +159,28 @@ def open(self): |
149 | 159 | self.session = requests.session() |
150 | 160 | self.cookies = self.session.cookies |
151 | 161 |
|
| 162 | + def get_aes_key(self): |
| 163 | + with open(self.DGP5_PATH + "\\Local State", "r") as f: |
| 164 | + local_state = json.load(f) |
| 165 | + encrypted_key = base64.b64decode( |
| 166 | + local_state["os_crypt"]["encrypted_key"].encode() |
| 167 | + )[5:] |
| 168 | + key = win32crypt.CryptUnprotectData(encrypted_key, None, None, None, 0)[1] |
| 169 | + return key |
| 170 | + |
| 171 | + def split_encrypted_data(self, encrypted_data: bytes) -> bytes: |
| 172 | + return ( |
| 173 | + encrypted_data[0:3], |
| 174 | + encrypted_data[3:15], |
| 175 | + encrypted_data[15:-16], |
| 176 | + encrypted_data[-16:], |
| 177 | + ) |
| 178 | + |
| 179 | + def join_encrypted_data( |
| 180 | + self, v10: bytes, nonce: bytes, data: bytes, mac: bytes |
| 181 | + ) -> bytes: |
| 182 | + return v10 + nonce + data + mac |
| 183 | + |
152 | 184 | def close(self): |
153 | 185 | self.db.close() |
154 | 186 |
|
@@ -327,6 +359,7 @@ def run_bypass_uac(): |
327 | 359 | argpar.add_argument("--https-proxy-uri", default=None) |
328 | 360 | argpar.add_argument("--non-request-admin", action="store_true") |
329 | 361 | argpar.add_argument("--non-bypass-uac", action="store_true") |
| 362 | +argpar.add_argument("--force-bypass-uac", action="store_true") |
330 | 363 | argpar.add_argument("--schtasks-path", default="schtasks.exe") |
331 | 364 |
|
332 | 365 | try: |
@@ -414,7 +447,12 @@ def run_bypass_uac(): |
414 | 447 | dmm_args = response["data"]["execute_args"].split(" ") |
415 | 448 | if arg.game_args is not None: |
416 | 449 | dmm_args = dmm_args + arg.game_args.split(" ") |
417 | | - print(game_path) |
| 450 | + if ( |
| 451 | + arg.force_bypass_uac |
| 452 | + and not arg.non_bypass_uac |
| 453 | + and response["data"]["is_administrator"] |
| 454 | + ): |
| 455 | + run_bypass_uac() |
418 | 456 | start_time = time.time() |
419 | 457 | process = process_manager.run([game_path] + dmm_args) |
420 | 458 | for line in process.stdout: |
|
0 commit comments