Skip to content

Instantly share code, notes, and snippets.

@BluBb-mADe
Last active May 7, 2024 18:36
Show Gist options
  • Save BluBb-mADe/f5faa900639fd0f94ab5f0886a41bafb to your computer and use it in GitHub Desktop.
Save BluBb-mADe/f5faa900639fd0f94ab5f0886a41bafb to your computer and use it in GitHub Desktop.
Generic Voicemeeter Potato in-memory patch
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()
@j3yps
Copy link

j3yps commented Aug 4, 2023

Hi, thanks for this! I added this to my "Autostart" as per instructions. But for it to work, I have to close VM (after starting it automatically upon windows launch), open the patcher then launch VM only then will the activation prompt disappear (like its already registered). Am I missing something?

@BluBb-mADe
Copy link
Author

BluBb-mADe commented Aug 4, 2023

I am sad to tell you I struggle with the same issue. The problem is that this is entirely timing-dependent. The patch spins looking for VoiceMeeter and tries to patch it before it ever reaches the licensing check. But if, for whatever reason, it is too slow, it still succeeds in patching it but the first license check already went through so the first trial cooldown window still shows up. The same thing can happen if you use this patch normally but it's far less likely. It's basically dependent on how much CPU time the patcher process gets. You could experiment with running the patch with elevated process priority to increase the chances of the patcher being in time. It fails on Autostart more often because lots of other processes are launching at the same time eating up CPU. I haven't tried working around this myself in any way yet.
It might even help to just remove the status prints because console prints can be surprisingly slow sometimes.

@j3yps
Copy link

j3yps commented Aug 5, 2023

I see, i'll try other things. hope you get to find a workaround for it :)

@BluBb-mADe
Copy link
Author

I figured out the main problem. It's nothing to do with timing. It's permissions. Normal autoruns don't have enough permissions to modify other processes' memory.
I have worked out a solution and I also decided to handle launching voicemeeter from inside the Python script alongside the patching process.
This works basically 100% of the time now at least on my machine. But you can not use the normal autostart folder in the Windows start menu. I use the Task Scheduler instead. I created a new Task that has the "Run with highest privileges" checkbox checked and has a trigger to run at logon as well as a "Start a program" action. The action in my case launches the python executable of the venv with the first argument being the potato_patcher.py script and the second argument as the full path to the voicemeeter executable to start and patch.
This updated version also includes waiting for low CPU usage and adjusting the process priorities to ensure the patch can run in time.

@j3yps
Copy link

j3yps commented Sep 14, 2023

Awesome! I'll try it out tomorrow as I am currently not home, thanks for the update!

@j3yps
Copy link

j3yps commented Sep 15, 2023

Hi @BluBb-mADe, I tried it. but it just opens a cmd window and it closes itself right away

edit: I just needed to include the VM path in the script. it's working perfectly now on boot with a task scheduled

@tankirules
Copy link

God bless you man. The donation alerts getting longer and longer is so annoying. I could not get the task scheduler to work with launching a python program and feeding it arguments, so I instead wrote a one liner batch file, and ran that as admin through task scheduler.

It's literally just

python "C:\Users\tankirules\Desktop\potato_patcher.py" "C:\Program Files (x86)\VB\Voicemeeter\voicemeeter8x64.exe"
pause

@Whosdeez
Copy link

Doesn't do anything for me.
I made a task scheduler entry at logon, ran with highest privileges on the admin account,
Program : "C:\Users\Me\AppData\Local\Programs\Python\Python311\python.exe"
Add arguments : potato_patcher.py
Start in : C:\Users\Me\Documents\Voicemeeter\ (I put the potato_patcher script in the Voicemeeter folder)
I also momentarily replaced your script with something simple of my own which just displays "done" to make sure the way I launch it isn't at fault, and my script is correctly being executed. But yours isn't.
I'm running Voicemeeter Potato 3.0.2.8 64bit.
Any help would be appreciated, have a nice day.

@BluBb-mADe
Copy link
Author

BluBb-mADe commented Jan 17, 2024

I don't really want to give tech support but even if I wanted to you are not giving me enough information here. Have you installed the pip dependencies pymem, psutil, and pywin32? Have you tried executing the script just on a terminal without the scheduler? From your post it doesn't seem like you have actually specified the path to the voicemeeter executable as explained in the comment of this script.
There shouldn't be any need to ensure the execution path ("Start in"). Anyway, Voicemeeter is typically installed in "c:\program files (x86)\vb...". Only the config files are in the documents folder.
I really have no idea where to even begin helping you here.
I was thinking about packaging this thing in a more user-friendly way but I have too much other things to do. Right now its more a demo of how you can get rid of the potato donation window that requires a bit of extra work. Maybe someone else can do the work of packaging this into an actual tool.

@obtuse-triangle
Copy link

obtuse-triangle commented Jan 23, 2024

Solution for this error. AttributeError: 'NoneType' object has no attribute 'lpBaseOfDll'
Replace the code on line 51 with the following

            module = None
            while module is None:
                module = process.module_from_name(
                    pm.process_handle, os.path.basename(voicemeeter_exe_path)
                )

@BluBb-mADe
Copy link
Author

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.

@Whosdeez
Copy link

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/"

@BluBb-mADe
Copy link
Author

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.

@Whosdeez
Copy link

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 !

@j3yps
Copy link

j3yps commented Mar 19, 2024

Hey @BluBb-mADe any chance you're planning on exploring the new VAIO Extensions as well?

@BluBb-mADe
Copy link
Author

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.

@j3yps
Copy link

j3yps commented Mar 20, 2024

It's actually for all versions of Voicemeeter, and with it you get additional ins/outs

@atroquinine
Copy link

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)

@j3yps
Copy link

j3yps commented Mar 27, 2024

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!

@BluBb-mADe
Copy link
Author

Awesome! This is obviously a much better solution. Go use that instead!

@LYNK-INCUU
Copy link

L it got DMCA'd

@MayhemBill
Copy link

@atroquinine
repo got remove, any plans to repost?

@BluBb-mADe
Copy link
Author

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.

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