-
-
Notifications
You must be signed in to change notification settings - Fork 18.2k
discord: fix krisp module #290077
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
discord: fix krisp module #290077
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,114 @@ | ||||||||||||||||
| #!@pythonInterpreter@ | ||||||||||||||||
| # slightly modefied version from the script created by @sersorrel | ||||||||||||||||
| # https://github.com/sersorrel/sys/blob/main/hm/discord/krisp-patcher.py | ||||||||||||||||
| """ | ||||||||||||||||
| This fixes the krisp module not loading. | ||||||||||||||||
| """ | ||||||||||||||||
|
|
||||||||||||||||
|
|
||||||||||||||||
| import subprocess | ||||||||||||||||
| import re | ||||||||||||||||
| import signal | ||||||||||||||||
| import os | ||||||||||||||||
| import shutil | ||||||||||||||||
| import sys | ||||||||||||||||
|
|
||||||||||||||||
| from pathlib import Path | ||||||||||||||||
| from elftools.elf.elffile import ELFFile | ||||||||||||||||
| from capstone import * | ||||||||||||||||
| from capstone.x86 import * | ||||||||||||||||
|
|
||||||||||||||||
| def getKrisp(): | ||||||||||||||||
| process = subprocess.Popen(sys.argv[1], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=False, universal_newlines=True, preexec_fn=os.setsid) | ||||||||||||||||
| print("[Nix] Leting Discord download Krisp") | ||||||||||||||||
| try: | ||||||||||||||||
| for line in iter(process.stdout.readline, ''): | ||||||||||||||||
| print(line, end='') | ||||||||||||||||
| if re.search("installed-module discord_krisp", line): | ||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||||||||
| os.killpg(os.getpgid(process.pid), signal.SIGTERM) | ||||||||||||||||
| print("[Nix] Finished downloading Krisp") | ||||||||||||||||
| break | ||||||||||||||||
| finally: | ||||||||||||||||
| process.wait() | ||||||||||||||||
| process.stdout.close() | ||||||||||||||||
|
|
||||||||||||||||
|
|
||||||||||||||||
| XDG_CONFIG_HOME = os.environ.get("XDG_CONFIG_HOME") or os.path.join( | ||||||||||||||||
| os.path.expanduser("~"), ".config" | ||||||||||||||||
| ) | ||||||||||||||||
|
|
||||||||||||||||
| executable = f"{XDG_CONFIG_HOME}/@configDirName@/@version@/modules/discord_krisp/discord_krisp.node" | ||||||||||||||||
|
|
||||||||||||||||
| if (not os.path.exists(Path(executable))): | ||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||
| print("[Nix] Krisp not found") | ||||||||||||||||
| getKrisp() | ||||||||||||||||
|
|
||||||||||||||||
| elf = ELFFile(open(executable, "rb")) | ||||||||||||||||
| symtab = elf.get_section_by_name('.symtab') | ||||||||||||||||
|
|
||||||||||||||||
| krisp_initialize_address = symtab.get_symbol_by_name("_ZN7discord15KrispInitializeEv")[0].entry.st_value | ||||||||||||||||
| isSignedByDiscord_address = symtab.get_symbol_by_name("_ZN7discord4util17IsSignedByDiscordERKNSt2Cr12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE")[0].entry.st_value | ||||||||||||||||
|
Comment on lines
+48
to
+50
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. a note about how these were derived could be useful in the future:
Suggested change
|
||||||||||||||||
|
|
||||||||||||||||
| text = elf.get_section_by_name('.text') | ||||||||||||||||
| text_start = text['sh_addr'] | ||||||||||||||||
| text_start_file = text['sh_offset'] | ||||||||||||||||
| # This seems to always be zero (.text starts at the right offset in the file). Do it just in case? | ||||||||||||||||
| address_to_file = text_start_file - text_start | ||||||||||||||||
|
|
||||||||||||||||
| # Done with the ELF now. | ||||||||||||||||
| # elf.close() | ||||||||||||||||
|
|
||||||||||||||||
| krisp_initialize_offset = krisp_initialize_address - address_to_file | ||||||||||||||||
| isSignedByDiscord_offset = krisp_initialize_address - address_to_file | ||||||||||||||||
|
|
||||||||||||||||
| f = open(executable, "rb") | ||||||||||||||||
| f.seek(krisp_initialize_offset) | ||||||||||||||||
| krisp_initialize = f.read(64) | ||||||||||||||||
| f.close() | ||||||||||||||||
|
|
||||||||||||||||
| # States | ||||||||||||||||
| found_issigned_by_discord_call = False | ||||||||||||||||
| found_issigned_by_discord_test = False | ||||||||||||||||
| found_issigned_by_discord_je = False | ||||||||||||||||
| found_already_patched = False | ||||||||||||||||
| je_location = None | ||||||||||||||||
|
|
||||||||||||||||
| # We are looking for a call to IsSignedByDiscord, followed by a test, followed by a je. | ||||||||||||||||
| # Then we patch the je into a two byte nop. | ||||||||||||||||
|
|
||||||||||||||||
| md = Cs(CS_ARCH_X86, CS_MODE_64) | ||||||||||||||||
| md.detail = True | ||||||||||||||||
| for i in md.disasm(krisp_initialize, krisp_initialize_address): | ||||||||||||||||
| if i.id == X86_INS_CALL: | ||||||||||||||||
| if i.operands[0].type == X86_OP_IMM: | ||||||||||||||||
| if i.operands[0].imm == isSignedByDiscord_address: | ||||||||||||||||
| found_issigned_by_discord_call = True | ||||||||||||||||
|
|
||||||||||||||||
| if i.id == X86_INS_TEST: | ||||||||||||||||
| if found_issigned_by_discord_call: | ||||||||||||||||
| found_issigned_by_discord_test = True | ||||||||||||||||
|
|
||||||||||||||||
| if i.id == X86_INS_JE: | ||||||||||||||||
| if found_issigned_by_discord_test: | ||||||||||||||||
| found_issigned_by_discord_je = True | ||||||||||||||||
| je_location = i.address | ||||||||||||||||
| break | ||||||||||||||||
|
|
||||||||||||||||
| if i.id == X86_INS_NOP: | ||||||||||||||||
| if found_issigned_by_discord_test: | ||||||||||||||||
| found_already_patched = True | ||||||||||||||||
| break | ||||||||||||||||
|
|
||||||||||||||||
| if je_location: | ||||||||||||||||
| print(f"[Nix] Found patch location: 0x{je_location:x}") | ||||||||||||||||
|
|
||||||||||||||||
| shutil.copyfile(executable, executable + ".orig") | ||||||||||||||||
| f = open(executable, 'rb+') | ||||||||||||||||
| f.seek(je_location - address_to_file) | ||||||||||||||||
| f.write(b'\x66\x90') # Two byte NOP | ||||||||||||||||
| f.close() | ||||||||||||||||
| else: | ||||||||||||||||
| if found_already_patched: | ||||||||||||||||
| print("[Nix] Couldn't find patch location - already patched.") | ||||||||||||||||
| else: | ||||||||||||||||
| print("[Nix] Couldn't find patch location - review manually. Sorry.") | ||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,6 +25,18 @@ let | |
| substituteAllInPlace $out/bin/disable-breaking-updates.py | ||
| chmod +x $out/bin/disable-breaking-updates.py | ||
| ''; | ||
| fixKrisp = runCommand "fix-krisp.py" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add to |
||
| { | ||
| pythonInterpreter = lib.getExe (python3.withPackages(ps: with ps; [ pyelftools capstone ])); | ||
| configDirName = lib.toLower binaryName; | ||
| version = version; | ||
| meta.mainProgram = "fix-krisp.py"; | ||
| } '' | ||
| mkdir -p $out/bin | ||
| cp ${./fix-krisp.py} $out/bin/fix-krisp.py | ||
| substituteAllInPlace $out/bin/fix-krisp.py | ||
| chmod +x $out/bin/fix-krisp.py | ||
| ''; | ||
| in | ||
|
|
||
| stdenv.mkDerivation rec { | ||
|
|
@@ -109,7 +121,8 @@ stdenv.mkDerivation rec { | |
| ${lib.strings.optionalString withTTS "--add-flags \"--enable-speech-dispatcher\""} \ | ||
| --prefix XDG_DATA_DIRS : "${gtk3}/share/gsettings-schemas/${gtk3.name}/" \ | ||
| --prefix LD_LIBRARY_PATH : ${libPath}:$out/opt/${binaryName} \ | ||
| --run "${lib.getExe disableBreakingUpdates}" | ||
| --run "${lib.getExe disableBreakingUpdates}" \ | ||
| --run "${lib.getExe fixKrisp} $out/opt/${binaryName}/.${binaryName}-wrapped" | ||
|
|
||
| ln -s $out/opt/${binaryName}/${binaryName} $out/bin/ | ||
| # Without || true the install would fail on case-insensitive filesystems | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stderr=subprocess.STDOUTseems dubious – presumably this should search either stdout or stderr, whichever this log goes to, and pass the other one through?shell=Falseis the defaultuniversal_newlines=Trueand search for bytes in the output instead (b"installed-module ..."), but shrugstart_new_session=Truerather than usingpreexec_fn=os.setsid