mirror of
https://github.com/paolo-projects/unlocker.git
synced 2025-07-28 16:34:29 +02:00
Moved ESXi code to new repository.
This commit is contained in:
parent
1073f82f1f
commit
9ed1c79d00
2
.gitignore
vendored
2
.gitignore
vendored
@ -6,3 +6,5 @@ tests/
|
|||||||
build/
|
build/
|
||||||
dist/
|
dist/
|
||||||
*.spec
|
*.spec
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
grep -il \(c\)AppleComputerInc /bin/vmx*
|
|
||||||
vim-cmd hostsvc/hosthardware | grep smcPresent | cut -d ',' -f 1 | sed 's/^[ \t]*//'
|
|
||||||
grep useVmxSandbox /etc/vmware/hostd/config.xml | sed 's/^[ \t]*//'
|
|
@ -1,3 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
tar czvf unlocker-esxi-300.tgz unlocker.tgz esxi-install.sh esxi-uninstall.sh
|
|
@ -1,14 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
#set -x
|
|
||||||
|
|
||||||
echo VMware Unlocker 3.0.0
|
|
||||||
echo ===============================
|
|
||||||
echo Copyright: Dave Parsons 2011-18
|
|
||||||
|
|
||||||
# Ensure we only use unmodified commands
|
|
||||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
|
|
||||||
|
|
||||||
echo Installing unlocker.tgz
|
|
||||||
BootModuleConfig.sh --verbose --add=unlocker.tgz
|
|
||||||
echo Success - please now restart the server!
|
|
@ -1,14 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
#set -x
|
|
||||||
|
|
||||||
echo VMware Unlocker 3.0.0
|
|
||||||
echo ===============================
|
|
||||||
echo Copyright: Dave Parsons 2011-18
|
|
||||||
|
|
||||||
# Ensure we only use unmodified commands
|
|
||||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
|
|
||||||
|
|
||||||
echo Uninstalling unlocker.tgz
|
|
||||||
BootModuleConfig.sh --verbose --remove=unlocker.tgz
|
|
||||||
echo Success - please now restart the server!
|
|
@ -1,384 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
"""
|
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2014-2018 Dave Parsons & Sam Bingner
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the 'Software'), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
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
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
||||||
vSMC Header Structure
|
|
||||||
Offset Length Struct Type Description
|
|
||||||
----------------------------------------
|
|
||||||
0x00/00 0x08/08 Q ptr Offset to key table
|
|
||||||
0x08/08 0x04/4 I int Number of private keys
|
|
||||||
0x0C/12 0x04/4 I int Number of public keys
|
|
||||||
|
|
||||||
vSMC Key Data Structure
|
|
||||||
Offset Length Struct Type Description
|
|
||||||
----------------------------------------
|
|
||||||
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
|
|
||||||
0x05/05 0x04/04 4s int Data type (byte reversed e.g. ui32 is 23iu)
|
|
||||||
0x09/09 0x01/01 B byte Flag R/W
|
|
||||||
0x0A/10 0x06/06 6x byte Padding
|
|
||||||
0x10/16 0x08/08 Q ptr Internal VMware routine
|
|
||||||
0x18/24 0x30/48 48B byte Data
|
|
||||||
"""
|
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
import codecs
|
|
||||||
import os
|
|
||||||
import shutil
|
|
||||||
import struct
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
|
|
||||||
if sys.version_info < (2, 7):
|
|
||||||
sys.stderr.write('You need Python 2.7 or later\n')
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
def bytetohex(data):
|
|
||||||
if sys.version_info > (3, 0):
|
|
||||||
# Python 3 code in this block
|
|
||||||
return "".join("{:02X} ".format(c) for c in data)
|
|
||||||
else:
|
|
||||||
# Python 2 code in this block
|
|
||||||
return "".join("{:02X} ".format(ord(c)) for c in data)
|
|
||||||
|
|
||||||
|
|
||||||
def joinpath(folder, filename):
|
|
||||||
return os.path.join(folder, filename)
|
|
||||||
|
|
||||||
|
|
||||||
def printkey(i, offset, smc_key, smc_data):
|
|
||||||
print(str(i + 1).zfill(3)
|
|
||||||
+ ' ' + hex(offset)
|
|
||||||
+ ' ' + smc_key[0][::-1].decode('UTF-8')
|
|
||||||
+ ' ' + str(smc_key[1]).zfill(2)
|
|
||||||
+ ' ' + smc_key[2][::-1].replace(b'\x00', b' ').decode('UTF-8')
|
|
||||||
+ ' ' + '{0:#0{1}x}'.format(smc_key[3], 4)
|
|
||||||
+ ' ' + hex(smc_key[4])
|
|
||||||
+ ' ' + bytetohex(smc_data))
|
|
||||||
|
|
||||||
|
|
||||||
def set_bit(value, bit):
|
|
||||||
return value | (1 << bit)
|
|
||||||
|
|
||||||
|
|
||||||
def clear_bit(value, bit):
|
|
||||||
return value & ~(1 << bit)
|
|
||||||
|
|
||||||
|
|
||||||
def test_bit(value, bit):
|
|
||||||
return value & bit
|
|
||||||
|
|
||||||
|
|
||||||
E_CLASS64 = 2
|
|
||||||
E_SHT_RELA = 4
|
|
||||||
|
|
||||||
|
|
||||||
def patchelf(f, oldoffset, newoffset):
|
|
||||||
f.seek(0)
|
|
||||||
magic = f.read(4)
|
|
||||||
if not magic == b'\x7fELF':
|
|
||||||
raise Exception('Magic number does not match')
|
|
||||||
|
|
||||||
ei_class = struct.unpack('=B', f.read(1))[0]
|
|
||||||
if ei_class != E_CLASS64:
|
|
||||||
raise Exception('Not 64bit elf header: ' + ei_class)
|
|
||||||
|
|
||||||
f.seek(40)
|
|
||||||
e_shoff = struct.unpack('=Q', f.read(8))[0]
|
|
||||||
f.seek(58)
|
|
||||||
e_shentsize = struct.unpack('=H', f.read(2))[0]
|
|
||||||
e_shnum = struct.unpack('=H', f.read(2))[0]
|
|
||||||
e_shstrndx = struct.unpack('=H', f.read(2))[0]
|
|
||||||
|
|
||||||
print('e_shoff: 0x{:x} e_shentsize: 0x{:x} e_shnum:0x{:x} e_shstrndx:0x{:x}'.format(e_shoff, e_shentsize,
|
|
||||||
e_shnum, e_shstrndx))
|
|
||||||
|
|
||||||
for i in range(0, e_shnum):
|
|
||||||
f.seek(e_shoff + i * e_shentsize)
|
|
||||||
e_sh = struct.unpack('=LLQQQQLLQQ', f.read(e_shentsize))
|
|
||||||
# e_sh_name = e_sh[0]
|
|
||||||
e_sh_type = e_sh[1]
|
|
||||||
e_sh_offset = e_sh[4]
|
|
||||||
e_sh_size = e_sh[5]
|
|
||||||
e_sh_entsize = e_sh[9]
|
|
||||||
if e_sh_type == E_SHT_RELA:
|
|
||||||
e_sh_nument = int(e_sh_size / e_sh_entsize)
|
|
||||||
# print 'RELA at 0x{:x} with {:d} entries'.format(e_sh_offset, e_sh_nument)
|
|
||||||
for j in range(0, e_sh_nument):
|
|
||||||
f.seek(e_sh_offset + e_sh_entsize * j)
|
|
||||||
rela = struct.unpack('=QQq', f.read(e_sh_entsize))
|
|
||||||
r_offset = rela[0]
|
|
||||||
r_info = rela[1]
|
|
||||||
r_addend = rela[2]
|
|
||||||
if r_addend == oldoffset:
|
|
||||||
r_addend = newoffset
|
|
||||||
f.seek(e_sh_offset + e_sh_entsize * j)
|
|
||||||
f.write(struct.pack('=QQq', r_offset, r_info, r_addend))
|
|
||||||
print('Relocation modified at: ' + hex(e_sh_offset + e_sh_entsize * j))
|
|
||||||
|
|
||||||
|
|
||||||
def patchkeys(f, key):
|
|
||||||
# Setup struct pack string
|
|
||||||
key_pack = '=4sB4sB6xQ'
|
|
||||||
# smc_old_memptr = 0
|
|
||||||
smc_new_memptr = 0
|
|
||||||
|
|
||||||
# Do Until OSK1 read
|
|
||||||
i = 0
|
|
||||||
while True:
|
|
||||||
|
|
||||||
# Read key into struct str and data byte str
|
|
||||||
offset = key + (i * 72)
|
|
||||||
f.seek(offset)
|
|
||||||
smc_key = struct.unpack(key_pack, f.read(24))
|
|
||||||
smc_data = f.read(smc_key[1])
|
|
||||||
|
|
||||||
# Reset pointer to beginning of key entry
|
|
||||||
f.seek(offset)
|
|
||||||
|
|
||||||
if smc_key[0] == b'SKL+':
|
|
||||||
# Use the +LKS data routine for OSK0/1
|
|
||||||
smc_new_memptr = smc_key[4]
|
|
||||||
print('+LKS Key: ')
|
|
||||||
printkey(i, offset, smc_key, smc_data)
|
|
||||||
|
|
||||||
elif smc_key[0] == b'0KSO':
|
|
||||||
# Write new data routine pointer from +LKS
|
|
||||||
print('OSK0 Key Before:')
|
|
||||||
printkey(i, offset, smc_key, smc_data)
|
|
||||||
# smc_old_memptr = smc_key[4]
|
|
||||||
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.flush()
|
|
||||||
|
|
||||||
# Write new data for key
|
|
||||||
f.seek(offset + 24)
|
|
||||||
smc_new_data = codecs.encode('bheuneqjbexolgurfrjbeqfthneqrqcy', 'rot_13')
|
|
||||||
f.write(smc_new_data.encode('UTF-8'))
|
|
||||||
f.flush()
|
|
||||||
|
|
||||||
# Re-read and print key
|
|
||||||
f.seek(offset)
|
|
||||||
smc_key = struct.unpack(key_pack, f.read(24))
|
|
||||||
smc_data = f.read(smc_key[1])
|
|
||||||
print('OSK0 Key After:')
|
|
||||||
printkey(i, offset, smc_key, smc_data)
|
|
||||||
|
|
||||||
elif smc_key[0] == b'1KSO':
|
|
||||||
# Write new data routine pointer from +LKS
|
|
||||||
print('OSK1 Key Before:')
|
|
||||||
printkey(i, offset, smc_key, smc_data)
|
|
||||||
smc_old_memptr = smc_key[4]
|
|
||||||
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.flush()
|
|
||||||
|
|
||||||
# Write new data for key
|
|
||||||
f.seek(offset + 24)
|
|
||||||
smc_new_data = codecs.encode('rnfrqbagfgrny(p)NccyrPbzchgreVap', 'rot_13')
|
|
||||||
f.write(smc_new_data.encode('UTF-8'))
|
|
||||||
f.flush()
|
|
||||||
|
|
||||||
# Re-read and print key
|
|
||||||
f.seek(offset)
|
|
||||||
smc_key = struct.unpack(key_pack, f.read(24))
|
|
||||||
smc_data = f.read(smc_key[1])
|
|
||||||
print('OSK1 Key After:')
|
|
||||||
printkey(i, offset, smc_key, smc_data)
|
|
||||||
|
|
||||||
# Finished so get out of loop
|
|
||||||
break
|
|
||||||
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
|
|
||||||
i += 1
|
|
||||||
return smc_old_memptr, smc_new_memptr
|
|
||||||
|
|
||||||
|
|
||||||
def patchsmc(name, sharedobj):
|
|
||||||
with open(name, 'r+b') as f:
|
|
||||||
|
|
||||||
smc_old_memptr = 0
|
|
||||||
smc_new_memptr = 0
|
|
||||||
|
|
||||||
# Read file into string variable
|
|
||||||
vmx = f.read()
|
|
||||||
|
|
||||||
print('File: ' + name + '\n')
|
|
||||||
|
|
||||||
# Setup hex string for vSMC headers
|
|
||||||
# These are the private and public key counts
|
|
||||||
smc_header_v0 = b'\xF2\x00\x00\x00\xF0\x00\x00\x00'
|
|
||||||
smc_header_v1 = b'\xB4\x01\x00\x00\xB0\x01\x00\x00'
|
|
||||||
|
|
||||||
# Setup hex string for #KEY key
|
|
||||||
key_key = b'\x59\x45\x4B\x23\x04\x32\x33\x69\x75'
|
|
||||||
|
|
||||||
# Setup hex string for $Adr key
|
|
||||||
adr_key = b'\x72\x64\x41\x24\x04\x32\x33\x69\x75'
|
|
||||||
|
|
||||||
# Find the vSMC headers
|
|
||||||
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)
|
|
||||||
smc_key1 = vmx.rfind(key_key)
|
|
||||||
|
|
||||||
# Find '$Adr' key only V1 table
|
|
||||||
smc_adr = vmx.find(adr_key)
|
|
||||||
|
|
||||||
# Print vSMC0 tables and keys
|
|
||||||
print('appleSMCTableV0 (smc.version = "0")')
|
|
||||||
print('appleSMCTableV0 Address : ' + hex(smc_header_v0_offset))
|
|
||||||
print('appleSMCTableV0 Private Key #: 0xF2/242')
|
|
||||||
print('appleSMCTableV0 Public Key #: 0xF0/240')
|
|
||||||
|
|
||||||
if (smc_adr - smc_key0) != 72:
|
|
||||||
print('appleSMCTableV0 Table : ' + hex(smc_key0))
|
|
||||||
smc_old_memptr, smc_new_memptr = patchkeys(f, smc_key0)
|
|
||||||
elif (smc_adr - smc_key1) != 72:
|
|
||||||
print('appleSMCTableV0 Table : ' + hex(smc_key1))
|
|
||||||
smc_old_memptr, smc_new_memptr = patchkeys(f, smc_key1)
|
|
||||||
|
|
||||||
print()
|
|
||||||
|
|
||||||
# Print vSMC1 tables and keys
|
|
||||||
print('appleSMCTableV1 (smc.version = "1")')
|
|
||||||
print('appleSMCTableV1 Address : ' + hex(smc_header_v1_offset))
|
|
||||||
print('appleSMCTableV1 Private Key #: 0x01B4/436')
|
|
||||||
print('appleSMCTableV1 Public Key #: 0x01B0/432')
|
|
||||||
|
|
||||||
if (smc_adr - smc_key0) == 72:
|
|
||||||
print('appleSMCTableV1 Table : ' + hex(smc_key0))
|
|
||||||
smc_old_memptr, smc_new_memptr = patchkeys(f, smc_key0)
|
|
||||||
elif (smc_adr - smc_key1) == 72:
|
|
||||||
print('appleSMCTableV1 Table : ' + hex(smc_key1))
|
|
||||||
smc_old_memptr, smc_new_memptr = patchkeys(f, smc_key1)
|
|
||||||
|
|
||||||
print()
|
|
||||||
|
|
||||||
# Find matching RELA record in .rela.dyn in ESXi ELF files
|
|
||||||
# This is temporary code until proper ELF parsing written
|
|
||||||
if sharedobj:
|
|
||||||
print('Modifying RELA records from: ' + hex(smc_old_memptr) + ' to ' + hex(smc_new_memptr))
|
|
||||||
patchelf(f, smc_old_memptr, smc_new_memptr)
|
|
||||||
|
|
||||||
# Tidy up
|
|
||||||
f.flush()
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
|
|
||||||
def patchvmkctl(name):
|
|
||||||
# Patch file
|
|
||||||
print('smcPresent Patching: ' + name)
|
|
||||||
f = open(name, 'r+b')
|
|
||||||
|
|
||||||
# Read file into string variable
|
|
||||||
vmkctl = f.read()
|
|
||||||
applesmc = vmkctl.find(b'applesmc')
|
|
||||||
f.seek(applesmc)
|
|
||||||
f.write(b'vmkernel')
|
|
||||||
|
|
||||||
# Tidy up
|
|
||||||
f.flush()
|
|
||||||
f.close()
|
|
||||||
print('smcPresent Patched: ' + name)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
|
|
||||||
# Stop the hostd service
|
|
||||||
subprocess.call('/etc/init.d/hostd stop', shell=True)
|
|
||||||
|
|
||||||
# Current folder
|
|
||||||
currdir = os.getcwd()
|
|
||||||
|
|
||||||
# Source files
|
|
||||||
srcvmx = '/bin/vmx'
|
|
||||||
srclib32 = '/lib/libvmkctl.so'
|
|
||||||
srclib64 = '/lib64/libvmkctl.so'
|
|
||||||
|
|
||||||
# Destination files cuurently tmp but may use scratch
|
|
||||||
basefolder = '/tmp/'
|
|
||||||
destfolder = joinpath(basefolder, 'unlocker')
|
|
||||||
destvmx = joinpath(destfolder,'bin/vmx')
|
|
||||||
destlib32 = joinpath(destfolder,'lib/libvmkctl.so')
|
|
||||||
destlib64 = joinpath(destfolder,'lib64/libvmkctl.so')
|
|
||||||
|
|
||||||
# Work files to create vmtardisk
|
|
||||||
# filetgz = joinpath(destfolder, 'custom.tgz')
|
|
||||||
# filevmtar = joinpath(destfolder, 'custom.vmtar')
|
|
||||||
# filevgz = joinpath(destfolder, 'custom.vgz')
|
|
||||||
|
|
||||||
# Remove files & folder if they exist
|
|
||||||
if os.path.isdir(destfolder):
|
|
||||||
shutil.rmtree(destfolder, True)
|
|
||||||
|
|
||||||
# Create the base folder
|
|
||||||
os.makedirs(destfolder)
|
|
||||||
os.chdir(destfolder)
|
|
||||||
|
|
||||||
# Patch the vmx executable
|
|
||||||
os.makedirs(joinpath(destfolder, 'bin'))
|
|
||||||
shutil.copy2(srcvmx, destvmx)
|
|
||||||
patchsmc(destvmx, True)
|
|
||||||
|
|
||||||
# Patch 32-bit libvmkctl to return Apple SMC present
|
|
||||||
os.makedirs(joinpath(destfolder, 'lib'))
|
|
||||||
shutil.copy2(srclib32, destlib32)
|
|
||||||
patchvmkctl(destlib32)
|
|
||||||
|
|
||||||
# Patch 64-bit libvmkctl to return Apple SMC present
|
|
||||||
if os.path.isfile(srclib64):
|
|
||||||
os.makedirs(joinpath(destfolder, 'lib64'))
|
|
||||||
shutil.copy2(srclib64, destlib64)
|
|
||||||
patchvmkctl(destlib64)
|
|
||||||
|
|
||||||
# Build the gzipped tar file custom.tgz
|
|
||||||
print('\nCreating custom.tgz...')
|
|
||||||
subprocess.call('/bin/tar czvf custom.tgz bin lib lib64', shell=True)
|
|
||||||
|
|
||||||
# Build the vmtar file custom.vmtar
|
|
||||||
print('\nCreating custom.vmtar...')
|
|
||||||
subprocess.call('/bin/vmtar -v -c custom.tgz -o custom.vmtar', shell=True)
|
|
||||||
|
|
||||||
# Build the gzipped vmtar file custom.vgz
|
|
||||||
print('\nCreating custom.vgz...')
|
|
||||||
subprocess.call('/bin/gzip < custom.vmtar > custom.vgz', shell=True)
|
|
||||||
subprocess.call('/bin/vmtar -v -t < custom.vgz', shell=True)
|
|
||||||
|
|
||||||
# Load the tardisk
|
|
||||||
subprocess.call('vmkramdisk custom.vgz', shell=True)
|
|
||||||
|
|
||||||
# Return to script folder
|
|
||||||
os.chdir(currdir)
|
|
||||||
|
|
||||||
# Start the hostd service
|
|
||||||
subprocess.call('/etc/init.d/hostd start', shell=True)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
Binary file not shown.
Binary file not shown.
@ -1,28 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo VMware Unlocker 2.1.1
|
|
||||||
echo ===============================
|
|
||||||
echo Copyright: Dave Parsons 2011-17
|
|
||||||
|
|
||||||
# Ensure we only use unmodified commands
|
|
||||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
|
|
||||||
|
|
||||||
# Make sure only root can run our script
|
|
||||||
if [[ $EUID -ne 0 ]]; then
|
|
||||||
echo "This script must be run as root" 1>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo Creating backup folder...
|
|
||||||
rm -rf ./backup
|
|
||||||
mkdir -p "./backup"
|
|
||||||
cp -v /Applications/VMware\ Fusion.app/Contents/Library/vmware-vmx ./backup/
|
|
||||||
cp -v /Applications/VMware\ Fusion.app/Contents/Library/vmware-vmx-debug ./backup/
|
|
||||||
cp -v /Applications/VMware\ Fusion.app/Contents/Library/vmware-vmx-stats ./backup/
|
|
||||||
cp -v /Applications/VMware\ Fusion.app/Contents/Frameworks/libvmwarebase.dylib ./backup/
|
|
||||||
|
|
||||||
echo Patching...
|
|
||||||
python ./unlocker.py
|
|
||||||
|
|
||||||
echo Finished!
|
|
@ -1,26 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo VMware Unlocker 2.1.1
|
|
||||||
echo ===============================
|
|
||||||
echo Copyright: Dave Parsons 2011-17
|
|
||||||
|
|
||||||
# Ensure we only use unmodified commands
|
|
||||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
|
|
||||||
|
|
||||||
# Make sure only root can run our script
|
|
||||||
if [[ $EUID -ne 0 ]]; then
|
|
||||||
echo "This script must be run as root" 1>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo Restoring files...
|
|
||||||
cp -v ./backup/vmware-vmx /Applications/VMware\ Fusion.app/Contents/Library
|
|
||||||
cp -v ./backup/vmware-vmx-debug /Applications/VMware\ Fusion.app/Contents/Library
|
|
||||||
cp -v ./backup/vmware-vmx-stats /Applications/VMware\ Fusion.app/Contents/Library
|
|
||||||
cp -v ./backup/libvmwarebase.dylib /Applications/VMware\ Fusion.app/Contents/Frameworks/
|
|
||||||
|
|
||||||
echo Removing backup files...
|
|
||||||
rm -rf ./backup
|
|
||||||
|
|
||||||
echo Finished!
|
|
45
readme.txt
45
readme.txt
@ -1,4 +1,4 @@
|
|||||||
macOS Unlocker for VMware V2.1
|
macOS Unlocker for VMware V3.0
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
+-----------------------------------------------------------------------------+
|
+-----------------------------------------------------------------------------+
|
||||||
@ -13,16 +13,15 @@ macOS Unlocker for VMware V2.1
|
|||||||
1. Introduction
|
1. Introduction
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Unlocker 2 is designed for Workstation 11/12/14, Player 7/12/14,
|
Unlocker 3 is designed for Workstation 11/12/14/15, Player 7/12/14/15,
|
||||||
and Fusion 7/8/10.
|
and Fusion 7/8/10.
|
||||||
|
|
||||||
If you are using an earlier product please continue using Unlocker 1.
|
If you are using an earlier product please continue using Unlocker 1.
|
||||||
|
|
||||||
Version 2 has been tested against:
|
Version 3 has been tested against:
|
||||||
|
|
||||||
* Workstation 11/12/14 on Windows and Linux
|
* Workstation 11/12/14/15 on Windows and Linux
|
||||||
* Workstation Player 7/12/14 on Windows and Linux
|
* Workstation Player 7/12/14/15 on Windows and Linux
|
||||||
* Fusion 7/8/10 on macOS Sierra
|
|
||||||
|
|
||||||
The patch code carries out the following modifications dependent on the product
|
The patch code carries out the following modifications dependent on the product
|
||||||
being patched:
|
being patched:
|
||||||
@ -34,9 +33,6 @@ being patched:
|
|||||||
Note that not all products recognise the darwin.iso via install tools menu item.
|
Note that not all products recognise the darwin.iso via install tools menu item.
|
||||||
You will have to manually mount the darwin.iso for example on Workstation 11 and Player 7.
|
You will have to manually mount the darwin.iso for example on Workstation 11 and Player 7.
|
||||||
|
|
||||||
The vmwarebase code does not need to be patched on macOS systems so you will see a
|
|
||||||
message on those systems telling you that it will not be patched.
|
|
||||||
|
|
||||||
In all cases make sure VMware is not running, and any background guests have
|
In all cases make sure VMware is not running, and any background guests have
|
||||||
been shutdown.
|
been shutdown.
|
||||||
|
|
||||||
@ -45,7 +41,7 @@ The code is written in Python as it makes the Unlocker easier to run and maintai
|
|||||||
2. Prerequisites
|
2. Prerequisites
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
The code requires Python 2.7 to work. Most Linux distros and macOS ship with a compatible
|
The code requires Python 2.7 to work. Most Linux distros ship with a compatible
|
||||||
Python interpreter and should work without requiring any additional software.
|
Python interpreter and should work without requiring any additional software.
|
||||||
|
|
||||||
Windows Unlocker has a packaged version of the Python script using PyInstaller,
|
Windows Unlocker has a packaged version of the Python script using PyInstaller,
|
||||||
@ -62,8 +58,8 @@ Latest Linux products are OK and do not show this problem.
|
|||||||
| IMPORTANT: |
|
| IMPORTANT: |
|
||||||
| ========== |
|
| ========== |
|
||||||
| |
|
| |
|
||||||
| If you create a new VM using version 11, 12 or 13 hardware VMware may stop |
|
| If you create a new VM VMware may stop and create a core dump. |
|
||||||
| and create a core dump. There are two options to work around this issue: |
|
| There are two options to work around this issue: |
|
||||||
| |
|
| |
|
||||||
| 1. Change the VM to be HW 10 - this does not affect performance. |
|
| 1. Change the VM to be HW 10 - this does not affect performance. |
|
||||||
| 2. Edit the VMX file and add: |
|
| 2. Edit the VMX file and add: |
|
||||||
@ -90,24 +86,8 @@ by running chmod +x against the 2 files.
|
|||||||
lnx-install.sh - patches VMware
|
lnx-install.sh - patches VMware
|
||||||
lnx-uninstall.sh - restores VMware
|
lnx-uninstall.sh - restores VMware
|
||||||
lnx-update-tools.cmd - retrieves latest macOS guest tools
|
lnx-update-tools.cmd - retrieves latest macOS guest tools
|
||||||
|
|
||||||
6. macOS
|
|
||||||
--------
|
|
||||||
On macOS you will need to be either root or use sudo to run the scripts.
|
|
||||||
This is really only needed if you want to use client versions of macOS.
|
|
||||||
|
|
||||||
You may need to ensure the macOS scripts have execute permissions
|
|
||||||
by running chmod +x against the 2 files.
|
|
||||||
|
|
||||||
osx-install.sh - patches VMware
|
|
||||||
osx-uninstall.sh - restores VMware
|
|
||||||
|
|
||||||
7. ESXi
|
|
||||||
-------
|
|
||||||
ESXi is no longer supported as there are too many errors on newer versions due to
|
|
||||||
VMware hardening the ESXi image.
|
|
||||||
|
|
||||||
8. Thanks
|
7. Thanks
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Thanks to Zenith432 for originally building the C++ unlocker and Mac Son of Knife
|
Thanks to Zenith432 for originally building the C++ unlocker and Mac Son of Knife
|
||||||
@ -120,10 +100,7 @@ modified the unlocker code to run on Python 3 in the ESXi 6.5 environment.
|
|||||||
|
|
||||||
History
|
History
|
||||||
-------
|
-------
|
||||||
10/10/17 2.1.0 - New version to support ESXi 6.5, Workstation/Player 14 and Fusion 10
|
10/10/17 2.1.0 - First release
|
||||||
- Removed support for ESXi 6.0
|
|
||||||
- Added ESXi boot option to disable unlocker (nounlocker)
|
|
||||||
11/10/17 2.1.1 - Removed all support for ESXi 6.x
|
|
||||||
|
|
||||||
|
|
||||||
(c) 2011-2017 Dave Parsons
|
(c) 2011-2018 Dave Parsons
|
40
unlocker.py
40
unlocker.py
@ -44,9 +44,7 @@ Offset Length Struct Type Description
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import codecs
|
import codecs
|
||||||
import os
|
import os
|
||||||
import six
|
|
||||||
import struct
|
import struct
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
if sys.version_info < (2, 7):
|
if sys.version_info < (2, 7):
|
||||||
@ -56,6 +54,7 @@ if sys.version_info < (2, 7):
|
|||||||
# 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':
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
from _winreg import *
|
from _winreg import *
|
||||||
|
|
||||||
|
|
||||||
@ -349,6 +348,7 @@ def patchvmkctl(name):
|
|||||||
print('smcPresent Patched: ' + name)
|
print('smcPresent Patched: ' + name)
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
def main():
|
def main():
|
||||||
# Work around absent Platform module on VMkernel
|
# Work around absent Platform module on VMkernel
|
||||||
if os.name == 'nt' or os.name == 'cli':
|
if os.name == 'nt' or os.name == 'cli':
|
||||||
@ -356,19 +356,11 @@ def main():
|
|||||||
else:
|
else:
|
||||||
osname = os.uname()[0].lower()
|
osname = os.uname()[0].lower()
|
||||||
|
|
||||||
vmwarebase = ''
|
# vmwarebase = ''
|
||||||
libvmkctl32 = ''
|
|
||||||
libvmkctl64 = ''
|
|
||||||
vmx_so = False
|
vmx_so = False
|
||||||
|
|
||||||
# Setup default paths
|
# Setup default paths
|
||||||
if osname == 'darwin':
|
if osname == 'linux':
|
||||||
vmx_path = '/Applications/VMware Fusion.app/Contents/Library/'
|
|
||||||
vmx = joinpath(vmx_path, 'vmware-vmx')
|
|
||||||
vmx_debug = joinpath(vmx_path, 'vmware-vmx-debug')
|
|
||||||
vmx_stats = joinpath(vmx_path, 'vmware-vmx-stats')
|
|
||||||
|
|
||||||
elif osname == 'linux':
|
|
||||||
vmx_path = '/usr/lib/vmware/bin/'
|
vmx_path = '/usr/lib/vmware/bin/'
|
||||||
vmx = joinpath(vmx_path, 'vmware-vmx')
|
vmx = joinpath(vmx_path, 'vmware-vmx')
|
||||||
vmx_debug = joinpath(vmx_path, 'vmware-vmx-debug')
|
vmx_debug = joinpath(vmx_path, 'vmware-vmx-debug')
|
||||||
@ -379,15 +371,6 @@ def main():
|
|||||||
else:
|
else:
|
||||||
vmwarebase = '/usr/lib/vmware/lib/libvmwarebase.so.0/libvmwarebase.so.0'
|
vmwarebase = '/usr/lib/vmware/lib/libvmwarebase.so.0/libvmwarebase.so.0'
|
||||||
|
|
||||||
elif osname == 'vmkernel':
|
|
||||||
vmx_path = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
vmx = joinpath(vmx_path, '/unlocker/bin/vmx')
|
|
||||||
vmx_debug = joinpath(vmx_path, '/unlocker/bin/vmx-debug')
|
|
||||||
vmx_stats = joinpath(vmx_path, '/unlocker/bin/vmx-stats')
|
|
||||||
vmx_so = True
|
|
||||||
libvmkctl32 = joinpath(vmx_path, '/unlocker/lib/libvmkctl.so')
|
|
||||||
libvmkctl64 = joinpath(vmx_path, '/unlocker/lib64/libvmkctl.so')
|
|
||||||
|
|
||||||
elif osname == 'windows':
|
elif osname == 'windows':
|
||||||
reg = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
|
reg = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
|
||||||
key = OpenKey(reg, r'SOFTWARE\Wow6432Node\VMware, Inc.\VMware Workstation')
|
key = OpenKey(reg, r'SOFTWARE\Wow6432Node\VMware, Inc.\VMware Workstation')
|
||||||
@ -409,20 +392,7 @@ def main():
|
|||||||
patchsmc(vmx_stats, vmx_so)
|
patchsmc(vmx_stats, vmx_so)
|
||||||
|
|
||||||
# Patch vmwarebase for Workstation and Player
|
# Patch vmwarebase for Workstation and Player
|
||||||
# Not required on Fusion or ESXi as table already has correct flags
|
patchbase(vmwarebase)
|
||||||
if vmwarebase != '':
|
|
||||||
patchbase(vmwarebase)
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Patch libvmkctl to return Apple SMC present
|
|
||||||
if osname == 'vmkernel':
|
|
||||||
# Patch ESXi 6.0 and 6.5 32 bit .so
|
|
||||||
patchvmkctl(libvmkctl32)
|
|
||||||
|
|
||||||
# Patch ESXi 6.5 64 bit .so
|
|
||||||
if os.path.isfile(libvmkctl64):
|
|
||||||
patchvmkctl(libvmkctl64)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
Loading…
x
Reference in New Issue
Block a user