unlocker 2.0.5

This commit is contained in:
Dave Parsons 2015-06-16 12:45:15 +01:00
parent aecbe827a9
commit 89587dfa12
16 changed files with 120 additions and 198 deletions

6
.gitignore vendored
View File

@ -1,2 +1,6 @@
backup/
.idea/
.idea/
unlocker/build
unlocker/dist
dumpsmc/build
dumpsmc/dist

134
README.md
View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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')

Binary file not shown.

Binary file not shown.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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