Skip to content

Instantly share code, notes, and snippets.

@santaklouse
Last active May 30, 2025 11:23
Show Gist options
  • Save santaklouse/a137ee51692b74d4cf2cc1bb68ed64ef to your computer and use it in GitHub Desktop.
Save santaklouse/a137ee51692b74d4cf2cc1bb68ed64ef to your computer and use it in GitHub Desktop.
unlimited CrossOver trial (MacOS)

Run it in console for permanent install :

bash -c "$(curl -fsSL https://gist.github.com/santaklouse/a137ee51692b74d4cf2cc1bb68ed64ef/raw/install.sh?token=$(date +%s))"

After install script will fix crossover as well as expired bottles (Thanks to @djsmax).

#!/usr/bin/env bash
# checck if pidof exists
PIDOF="$(which pidof)"
# and if not - install it
(test "${PIDOF}" && test -f "${PIDOF}") || brew install pidof
# find app in default paths
CO_PWD=~/Applications/CrossOver.app/Contents/MacOS
test -d "${CO_PWD}" || CO_PWD=/Applications/CrossOver.app/Contents/MacOS
test -d "${CO_PWD}" || (echo 'unable to detect app path. exiting...' && exit)
PWD="${CO_PWD}"
cd "${PWD}"
PROC_NAME='CrossOver'
# get all pids of CrossOver
pids=(`pgrep "${PROC_NAME}"`, `pidof "${PROC_NAME}"`, `ps -Ac | grep -m1 "${PROC_NAME}" | awk '{print $1}'`)
pids=`echo ${pids[*]}|tr ',' ' '`
# kills CrossOver process if it is running
[ "${pids}" ] && kill -9 `echo "${pids}"` > /dev/null 2>&1
# wait until app finish
sleep 3
# make the current date RFC3339-encoded string representation in UTC time zone
DATETIME=`date -u -v -3H '+%Y-%m-%dT%TZ'`
# modify time in order to reset trial
plutil -replace FirstRunDate -date "${DATETIME}" ~/Library/Preferences/com.codeweavers.CrossOver.plist
plutil -replace SULastCheckTime -date "${DATETIME}" ~/Library/Preferences/com.codeweavers.CrossOver.plist
# show tooltip notification
/usr/bin/osascript -e "display notification \"trial fixed: date changed to ${DATETIME}\""
# reset all bottles
for file in ~/Library/Application\ Support/CrossOver/Bottles/*/.{eval,update-timestamp}; do rm -rf "${file}";done
# and after this execute original crossover
echo "${PWD}" > /tmp/co_log.log
"$($PWD/CrossOver.origin)" >> /tmp/co_log.log
#!/usr/bin/env bash
# find app in default paths
CO_PWD=~/Applications/CrossOver.app/Contents/MacOS
test -d "${CO_PWD}" || CO_PWD=/Applications/CrossOver.app/Contents/MacOS
test -d "${CO_PWD}" || (echo 'unable to detect app path. exiting...' && exit)
PWD="${CO_PWD}"
cd "${PWD}"
PROC_NAME='CrossOver'
# get all pids of CrossOver
pids=(`pgrep "${PROC_NAME}"`, `pidof "${PROC_NAME}"`, `ps -Ac | grep -m1 "${PROC_NAME}" | awk '{print $1}'`)
pids=`echo ${pids[*]}|tr ',' ' '`
# kills CrossOver process if it is running
[ "${pids}" ] && kill -9 `echo "${pids}"` > /dev/null 2>&1
TIMESTAMP=$(date +%s)
FIX_FILE_LINK="https://gist.github.com/santaklouse/a137ee51692b74d4cf2cc1bb68ed64ef/raw/CrossOver.sh?token=${TIMESTAMP}"
if [ -f CrossOver.origin ]; then
echo 'already installed. update and exit.'
echo "$(curl -fsSL ${FIX_FILE_LINK})" > CrossOver
exit
fi;
test -f CrossOver.origin || mv CrossOver CrossOver.origin
echo "$(curl -fsSL ${FIX_FILE_LINK})" > CrossOver
chmod +x CrossOver
echo 'Done. Please open CrossOver '
#!/usr/bin/env bash
# find app in default paths
CO_PWD=~/Applications/CrossOver.app/Contents/MacOS
test -d "${CO_PWD}" || CO_PWD=/Applications/CrossOver.app/Contents/MacOS
test -d "${CO_PWD}" || (echo 'unable to detect app path. exiting...' && exit)
PWD="${CO_PWD}"
cd "${PWD}"
PROC_NAME='CrossOver'
# get all pids of CrossOver
pids=(`pgrep "${PROC_NAME}"`, `pidof "${PROC_NAME}"`, `ps -Ac | grep -m1 "${PROC_NAME}" | awk '{print $1}'`)
pids=`echo ${pids[*]}|tr ',' ' '`
# kills CrossOver process if it is running
[ "${pids}" ] && kill -9 `echo "${pids}"` > /dev/null 2>&1
if [ -f CrossOver.origin ]; then
echo 'original file found. Roll it back and exit.'
mv CrossOver.origin CrossOver
exit
fi;
echo 'original file not found.'
@EpicLPer
Copy link

@hackthegame101 Can confirm this works, tho editing the script to just automatically go through all Bottles and remove the lines in the registry automatically might be nice.

@Nygosaki
Copy link

If someone could try this out on their device, I'd appreciate it

@aSushiLegend
Copy link

@aSushiLegend the reason why it works for you, I think, is because Santaklouse's script generated a "backup" crossover.app file, which this script restored. I assume you ran his script before whatever update patched resetting our resetting the trial method, and your crossover got rolled back to that version. I'd be really happy if you proved me wrong, as I've explored all of crossover's directories looking for where it could be taking its initial run date from, and found absolutely nothing. Not even full uninstalls, whether that's codewaver's uninstall script or a uninstall utility app have worked. The only thing remaining is to actually just reverse engineer the app. If your .app is truly still vulnerable, could you upload it here?

Yh unless they dropped an update within the last 3 weeks I don't know but it works so long as I run the script in terminal and then run Crossover and the close crossover and run the uninstall script.

@supahfox
Copy link

supahfox commented May 14, 2025

If someone could try this out on their device, I'd appreciate it

Works fine for me (25.0)

@aSushiLegend
Copy link

My old Crossover method broke and I tried the new one and it works fine for me

@xVc323
Copy link

xVc323 commented May 23, 2025

Script here — resets trial, bottle reset included (experimental).

@Nygosaki
Copy link

@xVc323 I was snooping with wireshark for a while and crossover still doesn't validate trials with their servers. IMO it's overkill and doesen't treat the actual issues causing things to fail, trying to treat the symptoms instead with a wide spray, but as long as it helps someone I'm glad.
The actual reason why it stopped working I wrote about in an earlier comment here

@romthebom7
Copy link

how does it work when i paste it into terminal but it doesn't work nothing happens

@xVc323
Copy link

xVc323 commented May 27, 2025

@Nygosaki You’re absolutely right. I set up a testing environment and didn’t find any obvious network traffic to CodeWeavers that looked related to trial validation. That said, I’m no expert in network analysis so I can’t be 100% certain. The traffic I did see seemed to be tied to things like TIE files and software downloads. I'll simplify my script accordingly.

@UrkiMimi
Copy link

UrkiMimi commented May 28, 2025

If anyone needs it, I'll drop the Python script I made in like 5 minutes that I've been using for little over a month.
All this does is set the FirstRunDate to the current time. This doesn't fix effected bottles.

import plistlib
import os
from datetime import datetime

# set os path
userPath = os.path.expanduser('~')

# open plist
with open(f'{userPath}/Library/Preferences/com.codeweavers.CrossOver.plist', 'rb') as f:
    pl = plistlib.load(f)


# set first run date to correct time
pl['FirstRunDate'] = datetime.utcnow()

# save plist
with open(f'{userPath}/Library/Preferences/com.codeweavers.CrossOver.plist', 'wb') as f:
    plistlib.dump(pl, f)

@proffsmoke
Copy link

If anyone needs it, I'll drop the Python script I made in like 5 minutes that I've been using for little over a month. All this does is set the FirstRunDate to the current time. This doesn't fix effected bottles.

import plistlib
import os
from datetime import datetime

# set os path
userPath = os.path.expanduser('~')

# open plist
with open(f'{userPath}/Library/Preferences/com.codeweavers.CrossOver.plist', 'rb') as f:
    pl = plistlib.load(f)


# set first run date to correct time
pl['FirstRunDate'] = datetime.utcnow()

# save plist
with open(f'{userPath}/Library/Preferences/com.codeweavers.CrossOver.plist', 'wb') as f:
    plistlib.dump(pl, f)

works for me, very thx

@romthebom7
Copy link

If anyone needs it, I'll drop the Python script I made in like 5 minutes that I've been using for little over a month. All this does is set the FirstRunDate to the current time. This doesn't fix effected bottles.

import plistlib
import os
from datetime import datetime

# set os path
userPath = os.path.expanduser('~')

# open plist
with open(f'{userPath}/Library/Preferences/com.codeweavers.CrossOver.plist', 'rb') as f:
    pl = plistlib.load(f)


# set first run date to correct time
pl['FirstRunDate'] = datetime.utcnow()

# save plist
with open(f'{userPath}/Library/Preferences/com.codeweavers.CrossOver.plist', 'wb') as f:
    plistlib.dump(pl, f)

Where exactly would I use this code? I’m kinda dumb around software stuff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment