diff --git a/Helpers/Device.py b/Helpers/Device.py index 868fad5..725e238 100644 --- a/Helpers/Device.py +++ b/Helpers/Device.py @@ -22,10 +22,12 @@ class Device: self.name = self.usb_device.name def export_key(self, key, client_id): - system_id = client_id.Token._DeviceCertificate.SystemId save_dir = os.path.join( 'key_dumps', - f'{self.name}/private_keys/{system_id}/{str(key.n)[:10]}' + f'{self.name}', + 'private_keys', + f'{client_id.Token._DeviceCertificate.SystemId}', + f'{str(key.n)[:10]}' ) if not os.path.exists(save_dir): @@ -39,25 +41,28 @@ class Device: self.logger.info('Key pairs saved at %s', save_dir) def on_message(self, msg, data): - if msg['payload'] == 'private_key': - key = RSA.import_key(data) - if key.n not in self.saved_keys: - encoded_key = base64.b64encode(data).decode('utf-8') - self.logger.debug('Retrieved key: %s', encoded_key) - self.saved_keys[key.n] = key - elif msg['payload'] == 'device_info': - self.license_request_message(data) - elif msg['payload'] == 'message_info': - self.logger.info(data.decode()) + if 'payload' in msg: + if msg['payload'] == 'private_key': + key = RSA.import_key(data) + if key.n not in self.saved_keys: + self.logger.debug( + 'Retrieved key: \n\n%s\n', + key.export_key().decode("utf-8") + ) + self.saved_keys[key.n] = key + elif msg['payload'] == 'device_info': + self.license_request_message(data) + elif msg['payload'] == 'message_info': + self.logger.info(data.decode()) def license_request_message(self, data): + self.logger.debug( + 'Retrieved build info: \n\n%s\n', + base64.b64encode(data).decode('utf-8') + ) root = SignedLicenseRequest() root.ParseFromString(data) public_key = root.Msg.ClientId.Token._DeviceCertificate.PublicKey - self.logger.debug( - 'Retrieved key: %s', - base64.b64encode(public_key).decode('utf-8') - ) key = RSA.importKey(public_key) cur = self.saved_keys.get(key.n) self.export_key(cur, root.Msg.ClientId) diff --git a/Helpers/script.js b/Helpers/script.js index 5f1d03b..44e6a33 100644 --- a/Helpers/script.js +++ b/Helpers/script.js @@ -1,5 +1,4 @@ -const DYNAMIC_FUNCTION_NAME = 'CHANGE_ME' -const CDM_VERSION = 'CHANGE_ME' +const CDM_VERSION = '' // The TextEncoder/Decoder API isn't supported so it has to be polyfilled. // Taken from https://gist.github.com/Yaffle/5458286#file-textencodertextdecoder-js @@ -48,10 +47,14 @@ function getPrivateKey(address) { const bytes = new Uint8Array(buf); // The first two bytes of the DER encoding are 0x30 and 0x82 (MII). if (bytes[0] === 0x30 && bytes[1] === 0x82) { - const binaryString = a2bs(bytes) - const keyLength = getKeyLength(binaryString); - const key = bytes.slice(0, keyLength); - send('private_key', key); + try { + const binaryString = a2bs(bytes) + const keyLength = getKeyLength(binaryString); + const key = bytes.slice(0, keyLength); + send('private_key', key); + } catch (error) { + console.log(error) + } } } } @@ -73,6 +76,7 @@ function prepareKeyRequest(address) { Interceptor.attach(ptr(address), { onEnter: function (args) { switch (CDM_VERSION) { + case '14.0.0': case '15.0.0': case '16.0.0': this.ret = args[4]; @@ -103,19 +107,17 @@ function hookLibFunctions(lib) { send('message_info', new TextEncoder().encode(message)) Module.enumerateExportsSync(name).forEach(function (module) { - const privacy_mode = 'UsePrivacyMode' - const prepare_key_request = 'PrepareKeyRequest' try { let hookedModule; - if (module.name.includes(DYNAMIC_FUNCTION_NAME)) { - getPrivateKey(module.address); - hookedModule = DYNAMIC_FUNCTION_NAME - } else if (module.name.includes(privacy_mode)) { + if (module.name.includes('UsePrivacyMode')) { disablePrivacyMode(module.address); - hookedModule = privacy_mode - } else if (module.name.includes(prepare_key_request)) { + hookedModule = module.name + } else if (module.name.includes('PrepareKeyRequest')) { prepareKeyRequest(module.address); - hookedModule = prepare_key_request + hookedModule = module.name + } else if (module.name.match(/^[a-z]+$/)) { + getPrivateKey(module.address); + hookedModule = module.name } if (hookedModule) {