unlocker 2.0.5
This commit is contained in:
parent
aecbe827a9
commit
89587dfa12
|
@ -1,2 +1,6 @@
|
|||
backup/
|
||||
.idea/
|
||||
.idea/
|
||||
unlocker/build
|
||||
unlocker/dist
|
||||
dumpsmc/build
|
||||
dumpsmc/dist
|
134
README.md
134
README.md
|
@ -1,134 +0,0 @@
|
|||
|
||||
Mac OS X Unlocker for VMware V2.0
|
||||
=================================
|
||||
|
||||
1. Introduction
|
||||
---------------
|
||||
|
||||
Unlocker 2 is designed for Workstation 11, Player 7 and Fusion 7.
|
||||
|
||||
If you are using an earlier product please continue using Unlocker 1
|
||||
|
||||
Version 2 has been tested against:
|
||||
|
||||
* Workstation 11 on Windows and Linux
|
||||
* Player 7 on Windows and Linux
|
||||
* Fusion 7 on Mavericks and Yosemite
|
||||
* (Currently is does not work on ESXi 6.0)
|
||||
|
||||
The patch code carries out the following modifications dependent on the product
|
||||
being patched:
|
||||
|
||||
* Fix vmware-vmx and derivatives to allow Mac OS X to boot
|
||||
* Fix vmwarebase .dll or .so to allow Apple to be selected during VM creation
|
||||
* A copy of the latest VMware Tools for OS X is included
|
||||
|
||||
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 and Player.
|
||||
|
||||
The vmwarebase code does not need to be patched on OS X 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
|
||||
been shutdown.
|
||||
|
||||
The code is now Python as it makes the Unlocker easier to run and maintain on ESXi.
|
||||
There are some challenges to write the code as ESXi has a subset of Python 2.7 which
|
||||
constrains some modules that can be used.
|
||||
|
||||
2. Prerequisites
|
||||
----------------
|
||||
|
||||
The code requires Python 2.7 to work. Most Linux distros and OS X ship with a compatible
|
||||
Python interpreter and should work without requiring any additional software.
|
||||
|
||||
Windows has a packaged version of the Python script using PyInstaller, and so does not
|
||||
require Python to be installed.
|
||||
|
||||
3. Limitations
|
||||
--------------
|
||||
|
||||
The Unlocker currently does not work on ESXi 6.
|
||||
|
||||
Work continues to find solutions to the limitations.
|
||||
|
||||
4. Windows
|
||||
----------
|
||||
On Windows you will need to either run cmd.exe as Administrator or using
|
||||
Explorer right click on the command file and select "Run as administrator".
|
||||
|
||||
win-install.cmd - patches VMware
|
||||
win-uninstall.cmd - restores VMware
|
||||
|
||||
5. Linux
|
||||
---------
|
||||
On Linux you will need to be either root or use sudo to run the scripts.
|
||||
|
||||
You may need to ensure the Linux scripts have execute permissions
|
||||
by running chmod +x against the 2 files.
|
||||
|
||||
lnx-install.sh - patches VMware
|
||||
lnx-uninstall.sh - restores VMware
|
||||
|
||||
6. Mac OS X
|
||||
-----------
|
||||
On Mac OS X 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 Mac OS X.
|
||||
|
||||
You may need to ensure the OS X scripts have execute permissions
|
||||
by running chmod +x against the 2 files.
|
||||
|
||||
osx-install.sh - patches VMware
|
||||
osx-uninstall.sh - restores VMware
|
||||
|
||||
|
||||
7. Notes
|
||||
--------
|
||||
|
||||
+-----------------------------------------------------------------------------+
|
||||
| IMPORTANT: |
|
||||
| ========== |
|
||||
| |
|
||||
| If you create a new VM using version 11 hardware VMware will stop and |
|
||||
| create a core dump.There are two options to work around this issue: |
|
||||
| |
|
||||
| 1. Change the VM to be HW 10 - this does not affect performance. |
|
||||
| 2. Edit the VMX file and add: |
|
||||
| smc.version = "0" |
|
||||
| |
|
||||
+-----------------------------------------------------------------------------+
|
||||
|
||||
To remove the check for server versions for OS X Leopard and Snow Leopard
|
||||
(10.5 and 10.6) you must use a replacement EFI firwmare module from the firmware
|
||||
folder.
|
||||
|
||||
If you are using a 32-bit installation of OS X:
|
||||
|
||||
1. Copy efi32-srvr.rom to guest folder.
|
||||
2. Edit the vmx file and add:
|
||||
efi32.filename = "efi32-srvr.rom"
|
||||
|
||||
If you are using a 64-bit installation of OS X:
|
||||
|
||||
1. Copy efi64-srvr.rom to guest folder.
|
||||
2. Edit the vmx file and add:
|
||||
efi64.filename = "efi64-srvr.rom"
|
||||
|
||||
8. Thanks
|
||||
---------
|
||||
|
||||
Thanks to Zenith432 for originally building the C++ unlocker and Mac Son of Knife
|
||||
(MSoK) for all the testing and support.
|
||||
|
||||
|
||||
History
|
||||
-------
|
||||
12/12/14 2.0.0 - First release
|
||||
13/13/14 2.0.1 - Removed need for Python for Windows
|
||||
13/13/14 2.0.2 - darwin.iso was missing from zip file
|
||||
02/01/15 2.0.3 - Added EFI firmware files to remove Server check
|
||||
- Refactored Python code
|
||||
07/01/15 2.0.4 - Added View USB Service to Windows batch files
|
||||
- Fixed broken GOS Table patching on Linux
|
||||
|
||||
(c) 2011-2015 Dave Parsons
|
|
@ -1,12 +1,12 @@
|
|||
#!/usr/bin/python
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
osnames = ['darwin', 'linux', 'vmkernel', 'windows']
|
||||
parser.add_argument('-v', '--vmx', help='vmx file', dest='vmx', action='store', type=argparse.FileType('r+b'))
|
||||
parser.add_argument('-d', '--vmx-debug', help='vmx-debug file', dest='vmx_debug', action='store', type=argparse.FileType('r+b'))
|
||||
parser.add_argument('-s', '--vmx-stats', help='vmx-stats file', dest='vmx_stats', action='store', type=argparse.FileType('r+b'))
|
||||
parser.add_argument('-b', '--vmbase', help='vmwarebase file', dest='vmwarebase', action='store', type=argparse.FileType('r+b'))
|
||||
|
||||
parser.add_argument('-o', '--osname', help='OS type', dest='osname', action='store', choices=osnames )
|
||||
args = parser.parse_args()
|
||||
|
||||
parser.print_help()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo VMware Unlocker 2.0.4
|
||||
echo VMware Unlocker 2.0.5
|
||||
echo ===============================
|
||||
echo Copyright: Dave Parsons 2011-15
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo VMware Unlocker 2.0.4
|
||||
echo VMware Unlocker 2.0.5
|
||||
echo ===============================
|
||||
echo Copyright: Dave Parsons 2011-15
|
||||
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
set -e
|
||||
set -x
|
||||
|
||||
echo VMware ESXi 5.x Unlocker 1.3.1
|
||||
echo VMware ESXi 6.x Unlocker 2.0.5
|
||||
echo ===============================
|
||||
echo Copyright: Dave Parsons 2011-14
|
||||
echo Copyright: Dave Parsons 2011-15
|
||||
|
||||
# Ensure we only use unmodified commands
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo VMware Unlocker 2.0.4
|
||||
echo VMware Unlocker 2.0.5
|
||||
echo ===============================
|
||||
echo Copyright: Dave Parsons 2011-15
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo VMware Unlocker 2.0.4
|
||||
echo VMware Unlocker 2.0.5
|
||||
echo ===============================
|
||||
echo Copyright: Dave Parsons 2011-15
|
||||
|
||||
|
|
42
readme.txt
42
readme.txt
|
@ -4,7 +4,7 @@ Mac OS X Unlocker for VMware V2.0
|
|||
1. Introduction
|
||||
---------------
|
||||
|
||||
Unlocker 2 is designed for Workstation 11, Player 7 and Fusion 7.
|
||||
Unlocker 2 is designed for Workstation 11, Player 7, ESXi 6 and Fusion 7.
|
||||
|
||||
If you are using an earlier product please continue using Unlocker 1
|
||||
|
||||
|
@ -13,7 +13,7 @@ Version 2 has been tested against:
|
|||
* Workstation 11 on Windows and Linux
|
||||
* Player 7 on Windows and Linux
|
||||
* Fusion 7 on Mavericks and Yosemite
|
||||
* (Currently is does not work on ESXi 6.0)
|
||||
* ESXi 6.0
|
||||
|
||||
The patch code carries out the following modifications dependent on the product
|
||||
being patched:
|
||||
|
@ -25,7 +25,7 @@ being patched:
|
|||
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 and Player.
|
||||
|
||||
The vmwarebase code does not need to be patched on OS X so you will see a
|
||||
The vmwarebase code does not need to be patched on OS X or ESXi 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
|
||||
|
@ -38,7 +38,7 @@ constrains some modules that can be used.
|
|||
2. Prerequisites
|
||||
----------------
|
||||
|
||||
The code requires Python 2.7 to work. Most Linux distros and OS X ship with a compatible
|
||||
The code requires Python 2.7 to work. Most Linux distros, ESXi and OS X ship with a compatible
|
||||
Python interpreter and should work without requiring any additional software.
|
||||
|
||||
Windows has a packaged version of the Python script using PyInstaller, and so does not
|
||||
|
@ -47,9 +47,7 @@ require Python to be installed.
|
|||
3. Limitations
|
||||
--------------
|
||||
|
||||
The Unlocker currently does not work on ESXi 6.
|
||||
|
||||
Work continues to find solutions to the limitations.
|
||||
No known limitations.
|
||||
|
||||
4. Windows
|
||||
----------
|
||||
|
@ -80,8 +78,31 @@ by running chmod +x against the 2 files.
|
|||
osx-install.sh - patches VMware
|
||||
osx-uninstall.sh - restores VMware
|
||||
|
||||
7. ESXi
|
||||
-------
|
||||
You will need to transfer the zip file to the ESXi host either using vSphere client or SCP.
|
||||
|
||||
7. Notes
|
||||
Once uploaded you will need to either use the ESXi support console or use SSH to
|
||||
run the commands. Use the unzip command to extract the files.
|
||||
|
||||
<<< WARNING: use a datastore volume to run the scripts >>>
|
||||
|
||||
Please note that you will need to reboot the host for the patches to become active.
|
||||
The patcher is embbedded in a shell script local.sh which is run at boot from /etc/rc.local.d.
|
||||
|
||||
You may need to ensure the ESXi scripts have execute permissions
|
||||
by running chmod +x against the 2 files.
|
||||
|
||||
esxi-install.sh - patches VMware
|
||||
esxi-uninstall.sh - restores VMware
|
||||
|
||||
Note:
|
||||
1. Any changes you have made to local.sh will be lost. If you have made changes to
|
||||
that file, you will need to merge them into the supplied local.sh file.
|
||||
2. The unlocker runs at boot time to patch the relevant files and it now survives
|
||||
an upgrade or patch to ESXi as local.sh is part of the persisted local state.
|
||||
|
||||
8. Notes
|
||||
--------
|
||||
|
||||
+-----------------------------------------------------------------------------+
|
||||
|
@ -119,6 +140,9 @@ If you are using a 64-bit installation of OS X:
|
|||
Thanks to Zenith432 for originally building the C++ unlocker and Mac Son of Knife
|
||||
(MSoK) for all the testing and support.
|
||||
|
||||
Thanks also to Sam B for finding the solution for ESXi 6 and helping me with
|
||||
debugging expertise. Sam also wrote the code for patching ESXi ELF files.
|
||||
|
||||
|
||||
History
|
||||
-------
|
||||
|
@ -129,5 +153,7 @@ History
|
|||
- Refactored Python code
|
||||
07/01/15 2.0.4 - Added View USB Service to Windows batch files
|
||||
- Fixed broken GOS Table patching on Linux
|
||||
15/06/15 2.0.5 - ESXi 6 working
|
||||
- Latest tools from Fusion 7.1.1
|
||||
|
||||
(c) 2011-2015 Dave Parsons
|
27
tests.py
27
tests.py
|
@ -1,27 +0,0 @@
|
|||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import subprocess
|
||||
import hashlib
|
||||
|
||||
print sys.path[0]
|
||||
|
||||
shutil.rmtree(sys.path[0] + '/backup', True)
|
||||
os.mkdir(sys.path[0] + '/backup')
|
||||
|
||||
hashlib.sha224("Nobody inspects the spammish repetition").hexdigest()
|
||||
|
||||
shutil.copy2('/Applications/VMware Fusion.app/Contents/Library/vmware-vmx', './backup/')
|
||||
shutil.copy2('/Applications/VMware Fusion.app/Contents/Library/vmware-vmx-debug', './backup/')
|
||||
shutil.copy2('/Applications/VMware Fusion.app/Contents/Library/vmware-vmx-stats', './backup/')
|
||||
|
||||
res = subprocess.check_output(['/Applications/VMware Fusion.app/Contents/Library/vmrun', 'list'],
|
||||
stderr=subprocess.STDOUT)
|
||||
|
||||
if res == 'Total running VMs: 0\n':
|
||||
print 'OK'
|
||||
else:
|
||||
print 'Fail'
|
||||
|
||||
if not os.geteuid() == 0:
|
||||
sys.exit('Script must be run as root')
|
BIN
tools/darwin.iso
BIN
tools/darwin.iso
Binary file not shown.
Binary file not shown.
87
unlocker.py
87
unlocker.py
|
@ -65,8 +65,9 @@ def bytetohex(bytestr):
|
|||
return ''.join(['%02X ' % ord(x) for x in bytestr]).strip()
|
||||
|
||||
|
||||
def printkey(i, smc_key, smc_data):
|
||||
def printkey(i, offset, smc_key, smc_data):
|
||||
print str(i+1).zfill(3) \
|
||||
+ ' ' + hex(offset) \
|
||||
+ ' ' + smc_key[0][::-1] \
|
||||
+ ' ' + str(smc_key[1]).zfill(2) \
|
||||
+ ' ' + smc_key[2][::-1].replace('\x00', ' ') \
|
||||
|
@ -74,10 +75,54 @@ def printkey(i, smc_key, smc_data):
|
|||
+ ' ' + hex(smc_key[4]) \
|
||||
+ ' ' + bytetohex(smc_data)
|
||||
|
||||
E_CLASS64 = 2;
|
||||
E_SHT_RELA = 4;
|
||||
|
||||
def patchkeys(f, key):
|
||||
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 = 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, vmx, key, osname):
|
||||
# Setup struct pack string
|
||||
global smc_new_memptr
|
||||
key_pack = '=4sB4sB6xQ'
|
||||
|
||||
# Do Until OSK1 read
|
||||
|
@ -97,12 +142,13 @@ def patchkeys(f, key):
|
|||
# Use the +LKS data routine for OSK0/1
|
||||
smc_new_memptr = smc_key[4]
|
||||
print '+LKS Key: '
|
||||
printkey(i, smc_key, smc_data)
|
||||
printkey(i, offset, smc_key, smc_data)
|
||||
|
||||
elif smc_key[0] == '0KSO':
|
||||
# Write new data routine pointer from +LKS
|
||||
print 'OSK0 Key Before:'
|
||||
printkey(i, smc_key, smc_data)
|
||||
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()
|
||||
|
@ -118,12 +164,13 @@ def patchkeys(f, key):
|
|||
smc_key = struct.unpack(key_pack, f.read(24))
|
||||
smc_data = f.read(smc_key[1])
|
||||
print 'OSK0 Key After:'
|
||||
printkey(i, smc_key, smc_data)
|
||||
printkey(i, offset, smc_key, smc_data)
|
||||
|
||||
elif smc_key[0] == '1KSO':
|
||||
# Write new data routine pointer from +LKS
|
||||
print 'OSK1 Key Before:'
|
||||
printkey(i, smc_key, smc_data)
|
||||
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()
|
||||
|
@ -139,7 +186,7 @@ def patchkeys(f, key):
|
|||
smc_key = struct.unpack(key_pack, f.read(24))
|
||||
smc_data = f.read(smc_key[1])
|
||||
print 'OSK1 Key After:'
|
||||
printkey(i, smc_key, smc_data)
|
||||
printkey(i, offset, smc_key, smc_data)
|
||||
|
||||
# Finished so get out of loop
|
||||
break
|
||||
|
@ -148,9 +195,9 @@ def patchkeys(f, key):
|
|||
pass
|
||||
|
||||
i += 1
|
||||
return smc_old_memptr, smc_new_memptr
|
||||
|
||||
|
||||
def patchsmc(name):
|
||||
def patchsmc(name, osname):
|
||||
with open(name, 'r+b') as f:
|
||||
|
||||
# Read file into string variable
|
||||
|
@ -188,10 +235,10 @@ def patchsmc(name):
|
|||
|
||||
if (smc_adr - smc_key0) != 72:
|
||||
print 'appleSMCTableV0 Table : ' + hex(smc_key0)
|
||||
patchkeys(f, smc_key0)
|
||||
smc_old_memptr, smc_new_memptr = patchkeys(f, vmx, smc_key0, osname)
|
||||
elif (smc_adr - smc_key1) != 72:
|
||||
print 'appleSMCTableV0 Table : ' + hex(smc_key1)
|
||||
patchkeys(f, smc_key1)
|
||||
smc_old_memptr, smc_new_memptr = patchkeys(f, vmx, smc_key1, osname)
|
||||
|
||||
print
|
||||
|
||||
|
@ -203,13 +250,19 @@ def patchsmc(name):
|
|||
|
||||
if (smc_adr - smc_key0) == 72:
|
||||
print 'appleSMCTableV1 Table : ' + hex(smc_key0)
|
||||
patchkeys(f, smc_key0)
|
||||
smc_old_memptr, smc_new_memptr = patchkeys(f, vmx, smc_key0, osname)
|
||||
elif (smc_adr - smc_key1) == 72:
|
||||
print 'appleSMCTableV1 Table : ' + hex(smc_key1)
|
||||
patchkeys(f, smc_key1)
|
||||
smc_old_memptr, smc_new_memptr = patchkeys(f, vmx, smc_key1, osname)
|
||||
|
||||
print
|
||||
|
||||
# Find matching RELA record in .rela.dyn in ESXi ELF files
|
||||
# This is temporary code until proper ELF parsing written
|
||||
if osname == 'vmkernel':
|
||||
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()
|
||||
|
@ -301,10 +354,10 @@ def main():
|
|||
return
|
||||
|
||||
# Patch the vmx executables skipping stats version for Player
|
||||
patchsmc(vmx)
|
||||
patchsmc(vmx_debug)
|
||||
patchsmc(vmx, osname)
|
||||
patchsmc(vmx_debug, osname)
|
||||
try:
|
||||
patchsmc(vmx_stats)
|
||||
patchsmc(vmx_stats, osname)
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@echo off
|
||||
setlocal ENABLEEXTENSIONS
|
||||
echo VMware Unlocker 2.0.4
|
||||
echo VMware Unlocker 2.0.5
|
||||
echo ========================
|
||||
echo (c) Dave Parsons 2011-15
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@echo off
|
||||
setlocal ENABLEEXTENSIONS
|
||||
echo VMware Unlocker 2.0.4
|
||||
echo VMware Unlocker 2.0.5
|
||||
echo ========================
|
||||
echo (c) Dave Parsons 2011-15
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@echo off
|
||||
setlocal ENABLEEXTENSIONS
|
||||
echo VMware Unlocker 2.0.4
|
||||
echo VMware Unlocker 2.0.5
|
||||
echo ========================
|
||||
echo (c) Dave Parsons 2011-15
|
||||
|
||||
|
|
Loading…
Reference in New Issue