Guest User

ineptkeyv44

a guest
Mar 24th, 2010
19,502
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #! /usr/bin/python
  2.  
  3. # ineptkey.pyw, version 4.4
  4. # ineptkeyv44
  5.  
  6. # To run this program install Python 2.6 from http://www.python.org/download/
  7. # and PyCrypto from http://www.voidspace.org.uk/python/modules.shtml#pycrypto
  8. # (make sure to install the version for Python 2.6).  Save this script file as
  9. # ineptkey.pyw and double-click on it to run it.  It will create a file named
  10. # adeptkey.der in the same directory.  These are your ADEPT user keys.
  11.  
  12. # Revision history:
  13. #   1 - Initial release, for Adobe Digital Editions 1.7
  14. #   2 - Better algorithm for finding pLK; improved error handling
  15. #   3 - Rename to INEPT
  16. #   4.1 - quick beta fix for ADE 1.7.2 (anon)
  17. #   4.2 - added old 1.7.1 processing
  18. #   4.3 - better key search
  19. #   4.4 - Make it working on 64-bit Python
  20.  
  21. """
  22. Retrieve Adobe ADEPT user key under Windows.
  23. """
  24.  
  25. from __future__ import with_statement
  26.  
  27. __license__ = 'GPL v3'
  28.  
  29. import sys
  30. import os
  31. from struct import pack
  32. from ctypes import windll, c_char_p, c_wchar_p, c_uint, POINTER, byref, \
  33.     create_unicode_buffer, create_string_buffer, CFUNCTYPE, addressof, \
  34.     string_at, Structure, c_void_p, cast, c_ulonglong, \
  35.     sizeof, c_void_p, c_size_t
  36.  
  37. import _winreg as winreg
  38. import Tkinter
  39. import Tkconstants
  40. import tkMessageBox
  41. import traceback
  42. import hashlib
  43. import pickle
  44.  
  45.  
  46. try:
  47.     from Crypto.Cipher import AES
  48. except ImportError:
  49.     AES = None
  50.  
  51.  
  52. DEVICE_KEY = 'Software\\Adobe\\Adept\\Device'
  53. PRIVATE_LICENCE_KEY = 'Software\\Adobe\\Adept\\Activation\\%04d'
  54. PRIVATE_LICENCE_KEY_KEY = 'Software\\Adobe\\Adept\\Activation\\%04d\\%04d'
  55. ACTIVATION = 'Software\\Adobe\\Adept\\Activation\\'
  56.  
  57. MAX_PATH = 255
  58.  
  59. kernel32 = windll.kernel32
  60. advapi32 = windll.advapi32
  61. crypt32 = windll.crypt32
  62.  
  63.  
  64. class ADEPTError(Exception):
  65.     pass
  66.  
  67.  
  68. def GetSystemDirectory():
  69.     GetSystemDirectoryW = kernel32.GetSystemDirectoryW
  70.     GetSystemDirectoryW.argtypes = [c_wchar_p, c_uint]
  71.     GetSystemDirectoryW.restype = c_uint
  72.     def GetSystemDirectory():
  73.         buffer = create_unicode_buffer(MAX_PATH + 1)
  74.         GetSystemDirectoryW(buffer, len(buffer))
  75.         return buffer.value
  76.     return GetSystemDirectory
  77. GetSystemDirectory = GetSystemDirectory()
  78.  
  79.  
  80. def GetVolumeSerialNumber():
  81.     GetVolumeInformationW = kernel32.GetVolumeInformationW
  82.     GetVolumeInformationW.argtypes = [c_wchar_p, c_wchar_p, c_uint,
  83.                                       POINTER(c_uint), POINTER(c_uint),
  84.                                       POINTER(c_uint), c_wchar_p, c_uint]
  85.     GetVolumeInformationW.restype = c_uint
  86.     def GetVolumeSerialNumber(path):
  87.         vsn = c_uint(0)
  88.         GetVolumeInformationW(path, None, 0, byref(vsn), None, None, None, 0)
  89.         return vsn.value
  90.     return GetVolumeSerialNumber
  91. GetVolumeSerialNumber = GetVolumeSerialNumber()
  92.  
  93.  
  94. def GetUserName():
  95.     GetUserNameW = advapi32.GetUserNameW
  96.     GetUserNameW.argtypes = [c_wchar_p, POINTER(c_uint)]
  97.     GetUserNameW.restype = c_uint
  98.     def GetUserName():
  99.         buffer = create_unicode_buffer(32)
  100.         size = c_uint(len(buffer))
  101.         while not GetUserNameW(buffer, byref(size)):
  102.             buffer = create_unicode_buffer(len(buffer) * 2)
  103.             size.value = len(buffer)
  104.         return buffer.value.encode('utf-16-le')[::2]
  105.     return GetUserName
  106. GetUserName = GetUserName()
  107.  
  108. if sizeof(c_void_p) == 4:
  109.     ## 32-bit Python
  110.     CPUID0_INSNS = create_string_buffer("\x53\x31\xc0\x0f\xa2\x8b\x44\x24\x08\x89"
  111.                                         "\x18\x89\x50\x04\x89\x48\x08\x5b\xc3")
  112.     def cpuid0():
  113.         buffer = create_string_buffer(12)
  114.         cpuid0__ = CFUNCTYPE(c_char_p)(addressof(CPUID0_INSNS))
  115.         def cpuid0():
  116.             cpuid0__(buffer)
  117.             return buffer.raw
  118.         return cpuid0
  119.     cpuid0 = cpuid0()
  120.  
  121.     CPUID1_INSNS = create_string_buffer("\x53\x31\xc0\x40\x0f\xa2\x5b\xc3")
  122.     cpuid1 = CFUNCTYPE(c_uint)(addressof(CPUID1_INSNS))
  123. else:
  124.     ## 64 bit Python
  125.  
  126.     # In 64-bit we cannot execute instructions stored in a string because
  127.     # the O.S. prevents that to defend against buffer overrun attacks.
  128.     # Therefore we have to allocate a block of memory with the execute
  129.     # permission and copy our code into it.
  130.    
  131.     NULL = c_void_p(0)
  132.     PAGE_EXECUTE_READWRITE = 0x40
  133.     MEM_COMMIT  = 0x1000
  134.     MEM_RESERVE = 0x2000
  135.  
  136.     VirtualAlloc = windll.kernel32.VirtualAlloc
  137.     VirtualAlloc.restype = c_void_p
  138.     VirtualAlloc.argtypes = (c_void_p, c_size_t, c_uint, c_uint)
  139.  
  140.     from ctypes import memmove
  141.     memmove.restype = c_void_p
  142.     memmove.argtypes = (c_void_p, c_void_p, c_size_t)
  143.  
  144.     CPUID0_INSNS = (b"\x55"             # push   %rbp
  145.                     "\x48\x89\xe5"      # mov    %rsp,%rbp
  146.                     "\x48\x89\x4d\xf8"  # mov    %rcx,-0x8(%rbp)
  147.                     "\x31\xc0"          # xor    %eax,%eax
  148.                     "\x0f\xa2"          # cpuid  
  149.                     "\x48\x8b\x45\xf8"  # mov    -0x8(%rbp),%rax
  150.                     "\x89\x18"          # mov    %ebx,(%rax)
  151.                     "\x89\x50\x04"      # mov    %edx,0x4(%rax)
  152.                     "\x89\x48\x08"      # mov    %ecx,0x8(%rax)
  153.                     "\x48\x8b\x45\xf8"  # mov    -0x8(%rbp),%rax
  154.                     "\xc9"              # leave
  155.                     "\xc3"              # ret
  156.                     )
  157.  
  158.     CPUID1_INSNS = (b"\x31\xc0"         # xor    %eax,%eax
  159.                     "\xff\xc0"          # inc    %eax
  160.                     "\x0f\xa2"          # cpuid  
  161.                     "\xc3"              # ret
  162.                     )
  163.  
  164.     insnlen0 = len(CPUID0_INSNS)
  165.     insnlen1 = len(CPUID1_INSNS)
  166.     insnlen = insnlen0 + insnlen1
  167.  
  168.     code_addr = (VirtualAlloc(NULL, insnlen,
  169.                     MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE))
  170.  
  171.     if code_addr is None:
  172.         raise ADEPTError("Failed to allocate memory")
  173.  
  174.     memmove(code_addr, CPUID0_INSNS + CPUID1_INSNS, insnlen)
  175.  
  176.     def cpuid0():
  177.         buffer = create_string_buffer(12)
  178.         cpuid0__ = CFUNCTYPE(c_ulonglong, c_char_p)(code_addr)
  179.         def cpuid0():
  180.             cpuid0__(buffer)
  181.             return buffer.raw
  182.         return cpuid0
  183.     cpuid0 = cpuid0()
  184.  
  185.     cpuid1 =  CFUNCTYPE(c_ulonglong)(code_addr + insnlen0)
  186.  
  187. class DataBlob(Structure):
  188.     _fields_ = [('cbData', c_uint),
  189.                 ('pbData', c_void_p)]
  190. DataBlob_p = POINTER(DataBlob)
  191.  
  192. def CryptUnprotectData():
  193.     _CryptUnprotectData = crypt32.CryptUnprotectData
  194.     _CryptUnprotectData.argtypes = [DataBlob_p, c_wchar_p, DataBlob_p,
  195.                                    c_void_p, c_void_p, c_uint, DataBlob_p]
  196.     _CryptUnprotectData.restype = c_uint
  197.     def CryptUnprotectData(indata, entropy):
  198.         indatab = create_string_buffer(indata)
  199.         indata = DataBlob(len(indata), cast(indatab, c_void_p))
  200.         entropyb = create_string_buffer(entropy)
  201.         entropy = DataBlob(len(entropy), cast(entropyb, c_void_p))
  202.         outdata = DataBlob()
  203.         if not _CryptUnprotectData(byref(indata), None, byref(entropy),
  204.                                    None, None, 0, byref(outdata)):
  205.             raise ADEPTError("Failed to decrypt user key key (sic)")
  206.         return string_at(outdata.pbData, outdata.cbData)
  207.     return CryptUnprotectData
  208. CryptUnprotectData = CryptUnprotectData()
  209.  
  210.  
  211. def retrieve_key(keypath):
  212.     root = GetSystemDirectory().split('\\')[0] + '\\'
  213.     serial = GetVolumeSerialNumber(root)
  214.     vendor = cpuid0()
  215.     signature = pack('>I', cpuid1())[1:]
  216.     user = GetUserName()
  217.     entropy = pack('>I12s3s13s', serial, vendor, signature, user)
  218.     cuser = winreg.HKEY_CURRENT_USER
  219.     try:
  220.         regkey = winreg.OpenKey(cuser, DEVICE_KEY)
  221.     except WindowsError:
  222.         raise ADEPTError("Adobe Digital Editions not activated")
  223.     device = winreg.QueryValueEx(regkey, 'key')[0]
  224.     keykey = CryptUnprotectData(device, entropy)
  225.     userkey = None
  226.     pkcs = None
  227.     keys = {}
  228.     counter = 0
  229.     for i in xrange(0, 16):
  230.         skey = PRIVATE_LICENCE_KEY % i
  231.         try:
  232.             regkey = winreg.OpenKey(cuser, skey)
  233.         except WindowsError:
  234.             break
  235.         type = winreg.QueryValueEx(regkey, None)[0]
  236.         # obfuscation technique
  237.         if type != 'credentials':
  238.             continue
  239.         for j in xrange(0, 16):
  240.             plkkey = PRIVATE_LICENCE_KEY_KEY  % (i, j)
  241.             try:
  242.                 regkey = winreg.OpenKey(cuser, plkkey)                
  243.             except WindowsError:
  244.                 break
  245.             type = winreg.QueryValueEx(regkey, None)[0]            
  246.             if type != 'privateLicenseKey':
  247.                 continue
  248.             userkey = winreg.QueryValueEx(regkey, 'value')[0]
  249.             break
  250.         for j in xrange(0, 16):
  251.             plkkey = PRIVATE_LICENCE_KEY_KEY  % (i, j)
  252.             try:
  253.                 pkcs = winreg.OpenKey(cuser, plkkey)  
  254.             except WindowsError:
  255.                 break
  256.             type = winreg.QueryValueEx(pkcs, None)[0]
  257.             if type != 'pkcs12':
  258.                 continue
  259.             pkcs = winreg.QueryValueEx(pkcs, 'value')[0]
  260.             break
  261.     if pkcs is None:      
  262.         raise ADEPTError('Could not locate PKCS specification')
  263.     if userkey is None:
  264.         raise ADEPTError('Could not locate privateLicenseKey')
  265.     userkey = userkey.decode('base64')
  266.     userkey = AES.new(keykey, AES.MODE_CBC).decrypt(userkey)
  267.     userkey = userkey[26:-ord(userkey[-1])]
  268.     with open(keypath, 'wb') as f:
  269.         f.write(userkey)
  270.     return
  271.  
  272. class ExceptionDialog(Tkinter.Frame):
  273.     def __init__(self, root, text):
  274.         Tkinter.Frame.__init__(self, root, border=5)
  275.         label = Tkinter.Label(self, text="Unexpected error:",
  276.                               anchor=Tkconstants.W, justify=Tkconstants.LEFT)
  277.         label.pack(fill=Tkconstants.X, expand=0)
  278.         self.text = Tkinter.Text(self)
  279.         self.text.pack(fill=Tkconstants.BOTH, expand=1)
  280.         self.text.insert(Tkconstants.END, text)
  281.  
  282.  
  283. def main(argv=sys.argv):
  284.     root = Tkinter.Tk()
  285.     root.withdraw()
  286.     progname = os.path.basename(argv[0])
  287.     if AES is None:
  288.         tkMessageBox.showerror(
  289.             "ADEPT Key",
  290.             "This script requires PyCrypto, which must be installed "
  291.             "separately.  Read the top-of-script comment for details.")
  292.         return 1
  293.     keypath = 'adeptkey.der'
  294.     try:
  295.         retrieve_key(keypath)
  296.     except ADEPTError, e:
  297.         tkMessageBox.showerror("ADEPT Key", "Error: " + str(e))
  298.         return 1
  299.     except Exception:
  300.         root.wm_state('normal')
  301.         root.title('ADEPT Key')
  302.         text = traceback.format_exc()
  303.         ExceptionDialog(root, text).pack(fill=Tkconstants.BOTH, expand=1)
  304.         root.mainloop()
  305.         return 1
  306.     tkMessageBox.showinfo(
  307.         "ADEPT Key", "Key successfully retrieved to %s" % (keypath))
  308.     return 0
  309.  
  310. if __name__ == '__main__':
  311.     sys.exit(main())
RAW Paste Data