-
Notifications
You must be signed in to change notification settings - Fork 0
/
protector.py
323 lines (258 loc) · 13.8 KB
/
protector.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# coding: utf-8
from os import system
from os.path import exists
#from colorama import Fore
#import fade, psutil
import ctypes, random, string, subprocess, time, errno, os, stat, shutil, sys
#IF YOU WANT TO COMPILE ME REMOVE THE CODE FROM 14 TO 27 AND UNCOMMENT THE IMPORTS ABOVE
try:
from colorama import Fore
import psutil
import fade
except ModuleNotFoundError:
scriptPath = os.getcwd() + "\\" + os.path.basename(__file__)
print("Please Wait. Installing dependencies")
subprocess.call(f'pip install colorama==0.4.5', shell=True, creationflags=0x08000000) ## Install requirements
subprocess.call(f'pip install fade==0.0.9', shell=True, creationflags=0x08000000) ## Install requirements
subprocess.call(f'pip install psutil==5.9.1', shell=True, creationflags=0x08000000) ## Install requirements
print("Please run the script again!")
exit(0)
__author__ = 'Levi2288'
__version__ = 1.0
__status__ = 'Beta'
_AppName_ = 'Discord Token Protector'
##VARS
APP_List = ["Discord.exe", "DiscordPTB.exe", "DiscordCanary.exe"]
MODULE_List = ["colorama", "psutil", "fade"]
LOCAL = os.getenv("LOCALAPPDATA")
APPDATA = os.getenv("APPDATA").replace("\\Roaming", "")
ASCII = """\n\n ██████╗ ██╗███████╗ ██████╗ ██████╗ ██████╗ ██████╗ ██████╗ ██████╗ ██████╗ ████████╗███████╗ ██████╗████████╗ ██████╗ ██████╗
██╔══██╗██║██╔════╝██╔════╝██╔═══██╗██╔══██╗██╔══██╗ ██╔══██╗██╔══██╗██╔═══██╗╚══██╔══╝██╔════╝██╔════╝╚══██╔══╝██╔═══██╗██╔══██╗
██║ ██║██║███████╗██║ ██║ ██║██████╔╝██║ ██║ ██████╔╝██████╔╝██║ ██║ ██║ █████╗ ██║ ██║ ██║ ██║██████╔╝
██║ ██║██║╚════██║██║ ██║ ██║██╔══██╗██║ ██║ ██╔═══╝ ██╔══██╗██║ ██║ ██║ ██╔══╝ ██║ ██║ ██║ ██║██╔══██╗
██████╔╝██║███████║╚██████╗╚██████╔╝██║ ██║██████╔╝ ██║ ██║ ██║╚██████╔╝ ██║ ███████╗╚██████╗ ██║ ╚██████╔╝██║ ██║
╚═════╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝"""
DC_LOCAL_PATH = "\\Local\\Discord"
PTB_LOCAL_PATH = "\\Local\\DiscordPTB"
CANARY_LOCAL_PATH = "\\Local\\DiscordCanary"
DC_ROAMING_PATH = "\\Roaming\\discord"
PTB_ROAMING_PATH = "\\Roaming\\discordptb"
CANARY_ROMING_PATH = "\\Roaming\\discordcanary"
DC_INSTALLED = False
PTB_INSTALLED = False
CANARY_INSTALLED = False
##MISC
##############
####UTILS#####
##############
def get_folder(path, name):
return [f for f in os.listdir(path) if os.path.isdir(path + "\\" + f) and f.find(name) != -1]
def get_discord_version(path, NAME):
folder = get_folder(APPDATA + path, "app-")[0].split("-")[1]
fullpath = APPDATA + path + "\\" + "app-" + folder
## Lets Make sure we only have 1 Discord version installed
while exists(fullpath + "\\resources".strip()) == False:
if (isProcessAlive(NAME)):
subprocess.call(f"TASKKILL /F /IM {NAME}", shell=True, creationflags=0x08000000) # Taskill the specific app
#print(f"We found some problems. Just lay back while we try to solve it.")
time.sleep(3) # Wait for all processes to stop and let us use remove the stuff
shutil.rmtree(fullpath, ignore_errors=False, onerror=handleRemoveReadonly)
time.sleep(1) # wait for it to get removed
folder = get_folder(APPDATA + path, "app-")[0].split("-")[1]
fullpath = APPDATA + path + "\\" + "app-" + folder
else:
return folder
def id_generator(size=8, chars=string.ascii_letters + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
def syscheck():
if os.name != 'nt':
print(f"[{Fore.RED}-{Fore.RESET}] {Fore.RED}This protector is not made for this operating system.")
system("pause")
exit(0)
def handleRemoveReadonly(func, path, exc):
excvalue = exc[1]
if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
os.chmod(path, stat.S_IRWXU| stat.S_IRWXG| stat.S_IRWXO) # 0777
func(path)
else:
raise
def isProcessAlive(proc):
for process in psutil.process_iter():
if process.name() == proc:
return True
return False
def cmdOutput(cmd):
result = subprocess.getoutput(cmd)
return result
def uninstallNode():
if ("not recognized") in cmdOutput("node -v"):
print(f"[{Fore.GREEN}+{Fore.RESET}] {Fore.GREEN}Node.js is not installed. Uninstaller marked as completed{Fore.RESET}")
else:
scriptPath = os.getcwd()
installerPath = scriptPath + "\\setup\\node-v16.17.0-x64.msi"
print(installerPath)
if (exists(installerPath)): # Check Path
print(f"[{Fore.CYAN}i{Fore.RESET}] {Fore.CYAN}Installer found starting uninstalling...{Fore.RESET}")
subprocess.call(f'MsiExec.exe /x \"{installerPath}\" /qn') ## Install Node.js
time.sleep(3)
if ("not recognized") in cmdOutput("node -v"):
print(f"{Fore.GREEN}+{Fore.RESET}] {Fore.GREEN}Uninstalling was successful. No more Node.js{Fore.RESET}")
else:
print(f"[{Fore.RED}-{Fore.RESET}] {Fore.RED}Uninstalling failed.{Fore.RESET}")
def checkifNodeInstalled():
if ("not recognized") in cmdOutput("node -v"):
print(f"[{Fore.RED}-{Fore.RESET}] {Fore.RED}Node.js is missing!{Fore.RESET}")
time.sleep(1)
print(f"[{Fore.CYAN}i{Fore.RESET}] {Fore.CYAN}Installing Node.js...{Fore.RESET}")
scriptPath = os.getcwd()
installerPath = scriptPath + "\\setup\\node-v16.17.0-x64.msi"
print(installerPath)
if(exists(installerPath)): # Check Path
print(f"{Fore.CYAN}i{Fore.RESET}] {Fore.CYAN}Installer found starting installing...{Fore.RESET}")
subprocess.call(f'MsiExec.exe /i \"{installerPath}\" /qn') ## Install Node.js
time.sleep(3)
if ("not recognized") in cmdOutput("node -v"):
print(f"{Fore.RED}CRITICAL{Fore.RESET}] {Fore.RED}Installation failed!{Fore.RESET}\nPlease Install Node.js manually.\nInstaller Location: {installerPath}")
else:
print(f"[{Fore.GREEN}+{Fore.RESET}] {Fore.GREEN}Installation has been successful.{Fore.RESET}")
else:
print(f"[{Fore.GREEN}+{Fore.RESET}] {Fore.GREEN}Node.js Found! We are good to go!{Fore.RESET}")
##############
##############
##############
def extract_files(resource):
print(f"[{Fore.CYAN}i{Fore.RESET}] {Fore.CYAN}Extracting app.asar...{Fore.RESET}")
try:
subprocess.call("npm i -g asar", shell=True, creationflags=0x08000000)
subprocess.call("asar extract " + resource + "\\app.asar" + " " + resource + "\\tmp", shell=True, creationflags=0x08000000)
time.sleep(1)
patch_dc(resource)
except Exception as e:
print(f"[{Fore.RED}CRITICAL{Fore.RESET}] {Fore.RED}Extract error!{Fore.RESET}")
print("\n\n1 | Return To Main Menu")
print("2 | Uninstall Node & Quit")
print("3 | Quit")
choice = int(input("\n\nChoice > "))
while choice == None:
choice = int(input("Choice > "))
else:
if int(choice) == 1:
main()
elif int(choice) == 2:
uninstallNode()
time.sleep(3)
exit(0)
elif int(choice) == 3:
exit(0)
def patch_dc(RESOURCES_PATH):
patch = ""
PATH_HASH = id_generator(random.randint(6,24))
with open(RESOURCES_PATH+"\\tmp\\common\\paths.js", "r") as f:
content = f.read()
old_content = "return _path.default.join(userDataRoot, 'discord' + (buildInfo.releaseChannel == 'stable' ? '' : buildInfo.releaseChannel));"
if (content.find(old_content) == -1):
print(f"{Fore.RED}-{Fore.RESET}] {Fore.RED}This file is not original skipping...{Fore.RESET}")
return None
patch = content.replace(old_content, old_content.replace("'discord'", "'"+PATH_HASH+"'"))
with open(RESOURCES_PATH+"\\tmp\\common\\paths.js", "w") as f:
if f.write(patch):
os.mkdir(APPDATA + "\\Roaming\\" +PATH_HASH)
print(f"[{Fore.GREEN}+{Fore.RESET}] {Fore.GREEN}Patch applied!{Fore.RESET}")
system("asar pack " + RESOURCES_PATH+"\\tmp" + " " + RESOURCES_PATH+"\\app.asar")
def protect_DC(LOCAL_PATH, ROAMING_PATH, VER, NAME, panel):
NAME = NAME.replace(".exe", "")
if not VER:
print(f"[{Fore.RED}CRITICAL{Fore.RESET}] {Fore.RED}Invalid {NAME} version!{Fore.RESET}")
else:
resource_path = ""
resource_path = APPDATA + LOCAL_PATH + "\\app-" + VER + "\\resources"
if os.path.exists(resource_path) == False:
print(f"[{Fore.RED}CRITICAL{Fore.RESET}] {Fore.RED}Something went wrong failed protecting {NAME}{Fore.RESET}")
else:
print(f"\n\n[{Fore.CYAN}i{Fore.RESET}] {Fore.CYAN}{NAME} Version: {VER}{Fore.RESET}")
print(f"[{Fore.CYAN}i{Fore.RESET}] {Fore.CYAN}Protecting {NAME}...{Fore.RESET}")
extract_files(resource_path)
subprocess.call(f"TASKKILL /F /IM {NAME}.exe", shell=True, creationflags=0x08000000)
if(os.path.exists(APPDATA + ROAMING_PATH)):
try:
shutil.rmtree(APPDATA + ROAMING_PATH, ignore_errors=False, onerror=handleRemoveReadonly)
print(f"[{Fore.CYAN}i{Fore.RESET}] {Fore.CYAN}{NAME} removed successfully!\n{Fore.RESET}")
print(f"[{Fore.CYAN}i{Fore.RESET}] {Fore.CYAN}DO NOT FORGET TO LOG OUT FROM YOUR BROWSER! OR THIS PROTECTION WILL DO NOTHING.\nFr do not log into discord in your browser!{Fore.RESET}")
except OSError as error:
print(error)
print(f"[{Fore.RED}-{Fore.RESET}] {Fore.RED}File path can not be removed{Fore.RESET}")
print(f"[{Fore.RED}-{Fore.RESET}] {Fore.RED}Please remove {Fore.YELLOW}{APPDATA + ROAMING_PATH}{Fore.RESET} yourself! ASAP{Fore.RESET}")
if panel:
print("\n\n1 | Return To Main Menu")
print("2 | Uninstall Node & Quit")
print("3 | Quit")
choice = int(input("\n\nChoice > "))
while choice == None:
choice = int(input("Choice > "))
else:
if int(choice) == 1:
main()
elif int(choice) == 2:
uninstallNode()
time.sleep(3)
exit(0)
elif int(choice) == 3:
exit(0)
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
def main():
checkifNodeInstalled()
global PTB_INSTALLED, DC_INSTALLED, CANARY_INSTALLED, APP_List
DC_VER = ""
PTB_VER = ""
CANARY_VER = ""
print(f''' {fade.purpleblue(ASCII)}''')
print(f''' {fade.purpleblue("By:{}".format(__author__).center(110))}''')
print("Wich Discord Do you Wish To Protect?\n")
print("0 | Every Installed Discord")
if (os.path.exists(APPDATA + DC_ROAMING_PATH)):
DC_INSTALLED = True
DC_VER = get_discord_version(DC_LOCAL_PATH, APP_List[0])
print("1 | Discord")
if (os.path.exists(APPDATA + PTB_LOCAL_PATH)):
PTB_INSTALLED = True
PTB_VER = get_discord_version(PTB_LOCAL_PATH, APP_List[1])
print("2 | Discord PTB")
if (os.path.exists(APPDATA + CANARY_LOCAL_PATH)):
CANARY_INSTALLED = True
CANARY_VER = get_discord_version(CANARY_LOCAL_PATH, APP_List[2])
print("3 | Discord Canary")
print("\n\n")
choice = input("Choice > ")
while choice == None:
choice = input("Choice > ")
else:
if int(choice) == 0:
if (DC_INSTALLED):
protect_DC(DC_LOCAL_PATH, DC_ROAMING_PATH, DC_VER, APP_List[0], False)
if (PTB_INSTALLED):
protect_DC(PTB_LOCAL_PATH, PTB_ROAMING_PATH, PTB_VER, APP_List[1], False)
if (CANARY_INSTALLED):
protect_DC(CANARY_LOCAL_PATH, CANARY_VER, APP_List[2], False)
elif int(choice) == 1:
protect_DC(DC_LOCAL_PATH, DC_ROAMING_PATH, DC_VER, APP_List[0], True)
elif int(choice) == 2:
protect_DC(PTB_LOCAL_PATH, PTB_ROAMING_PATH, PTB_VER, APP_List[1], True)
elif int(choice) == 3:
protect_DC(CANARY_LOCAL_PATH, CANARY_ROMING_PATH, CANARY_VER, APP_List[2], True)
if (choice == "quit") or (choice == "exit"):
exit(0)
if __name__ == '__main__':
os.system('cls')
os.system('mode con: cols=150 lines=40')
if is_admin():
main()
else:
# Re-run the program with admin rights
print(f"[{Fore.RED}-{Fore.RESET}] {Fore.RED}This Program requires Admin Rights!{Fore.RESET}")
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
time.sleep(20)
exit(0)