Skip to content

Instantly share code, notes, and snippets.

@BluBb-mADe
Last active September 24, 2024 06:04
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()
@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.

@geringverdien
Copy link

archive can be found here

@ylyxa
Copy link

ylyxa commented Aug 5, 2024

Just FYI @atroquinine the keygen doesn't work for the latest version of VM.

@huoyan1231
Copy link

仅供参考@atroquinine该密钥生成器不适用于最新版本的 VM。

use 3.1.1.1 version

@laincey
Copy link

laincey commented Aug 11, 2024

@geringverdien thanks bro

@ylyxa
Copy link

ylyxa commented Aug 11, 2024

Also FYI you can't download the 3.1.1.1 .exe from VM's website anymore.

The latest version I could find was 3.0.2.8

@laincey
Copy link

laincey commented Aug 12, 2024

Also FYI you can't download the 3.1.1.1 .exe from VM's website anymore.

The latest version I could find was 3.0.2.8

i alr got 3.1.1.1 all g

@craeckor
Copy link

Also FYI you can't download the 3.1.1.1 .exe from VM's website anymore.

The latest version I could find was 3.0.2.8

I created a clone of the original keygen site and added version 3.1.1.1.
https://vmac.craeckor.ch/

@MayhemBill
Copy link

Also FYI you can't download the 3.1.1.1 .exe from VM's website anymore.
The latest version I could find was 3.0.2.8

I created a clone of the original keygen site and added version 3.1.1.1. https://vmac.craeckor.ch/

is it possible to get the source for this?

@okejadi
Copy link

okejadi commented Aug 25, 2024

thanks @craeckor !

@okejadi
Copy link

okejadi commented Aug 25, 2024

Also FYI you can't download the 3.1.1.1 .exe from VM's website anymore.
The latest version I could find was 3.0.2.8

I created a clone of the original keygen site and added version 3.1.1.1. https://vmac.craeckor.ch/

is it possible to get the source for this?

You can just inspect element the website and copy it, as it was only a client-side script

@craeckor
Copy link

Also FYI you can't download the 3.1.1.1 .exe from VM's website anymore.
The latest version I could find was 3.0.2.8

I created a clone of the original keygen site and added version 3.1.1.1. https://vmac.craeckor.ch/

is it possible to get the source for this?

You can just inspect element the website and copy it, as it was only a client-side script

That's what i did

@electricsteve
Copy link

Anyone know if you can just patch the exe with x64dbg? I can't really because it tries to run in dos mode and it can't.

@craeckor
Copy link

Anyone know if you can just patch the exe with x64dbg? I can't really because it tries to run in dos mode and it can't.

Doesn't work, they added signature check, it just wont start if you patch the exe.

@electricsteve
Copy link

electricsteve commented Aug 25, 2024

Anyone know if you can just patch the exe with x64dbg? I can't really because it tries to run in dos mode and it can't.

Doesn't work, they added signature check, it just wont start if you patch the exe.

And the signature check also can't be stopped?

@craeckor
Copy link

Anyone know if you can just patch the exe with x64dbg? I can't really because it tries to run in dos mode and it can't.

Doesn't work, they added signature check, it just wont start if you patch the exe.

And the signature check also can't be stopped?

I heard there are some ways but no idea if they even work cause the signature check runs before the debugger injects itself into the exe

@BluBb-mADe
Copy link
Author

You should be able to patch it in x64dbg as the signature is only about the file on disk and doesn't include in-memory modifications.
If you want to take the time to figure out what to patch in the latest version, assuming my script doesn't work anymore, you should be able to write a new small script, maybe using mine as a template and adding the necessary places to patch in the latest version and use that instead.
But you can not easily save these changes into the binary on disk without also bypassing the signature check which would be quite a bit more work. I am not entirely sure but it seemed to me like the signature check is part of the binary as well so maybe you can just bypass that the same way as well.
But if you don't know all these things already you are probably ill-equipped to pull this kind of patch off because that requires some experience and general understanding of how these things work. It's not something you can just do over a weekend without prior experience.

@atroquinine
Copy link

atroquinine commented Sep 22, 2024

Just FYI @atroquinine the keygen doesn't work for the latest version of VM.

Here's how Voicemeeter previously generated response codes:

  • state = prepare(username, computer_name, ...product_info);
  • challenge_code = digest_challenge_code(state);
  • response_code = md5(keygen(email, product_id, challenge_code)).

The new key generation algorithm is very obfuscated and is essentially a black box to me. My interpretation of the process is like so:

  • blackbox_state = prepare_bb(username, computer_name, ...product_info);
  • challenge_code = digest_challenge_code(blackbox_state);
  • response_code = keygen_bb(email, product_id, blackbox_state).

The problem is that from just the challenge code, it is very difficult to get the corresponding blackbox state without knowing how the entire blackbox works. It is possible, just difficult, given that the Voicemeeter shop requires only the challenge code, not your user name and computer name.

Considering the difficulty in reversing the blackbox, my approach to a simple keygen would be like so:

  • ask the user for the required information to create the blackbox state;
  • launch Voicemeeter in a suspended state and call the prepare_bb function with CreateRemoteThread;
  • digest the challenge code and show it to the user, so they can confirm it is the same as the one shown in Voicemeeter;
  • call keygen_bb with CreateRemoteThread;
  • now you have the key for the corresponding challenge code.

This approach is very fragile and would break in a version update, because it depends on specific offsets for functions in the file. To prevent that, I could extract the functions from a known version and place it in the keygen, but I would not be able to distribute the code here without risking another DMCA. Where's the fun in that?

With all of that said, I don't think I'll write another keygen for Voicemeeter.


PS: If you just want to activate your own Voicemeeter without patching it, it's simple. Shutdown Voicemeeter and open it through a debugger. Breakpoint where the response code comparison happens and read the expected code (RVA 0x94703 on voicemeeter8x64.exe 3.1.1.3, expected response code in RAX).

If you're using Voicemeeter Potato, the breakpoint will be hit twice. The first one is for removing the nagging popups and the second is the VAIO extension. Make sure you have an email set in each activation window before attempting this.

@Masterload1975
Copy link

PS: If you just want to activate your own Voicemeeter without patching it, it's simple. Shutdown Voicemeeter and open it through a debugger. Breakpoint where the response code comparison happens and read the expected code (RVA 0x94703 on voicemeeter8x64.exe 3.1.1.3, expected response code in RAX).

If you're using Voicemeeter Potato, the breakpoint will be hit twice. The first one is for removing the nagging popups and the second is the VAIO extension. Make sure you have an email set in each activation window before attempting this.

How to find this with x64dbg?

@atroquinine
Copy link

@Masterload1975 I already gave you the cake, you just need to learn to use the knife.

Do a bit of searching and fussing around; it'll do you good to learn debugging skills.

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