# Path: owade/fileAnalyze/hashcatLib/framework/addrspace.py
# class HiveFileAddressSpace:
#     def __init__(self, fname):
#         self.fname = fname
#         self.base = FileAddressSpace(fname)
# 
#     def vtop(self, vaddr):
#         return vaddr + BLOCK_SIZE + 4
# 
#     def read(self, vaddr, length, zero=False):
#         first_block = BLOCK_SIZE - vaddr % BLOCK_SIZE
#         full_blocks = ((length + (vaddr % BLOCK_SIZE)) / BLOCK_SIZE) - 1
#         left_over = (length + vaddr) % BLOCK_SIZE
#         
#         paddr = self.vtop(vaddr)
#         if paddr == None and zero:
#             if length < first_block:
#                 return "\0" * length
#             else:
#                 stuff_read = "\0" * first_block
#         elif paddr == None:
#             return None
#         else:
#             if length < first_block:
#                 stuff_read = self.base.read(paddr, length)
#                 if not stuff_read and zero:
#                     return "\0" * length
#                 else:
#                     return stuff_read
# 
#             stuff_read = self.base.read(paddr, first_block)
#             if not stuff_read and zero:
#                 stuff_read = "\0" * first_block
# 
#         new_vaddr = vaddr + first_block
#         for i in range(0,full_blocks):
#             paddr = self.vtop(new_vaddr)
#             if paddr == None and zero:
#                 stuff_read = stuff_read + "\0" * BLOCK_SIZE
#             elif paddr == None:
#                 return None
#             else:
#                 new_stuff = self.base.read(paddr, BLOCK_SIZE)
#                 if not new_stuff and zero:
#                     new_stuff = "\0" * BLOCK_SIZE
#                 elif not new_stuff:
#                     return None
#                 else:
#                     stuff_read = stuff_read + new_stuff
#             new_vaddr = new_vaddr + BLOCK_SIZE
# 
#         if left_over > 0:
#             paddr = self.vtop(new_vaddr)
#             if paddr == None and zero:
#                 stuff_read = stuff_read + "\0" * left_over
#             elif paddr == None:
#                 return None
#             else:
#                 stuff_read = stuff_read + self.base.read(paddr, left_over)
#         return stuff_read
# 
#     def read_long_phys(self, addr):
#         string = self.base.read(addr, 4)
#         (longval, ) =  struct.unpack('L', string)
#         return longval
# 
#     def is_valid_address(self, vaddr):
#         paddr = self.vtop(vaddr)
#         if not paddr: return False
#         return self.base.is_valid_address(paddr)
# 
# Path: owade/fileAnalyze/hashcatLib/framework/win32/hashdump.py
# def get_bootkey(sysaddr):
#     cs = find_control_set(sysaddr)
#     lsa_base = ["ControlSet%03d" % cs, "Control", "Lsa"]
#     lsa_keys = ["JD","Skew1","GBG","Data"]
# 
#     root = get_root(sysaddr)
#     if not root: return None
# 
#     lsa = open_key(root, lsa_base)
#     if not lsa: return None
# 
#     bootkey = ""
#     
#     for lk in lsa_keys:
#         key = open_key(lsa, [lk])
#         class_data = sysaddr.read(key.Class.value, key.ClassLength.value)
#         bootkey += class_data.decode('utf-16-le').decode('hex')
#     
#     bootkey_scrambled = ""
#     for i in range(len(bootkey)):
#         bootkey_scrambled += bootkey[p[i]]
#     
#     return bootkey_scrambled
# 
# def str_to_key(s):
#     key = []
#     key.append( ord(s[0])>>1 )
#     key.append( ((ord(s[0])&0x01)<<6) | (ord(s[1])>>2) )
#     key.append( ((ord(s[1])&0x03)<<5) | (ord(s[2])>>3) )
#     key.append( ((ord(s[2])&0x07)<<4) | (ord(s[3])>>4) )
#     key.append( ((ord(s[3])&0x0F)<<3) | (ord(s[4])>>5) )
#     key.append( ((ord(s[4])&0x1F)<<2) | (ord(s[5])>>6) )
#     key.append( ((ord(s[5])&0x3F)<<1) | (ord(s[6])>>7) )
#     key.append( ord(s[6])&0x7F )
#     for i in range(8):
#         key[i] = (key[i]<<1)
#         key[i] = odd_parity[key[i]]
#     return "".join(chr(k) for k in key)


from Crypto.Hash import MD5, SHA256
from Crypto.Cipher import ARC4,DES, AES
from owade.fileAnalyze.hashcatLib.framework.win32.rawreg import *
from owade.fileAnalyze.hashcatLib.framework.addrspace import HiveFileAddressSpace
from owade.fileAnalyze.hashcatLib.framework.win32.hashdump import get_bootkey,str_to_key
    secrets_key = open_key(root, ["Policy", "Secrets"])
    if not secrets_key:
        return None
    
    secrets = {}
    for key in subkeys(secrets_key):
        sec_val_key = open_key(key, ["CurrVal"])
        if not sec_val_key:
            continue
        
        enc_secret_value = sec_val_key.ValueList.List[0]
        if not enc_secret_value:
            continue
        
        enc_secret = secaddr.read(enc_secret_value.Data.value,
                enc_secret_value.DataLength.value)
        if not enc_secret:
            continue

        if vista:
            secret = decrypt_aes(enc_secret, lsakey)
        else:
            secret = decrypt_secret(enc_secret[0xC:], lsakey)

        secrets[key.Name] = secret

    return secrets

def get_file_secrets(sysfile, secfile, vista):
    sysaddr = HiveFileAddressSpace(sysfile)

# Path: owade/fileAnalyze/hashcatLib/framework/addrspace.py
# class HiveFileAddressSpace:
#     def __init__(self, fname):
#         self.fname = fname
#         self.base = FileAddressSpace(fname)
# 
#     def vtop(self, vaddr):
#         return vaddr + BLOCK_SIZE + 4
# 
#     def read(self, vaddr, length, zero=False):
#         first_block = BLOCK_SIZE - vaddr % BLOCK_SIZE
#         full_blocks = ((length + (vaddr % BLOCK_SIZE)) / BLOCK_SIZE) - 1
#         left_over = (length + vaddr) % BLOCK_SIZE
#         
#         paddr = self.vtop(vaddr)
#         if paddr == None and zero:
#             if length < first_block:
#                 return "\0" * length
#             else:
#                 stuff_read = "\0" * first_block
#         elif paddr == None:
#             return None
#         else:
#             if length < first_block:
#                 stuff_read = self.base.read(paddr, length)
#                 if not stuff_read and zero:
#                     return "\0" * length
#                 else:
#                     return stuff_read
# 
#             stuff_read = self.base.read(paddr, first_block)
#             if not stuff_read and zero:
#                 stuff_read = "\0" * first_block
# 
#         new_vaddr = vaddr + first_block
#         for i in range(0,full_blocks):
#             paddr = self.vtop(new_vaddr)
#             if paddr == None and zero:
#                 stuff_read = stuff_read + "\0" * BLOCK_SIZE
#             elif paddr == None:
#                 return None
#             else:
#                 new_stuff = self.base.read(paddr, BLOCK_SIZE)
#                 if not new_stuff and zero:
#                     new_stuff = "\0" * BLOCK_SIZE
#                 elif not new_stuff:
#                     return None
#                 else:
#                     stuff_read = stuff_read + new_stuff
#             new_vaddr = new_vaddr + BLOCK_SIZE
# 
#         if left_over > 0:
#             paddr = self.vtop(new_vaddr)
#             if paddr == None and zero:
#                 stuff_read = stuff_read + "\0" * left_over
#             elif paddr == None:
#                 return None
#             else:
#                 stuff_read = stuff_read + self.base.read(paddr, left_over)
#         return stuff_read
# 
#     def read_long_phys(self, addr):
#         string = self.base.read(addr, 4)
#         (longval, ) =  struct.unpack('L', string)
#         return longval
# 
#     def is_valid_address(self, vaddr):
#         paddr = self.vtop(vaddr)
#         if not paddr: return False
#         return self.base.is_valid_address(paddr)
# 
# Path: owade/fileAnalyze/hashcatLib/framework/win32/hashdump.py
# def get_bootkey(sysaddr):
#     cs = find_control_set(sysaddr)
#     lsa_base = ["ControlSet%03d" % cs, "Control", "Lsa"]
#     lsa_keys = ["JD","Skew1","GBG","Data"]
# 
#     root = get_root(sysaddr)
#     if not root: return None
# 
#     lsa = open_key(root, lsa_base)
#     if not lsa: return None
# 
#     bootkey = ""
#     
#     for lk in lsa_keys:
#         key = open_key(lsa, [lk])
#         class_data = sysaddr.read(key.Class.value, key.ClassLength.value)
#         bootkey += class_data.decode('utf-16-le').decode('hex')
#     
#     bootkey_scrambled = ""
#     for i in range(len(bootkey)):
#         bootkey_scrambled += bootkey[p[i]]
#     
#     return bootkey_scrambled
# 
# def str_to_key(s):
#     key = []
#     key.append( ord(s[0])>>1 )
#     key.append( ((ord(s[0])&0x01)<<6) | (ord(s[1])>>2) )
#     key.append( ((ord(s[1])&0x03)<<5) | (ord(s[2])>>3) )
#     key.append( ((ord(s[2])&0x07)<<4) | (ord(s[3])>>4) )
#     key.append( ((ord(s[3])&0x0F)<<3) | (ord(s[4])>>5) )
#     key.append( ((ord(s[4])&0x1F)<<2) | (ord(s[5])>>6) )
#     key.append( ((ord(s[5])&0x3F)<<1) | (ord(s[6])>>7) )
#     key.append( ord(s[6])&0x7F )
#     for i in range(8):
#         key[i] = (key[i]<<1)
#         key[i] = odd_parity[key[i]]
#     return "".join(chr(k) for k in key)


# Path: owade/fileAnalyze/hashcatLib/framework/win32/lsasecrets.py
from Crypto.Hash import MD5, SHA256
from Crypto.Cipher import ARC4,DES, AES
from owade.fileAnalyze.hashcatLib.framework.win32.rawreg import *
from owade.fileAnalyze.hashcatLib.framework.addrspace import HiveFileAddressSpace
from owade.fileAnalyze.hashcatLib.framework.win32.hashdump import get_bootkey,str_to_key

    secrets_key = open_key(root, ["Policy", "Secrets"])
    if not secrets_key:
        return None
    
    secrets = {}
    for key in subkeys(secrets_key):
        sec_val_key = open_key(key, ["CurrVal"])
        if not sec_val_key:
            continue
        
        enc_secret_value = sec_val_key.ValueList.List[0]
        if not enc_secret_value:
            continue
        
        enc_secret = secaddr.read(enc_secret_value.Data.value,
                enc_secret_value.DataLength.value)
        if not enc_secret:
            continue

        if vista:
            secret = decrypt_aes(enc_secret, lsakey)
        else:
            secret = decrypt_secret(enc_secret[0xC:], lsakey)

        secrets[key.Name] = secret

    return secrets

def get_file_secrets(sysfile, secfile, vista):
    sysaddr = HiveFileAddressSpace(sysfile)

    secaddr = HiveFileAddressSpace(secfile)