Various changes:

1. Add .gitignore
2. Fix line endings as mixed LF and CRLF files
3. Reformat of code to PEP8 standards
This commit is contained in:
Dave Parsons 2015-01-31 16:22:32 +00:00
parent 229e1aee78
commit 283442fd64
2 changed files with 317 additions and 335 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
backup/ backup/
.idea/

View File

@ -1,334 +1,316 @@
""" """
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014 Dave Parsons Copyright (c) 2014 Dave Parsons
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the 'Software'), to deal of this software and associated documentation files (the 'Software'), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
vSMC Header Structure vSMC Header Structure
Offset Length struct Type Description Offset Length struct Type Description
---------------------------------------- ----------------------------------------
0x00/00 0x08/08 Q ptr Offset to key table 0x00/00 0x08/08 Q ptr Offset to key table
0x08/08 0x04/4 I int Number of private keys 0x08/08 0x04/4 I int Number of private keys
0x0C/12 0x04/4 I int Number of public keys 0x0C/12 0x04/4 I int Number of public keys
vSMC Key Data Structure vSMC Key Data Structure
Offset Length struct Type Description Offset Length struct Type Description
---------------------------------------- ----------------------------------------
0x00/00 0x04/04 4s int Key name (byte reversed e.g. #KEY is YEK#) 0x00/00 0x04/04 4s int Key name (byte reversed e.g. #KEY is YEK#)
0x04/04 0x01/01 B byte Length of returned data 0x04/04 0x01/01 B byte Length of returned data
0x05/05 0x04/04 4s int Data type (byte reversed e.g. ui32 is 23iu) 0x05/05 0x04/04 4s int Data type (byte reversed e.g. ui32 is 23iu)
0x09/09 0x01/01 B byte Flag R/W 0x09/09 0x01/01 B byte Flag R/W
0x0A/10 0x06/06 6x byte Padding 0x0A/10 0x06/06 6x byte Padding
0x10/16 0x08/08 Q ptr Internal VMware routine 0x10/16 0x08/08 Q ptr Internal VMware routine
0x18/24 0x30/48 48B byte Data 0x18/24 0x30/48 48B byte Data
""" """
import optparse import os
import os import sys
import sys import struct
import struct
# Setup imports depending on whether IronPython or CPython
# Setup imports depending on whether IronPython or CPython if sys.platform == 'win32' \
if sys.platform == 'win32' \ or sys.platform == 'cli':
or sys.platform == 'cli': from _winreg import *
from _winreg import *
def rot13(s):
def rot13(s): chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz'
chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz' trans = chars[26:] + chars[:26]
trans = chars[26:] + chars[:26] rot_char = lambda c: trans[chars.find(c)] if chars.find(c) > -1 else c
rot_char = lambda c: trans[chars.find(c)] if chars.find(c) > -1 else c return ''.join(rot_char(c) for c in s)
return ''.join(rot_char(c) for c in s)
def bytetohex(bytestr):
def bytetohex(bytestr): return ''.join(['%02X ' % ord(x) for x in bytestr]).strip()
return ''.join(['%02X ' % ord(x) for x in bytestr]).strip()
def printkey(i, smc_key, smc_data):
def printkey(i, smc_key, smc_data): print str(i+1).zfill(3) \
print str(i).zfill(3) \ + ' ' + smc_key[0][::-1] \
+ ' ' + smc_key[0][::-1] \ + ' ' + str(smc_key[1]).zfill(2) \
+ ' ' + str(smc_key[1]).zfill(2) \ + ' ' + smc_key[2][::-1].replace('\x00', ' ') \
+ ' ' + smc_key[2][::-1].replace('\x00', ' ') \ + ' ' + '{0:#0{1}x}'.format(smc_key[3], 4) \
+ ' ' + '{0:#0{1}x}'.format(smc_key[3],4) \ + ' ' + hex(smc_key[4]) \
+ ' ' + hex(smc_key[4]) \ + ' ' + bytetohex(smc_data)
+ ' ' + bytetohex(smc_data)
def patchkeys(f, key):
def patchkeys(f, key): # Setup struct pack string
global smc_new_memptr
# Setup struct pack string key_pack = '=4sB4sB6xQ'
key_pack = '=4sB4sB6xQ'
# Do Until OSK1 read
# Do Until OSK1 read i = 0
i = 0 while True:
while True:
# Read key into struct str and data byte str
# Read key into struct str and data byte str offset = key + (i * 72)
offset = key + (i * 72) f.seek(offset)
f.seek(offset) smc_key = struct.unpack(key_pack, f.read(24))
smc_key = struct.unpack(key_pack, f.read(24)) smc_data = f.read(smc_key[1])
smc_data = f.read(smc_key[1])
# Reset pointer to beginning of key entry
# Reset pointer to beginning of key entry f.seek(offset)
f.seek(offset)
if smc_key[0] == 'SKL+':
if smc_key[0] == 'SKL+': # Use the +LKS data routine for OSK0/1
# Use the +LKS data routine for OSK0/1 smc_new_memptr = smc_key[4]
smc_new_memptr = smc_key[4] print '+LKS Key: '
print '+LKS Key: ' printkey(i, smc_key, smc_data)
printkey(i, smc_key, smc_data)
elif smc_key[0] == '0KSO':
elif smc_key[0] == '0KSO': # Write new data routine pointer from +LKS
# Write new data routine pointer from +LKS print 'OSK0 Key Before:'
print 'OSK0 Key Before:' printkey(i, smc_key, smc_data)
printkey(i, smc_key, smc_data) f.seek(offset)
f.seek(offset) f.write(struct.pack(key_pack, smc_key[0], smc_key[1], smc_key[2], smc_key[3], smc_new_memptr))
f.write(struct.pack(key_pack, smc_key[0], smc_key[1], smc_key[2], smc_key[3], smc_new_memptr)) f.flush()
f.flush()
# Write new data for key
# Write new data for key f.seek(offset + 24)
f.seek(offset + 24) smc_new_data = rot13('bheuneqjbexolgurfrjbeqfthneqrqcy')
smc_new_data = rot13('bheuneqjbexolgurfrjbeqfthneqrqcy') f.write(smc_new_data)
f.write(smc_new_data) f.flush()
f.flush()
# Re-read and print key
# Re-read and print key f.seek(offset)
f.seek(offset) smc_key = struct.unpack(key_pack, f.read(24))
smc_key = struct.unpack(key_pack, f.read(24)) smc_data = f.read(smc_key[1])
smc_data = f.read(smc_key[1]) print 'OSK0 Key After:'
print 'OSK0 Key After:' printkey(i, smc_key, smc_data)
printkey(i, smc_key, smc_data)
elif smc_key[0] == '1KSO':
elif smc_key[0] == '1KSO': # Write new data routine pointer from +LKS
# Write new data routine pointer from +LKS print 'OSK1 Key Before:'
print 'OSK1 Key Before:' printkey(i, smc_key, smc_data)
printkey(i, smc_key, smc_data) f.seek(offset)
f.seek(offset) f.write(struct.pack(key_pack, smc_key[0], smc_key[1], smc_key[2], smc_key[3], smc_new_memptr))
f.write(struct.pack(key_pack, smc_key[0], smc_key[1], smc_key[2], smc_key[3], smc_new_memptr)) f.flush()
f.flush()
# Write new data for key
# Write new data for key f.seek(offset + 24)
f.seek(offset + 24) smc_new_data = rot13('rnfrqbagfgrny(p)NccyrPbzchgreVap')
smc_new_data = rot13('rnfrqbagfgrny(p)NccyrPbzchgreVap') f.write(smc_new_data)
f.write(smc_new_data) f.flush()
f.flush()
# Re-read and print key
# Re-read and print key f.seek(offset)
f.seek(offset) smc_key = struct.unpack(key_pack, f.read(24))
smc_key = struct.unpack(key_pack, f.read(24)) smc_data = f.read(smc_key[1])
smc_data = f.read(smc_key[1]) print 'OSK1 Key After:'
print 'OSK1 Key After:' printkey(i, smc_key, smc_data)
printkey(i, smc_key, smc_data)
# Finished so get out of loop
# Finished so get out of loop break
break
else:
else: pass
pass
i += 1
i += 1
def patchsmc(name):
def patchsmc(name): with open(name, 'r+b') as f:
with open(name, 'r+b') as f: # Read file into string variable
vmx = f.read()
# Read file into string variable
vmx = f.read() print 'File: ' + name
print 'File: ' + name # Setup hex string for vSMC headers
# These are the private and public key counts
# Setup hex string for vSMC headers smc_header_v0 = '\xF2\x00\x00\x00\xF0\x00\x00\x00'
# These are the private and public key counts smc_header_v1 = '\xB4\x01\x00\x00\xB0\x01\x00\x00'
smc_header_v0 = '\xF2\x00\x00\x00\xF0\x00\x00\x00'
smc_header_v1 = '\xB4\x01\x00\x00\xB0\x01\x00\x00' # Setup hex string for #KEY key
key_key = '\x59\x45\x4B\x23\x04\x32\x33\x69\x75'
# Setup hex string for #KEY key
key_key = '\x59\x45\x4B\x23\x04\x32\x33\x69\x75' # Setup hex string for $Adr key
adr_key = '\x72\x64\x41\x24\x04\x32\x33\x69\x75'
# Setup hex string for $Adr key
adr_key = '\x72\x64\x41\x24\x04\x32\x33\x69\x75' # Find the vSMC headers
smc_header_v0_offset = vmx.find(smc_header_v0) - 8
# Find the vSMC headers smc_header_v1_offset = vmx.find(smc_header_v1) - 8
smc_header_v0_offset = vmx.find(smc_header_v0) - 8
smc_header_v1_offset = vmx.find(smc_header_v1) - 8 # Find '#KEY' keys
smc_key0 = vmx.find(key_key)
# Find '#KEY' keys smc_key1 = vmx.rfind(key_key)
smc_key0 = vmx.find(key_key)
smc_key1 = vmx.rfind(key_key) # Find '$Adr' key only V1 table
smc_adr = vmx.find(adr_key)
# Find '$Adr' key only V1 table
smc_adr = vmx.find(adr_key) # Print vSMC0 tables and keys
print 'applesmctablev0 (smc.version = "0")'
# Read the vSMC version 0 header print 'applesmctablev0 Address : ' + hex(smc_header_v0_offset)
f.seek(smc_header_v0_offset) print 'applesmctablev0 Private Key #: 0xF2/242'
appleSMCTableV0 = struct.unpack('=QII', f.read(16)) print 'applesmctablev0 Public Key #: 0xF0/240'
# Read the vSMC version 1 header if (smc_adr - smc_key0) != 72:
f.seek(smc_header_v1_offset) print 'applesmctablev0 Table : ' + hex(smc_key0)
appleSMCTableV1 = struct.unpack('=QII', f.read(16)) patchkeys(f, smc_key0)
elif (smc_adr - smc_key1) != 72:
# Print vSMC0 tables and keys print 'applesmctablev0 Table : ' + hex(smc_key1)
print 'appleSMCTableV0 (smc.version = "0")' patchkeys(f, smc_key1)
print 'appleSMCTableV0 Address : ' + hex(smc_header_v0_offset)
print 'appleSMCTableV0 Private Key #: 0xF2' print
print 'appleSMCTableV0 Public Key #: 0xF0'
# Print vSMC1 tables and keys
if (smc_adr - smc_key0) != 72: print 'applesmctablev1 (smc.version = "1")'
print 'appleSMCTableV0 Table : ' + hex(smc_key0) print 'applesmctablev1 Address : ' + hex(smc_header_v1_offset)
patchkeys(f, smc_key0) print 'applesmctablev1 Private Key #: 0x01B4/436'
elif (smc_adr - smc_key1) != 72: print 'applesmctablev1 Public Key #: 0x01B0/432'
print 'appleSMCTableV0 Table : ' + hex(smc_key1)
patchkeys(f, smc_key1) if (smc_adr - smc_key0) == 72:
else: print 'applesmctablev1 Table : ' + hex(smc_key0)
print 'appleSMCTableV0 Error : ' \ patchkeys(f, smc_key0)
+ hex((appleSMCTableV0[0] - data_offset) - smc_key0) + ' ' \ elif (smc_adr - smc_key1) == 72:
+ hex((appleSMCTableV0[0] - data_offset) - smc_key1) print 'applesmctablev1 Table : ' + hex(smc_key1)
patchkeys(f, smc_key1)
print
print
# Print vSMC1 tables and keys
print 'appleSMCTableV1 (smc.version = "1")' # Tidy up
print 'appleSMCTableV1 Address : ' + hex(smc_header_v1_offset) f.flush()
print 'appleSMCTableV1 Private Key #: 0x01B0' f.close()
print 'appleSMCTableV1 Public Key #: 0x01B4'
if (smc_adr - smc_key0) == 72: def patchbase(name):
print 'appleSMCTableV1 Table : ' + hex(smc_key0) # Patch file
patchkeys(f, smc_key0) print 'GOS Patching: ' + name
elif (smc_adr - smc_key1) == 72: f = open(name, 'r+b')
print 'appleSMCTableV1 Table : ' + hex(smc_key1)
patchkeys(f, smc_key1) # Entry to search for in GOS table
else: darwin = (
print 'appleSMCTableV1 Error : ' \ '\x10\x00\x00\x00\x10\x00\x00\x00'
+ hex((appleSMCTableV1[0] - data_offset) - smc_key0) + ' ' \ '\x02\x00\x00\x00\x00\x00\x00\x00'
+ hex((appleSMCTableV1[0] - data_offset) - smc_key1) '\x00\x00\x00\x00\x00\x00\x00\x00'
'\x00\x00\x00\x00\x00\x00\x00\x00'
print '\xBE'
)
# Tidy up
f.flush() # Read file into string variable
f.close() base = f.read()
def patchbase(name): # Loop thorugh each entry and set top bit
# 0xBE --> 0xBF
# Patch file offset = 0
print 'GOS Patching: ' + name while offset < len(base):
f = open(name, 'r+b') offset = base.find(darwin, offset)
if offset == -1:
# Entry to search for in GOS table break
darwin = ( f.seek(offset + 32)
'\x10\x00\x00\x00\x10\x00\x00\x00' flag = f.read(1)
'\x02\x00\x00\x00\x00\x00\x00\x00' if flag == '\xBE':
'\x00\x00\x00\x00\x00\x00\x00\x00' f.seek(offset + 32)
'\x00\x00\x00\x00\x00\x00\x00\x00' f.write('\xBF')
'\xBE' print 'GOS Patched flag @: ' + hex(offset)
) else:
print 'GOS Unknown flag @: {0}/{1}'.format(hex(offset), hex(flag))
# Read file into string variable
base = f.read() offset += 33
# Loop thorugh each entry and set top bit # # Tidy up
# 0xBE --> 0xBF f.flush()
offset = 0 f.close()
while offset < len(base): print 'GOS Patched: ' + name
offset = base.find(darwin, offset)
if offset == -1:
break def main():
f.seek(offset + 32)
flag = f.read(1) # Work around absent Platform module on VMkernel
if flag == '\xBE': if os.name == 'nt' or os.name == 'cli':
f.seek(offset + 32) osname = 'windows'
f.write('\xBF') else:
print 'GOS Patched flag @: ' + hex(offset) osname = os.uname()[0].lower()
else:
print 'GOS Unknown flag @: ' + hex(offset) + '/' + hex(flag) # Setup default paths
if osname == 'darwin':
offset += 33 vmx_path = '/Applications/VMware Fusion.app/Contents/Library/'
vmx = vmx_path + 'vmware-vmx'
# # Tidy up vmx_debug = vmx_path + 'vmware-vmx-debug'
f.flush() vmx_stats = vmx_path + 'vmware-vmx-stats'
f.close() vmwarebase = ''
print 'GOS Patched: ' + name
elif osname == 'linux':
vmx_path = '/usr/lib/vmware/bin/'
def main(): vmx = vmx_path + 'vmware-vmx'
vmx_debug = vmx_path + 'vmware-vmx-debug'
# Work around absent Platform module on VMkernel vmx_stats = vmx_path + 'vmware-vmx-stats'
if os.name == 'nt' or os.name == 'cli': vmwarebase = '/usr/lib/vmware/lib/libvmwarebase.so.0/libvmwarebase.so.0'
osname = 'windows'
else: elif osname == 'vmkernel':
osname = os.uname()[0].lower() vmx_path = '/unlocker/'
vmx = vmx_path + 'vmx'
# Setup default paths vmx_debug = vmx_path + 'vmx-debug'
if osname == 'darwin': vmx_stats = vmx_path + 'vmx-stats'
vmx_path = '/Applications/VMware Fusion.app/Contents/Library/' vmwarebase = ''
vmx = vmx_path + 'vmware-vmx'
vmx_debug = vmx_path + 'vmware-vmx-debug' elif osname == 'windows':
vmx_stats = vmx_path + 'vmware-vmx-stats' reg = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
vmwarebase = '' key = OpenKey(reg, r'SOFTWARE\Wow6432Node\VMware, Inc.\VMware Workstation')
vmwarebase_path = QueryValueEx(key, 'InstallPath')[0]
elif osname == 'linux': vmx_path = QueryValueEx(key, 'InstallPath64')[0]
vmx_path = '/usr/lib/vmware/bin/' vmx = vmx_path + 'vmware-vmx.exe'
vmx = vmx_path + 'vmware-vmx' vmx_debug = vmx_path + 'vmware-vmx-debug.exe'
vmx_debug = vmx_path + 'vmware-vmx-debug' vmx_stats = vmx_path + 'vmware-vmx-stats.exe'
vmx_stats = vmx_path + 'vmware-vmx-stats' vmwarebase = vmwarebase_path + 'vmwarebase.dll'
vmwarebase = '/usr/lib/vmware/lib/libvmwarebase.so.0/libvmwarebase.so.0'
else:
elif osname == 'vmkernel': print('Unknown Operating System: ' + osname)
vmx_path = '/unlocker/' return
vmx = vmx_path + 'vmx'
vmx_debug = vmx_path + 'vmx-debug' # Patch the vmx executables skipping stats version for Player
vmx_stats = vmx_path + 'vmx-stats' patchsmc(vmx)
vmwarebase = '' patchsmc(vmx_debug)
try:
elif osname == 'windows': patchsmc(vmx_stats)
reg = ConnectRegistry(None, HKEY_LOCAL_MACHINE) except IOError:
key = OpenKey(reg, r'SOFTWARE\Wow6432Node\VMware, Inc.\VMware Workstation') pass
vmwarebase_path = QueryValueEx(key, 'InstallPath')[0]
vmx_path = QueryValueEx(key, 'InstallPath64')[0] # Patch vmwarebase for Workstation and Player
vmx = vmx_path + 'vmware-vmx.exe' # Not required on Fusion or ESXi as table already has correct flags
vmx_debug = vmx_path + 'vmware-vmx-debug.exe' if vmwarebase != '':
vmx_stats = vmx_path + 'vmware-vmx-stats.exe' patchbase(vmwarebase)
vmwarebase = vmwarebase_path + 'vmwarebase.dll' else:
print 'Patching vmwarebase is not required on this system'
else:
print('Unknown Operating System: ' + osname)
return if __name__ == '__main__':
main()
# Patch the vmx executables skipping stats version for Player
patchsmc(vmx)
patchsmc(vmx_debug)
try:
patchsmc(vmx_stats)
except IOError:
pass
# Patch vmwarebase for Workstation and Player
# Not required on Fusion or ESXi as table already has correct flags
if vmwarebase != '':
patchbase(vmwarebase)
else:
print 'Patching vmwarebase is not required on this system'
if __name__ == '__main__':
main()