-
-
Save BluBb-mADe/f5faa900639fd0f94ab5f0886a41bafb to your computer and use it in GitHub Desktop.
import os | |
import sys | |
import time | |
import subprocess | |
import traceback | |
from pymem import Pymem, process, exception | |
############################################################################################# | |
# This is an in-memory patch that launches and patches Voicemeeter Potato in memory on startup. | |
# It will not actually properly activate Voicemeeter but by supressing the activation popup after the trial period expires | |
# it behaves as if it has been activated for all intents and purposes. | |
# | |
# The most recent versions of Voicemeeter Potato validate their own binary integrity by checking the digital file signature | |
# so it is no longer possible to simply apply the patch to the binary itself and I couldn't be bothered to figure out how to bypass the signature check. | |
# This patch was developed for version 3.0.2.8 but it should work for newer versions as long as no major changes are made to the activation popup. | |
# | |
# For this to work as an autorun you can create a Task Scheduler Task with high privileges that launches this python script on logon. | |
# You have to pass the full exe path and file name of the Voicemeeter exe you want to patch as the only argument. | |
# The script will launch Voicemeeter and then immediately patch its memory. | |
############################################################################################# | |
patches = [ | |
("voicemeeter8x64.exe", b"\xb9\x2c\x01\x00\x00", b"\xb9\x00\x00"), | |
("voicemeeter8.exe", b"\x3d\x2c\x01\x00\x00", b"\x3d\x00\x00\x00\x00\x7e\x0a\xb8\x00\x00"), | |
] | |
def main(voicemeeter_exe_path): | |
# Select the correct patch based on the executable name | |
selected_patch = next((sig, patch) for handle, sig, patch in patches if handle.lower() in voicemeeter_exe_path.lower()) | |
# Launch Voicemeeter with idle priority | |
proc = subprocess.Popen([voicemeeter_exe_path], cwd=os.path.dirname(voicemeeter_exe_path)) | |
pid = proc.pid | |
if not selected_patch: | |
print("- No patch found for the given executable.") | |
return | |
sig, patch = selected_patch | |
try: | |
pm = Pymem(pid) | |
except exception.ProcessNotFound: | |
print("- Process not found, even though it should have been launched.") | |
return | |
print(f"+ Found Voicemeeter with PID {pm.process_id}") | |
for i in range(10): | |
module = process.module_from_name(pm.process_handle, os.path.basename(voicemeeter_exe_path)) | |
if module is not None: | |
break | |
time.sleep(.1) | |
else: | |
print(f"- Could not resolve main module") | |
print("* Aborting...") | |
return | |
address = pm.pattern_scan_module(sig, module) | |
if address is None: | |
print(f"- Couldn't find signature 0x{sig.hex()}") | |
print("* Aborting...") | |
return | |
print(f"+ Found signature at address 0x{address:02x}") | |
pm.write_bytes(address, patch, len(patch)) | |
print(f"+ Voicemeeter successfully patched") | |
if __name__ == '__main__': | |
try: | |
if len(sys.argv) > 1: | |
main(' '.join(sys.argv[1:])) | |
else: | |
print(f"Usage: python {os.path.basename(__file__)} <path/to/voicemeeter8[x64].exe>") | |
except Exception: | |
traceback.print_exc() | |
input() |
I never needed this on my system but I assume on some systems there is a delay until the process is launched far enough for module_from_name to work so I guess adding this doesn't hurt. But maybe a loop like this is a bit dangerous. Who knows why it might keep failing and lock up the script in a spinning loop.
Thanks for the answer. I installed all dependencies.
I can't manage to pass the path as argument.
I always get this :
_Traceback (most recent call last):
File "C:\Users\Me\Documents\Voicemeeter\potato_patcher.py", line 91, in <module>
main(' '.join(sys.argv[1:]))
File "C:\Users\Me\Documents\Voicemeeter\potato_patcher.py", line 37, in main
selected_patch = next((sig, patch) for handle, sig, patch in patches if handle.lower() in voicemeeter_exe_path.lower())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
StopIteration
Typing in my cmd python "C:\Users\Me\Documents\Voicemeeter\potato_patcher.py"
the program returns
Usage: python patch_potato.py <Voicemeeter_exe_path>
so I know I can at least launch the script.
After that, I tried :
python "C:\Users\Me\Documents\Voicemeeter\potato_patcher.py" "C:\Program Files (x86)\VB\Voicemeeter"
python "C:\Users\Me\Documents\Voicemeeter\potato_patcher.py" "C:\Program Files (x86)\VB\Voicemeeter\"
python "C:\Users\Me\Documents\Voicemeeter\potato_patcher.py" "C:\\Program Files (x86)\\VB\\Voicemeeter\\"
python "C:\Users\Me\Documents\Voicemeeter\potato_patcher.py" "C:/Program Files (x86)/VB/Voicemeeter"
python "C:\Users\Me\Documents\Voicemeeter\potato_patcher.py" "C:/Program Files (x86)/VB/Voicemeeter/"
You need to include the exe file name as well. The patcher doesn't know if you want to use the 32 or the 64 bit version of voicemeeter.
python "C:\Users\Me\Documents\Voicemeeter\potato_patcher.py" C:\Program Files (x86)\VB\Voicemeeter\voicemeeter8x64.exe
should work.
You need to include the exe file name as well. The patcher doesn't know if you want to use the 32 or the 64 bit version of voicemeeter.
python "C:\Users\Me\Documents\Voicemeeter\potato_patcher.py" C:\Program Files (x86)\VB\Voicemeeter\voicemeeter8x64.exe
should work.
THANK YOU SO MUCH
Hopefully this conversation will help many users from Google search in the future.
After a few tweaks it worked :
- My cpu stays at 30% load for 30 seconds after logon, so I increased the threshold from 5 to 50, otherwise Voicemeeter would launch before the patch is done.
- I wrote the command "python [...]" in a .bat and ran the .bat from the Task Scheduler.
- Task scheduler action is "%userprofile%\rest of the path\potato.bat" (quotes included), nothing in "Start in" nor "Argument".
I did %userprofile% instead of C:\Users\Me because my actual name has diacritics in it and the directory couldn't be found.
Thank you again and good luck for your future projects !
Hey @BluBb-mADe any chance you're planning on exploring the new VAIO Extensions as well?
No I haven't but as far as I can tell this is only for standard and banana and doesn't even support potato and you get the same number of devices in potato by default anyway.
It's actually for all versions of Voicemeeter, and with it you get additional ins/outs
I used this and another activator for a while, but decided to permanently activate Voicemeeter. So I wrote a keygen for Voicemeeter Potato and the VAIO extensions.
It is available here if you're interested: https://atroquinine.github.io/voicemeeter
A reference implementation of the key generation is available here (it is very simple) https://github.com/atroquinine/voicemeeter-keygen
(pinging @j3yps because you seemed interested in a VAIO extension activator)
I used this and another activator for a while, but decided to permanently activate Voicemeeter. So I wrote a keygen for Voicemeeter Potato and the VAIO extensions.
It is available here if you're interested: https://atroquinine.github.io/voicemeeter A reference implementation of the key generation is available here (it is very simple) https://github.com/atroquinine/voicemeeter-keygen
(pinging @j3yps because you seemed interested in a VAIO extension activator)
Awesome, i'll check it out!
Awesome! This is obviously a much better solution. Go use that instead!
L it got DMCA'd
@atroquinine
repo got remove, any plans to repost?
You can still use it on web archive as it was a client-only javascript library and there is a working snapshot before the takedown.
archive can be found here
Solution for this error.
AttributeError: 'NoneType' object has no attribute 'lpBaseOfDll'
Replace the code on line 51 with the following